using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Google.Apis.Drive.v3.Data;
using System.IO;
using System.Collections.Generic;
using System.Linq;

// usage example at the very bottom
namespace ConsoleApp1
{
    public class GoogleDriveService
    {
        private readonly DriveService service;
        
        public GoogleDriveService()
        {   // ключи для почты asbautodrilling@gmail.com.
            var tokenResponse = new TokenResponse
            {
                AccessToken = "ya29.a0ARrdaM-lM7q0TIC_DXixR4oW63QUftjSPHl-8nIdvZwtqA8Z1bXtlYpDrQXj9UFTjW8FW8uqPMrdamUSp4kO4a9JX7FddkBWxaJ_omSJpqzDfnHTHA_7-zGMUohaAsmPLsQtFz_GUmB5ZoVLmA8xWdbJxVxU",
                RefreshToken = "1//04FeDguc19IfgCgYIARAAGAQSNwF-L9Ir8U7wX2seanUzsxXXGgFzOYQqjbtN9O27ZZybbOobZjVAo_4_eFNLMX1ElPKOFVWsrJQ"
            };

            var applicationName = "Files"; // Use the name of the project in Google Cloud
            var username = "asbautodrilling@gmail.com"; // Use your email

            var apiCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets
                {
                    ClientId = "1020584579240-f7amqg35qg7j94ta1ntgitajq27cgh49.apps.googleusercontent.com",
                    ClientSecret = "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"
                },
                Scopes = new[] {DriveService.Scope.Drive},
                DataStore = new FileDataStore(applicationName)
            });

            var credential = new UserCredential(apiCodeFlow, username, tokenResponse);

            var newService = new DriveService(new BaseClientService.Initializer
            {
                HttpClientInitializer = credential,
                ApplicationName = applicationName
            });
            this.service = newService;
        }
        
        // public IEnumerable<Google.Apis.Drive.v3.Data.File> GetAllFiles() // get file names
        // {
        //     var fileList = service.Files.List();
        //     fileList.Fields = "files(id, webViewLink, size)";
        //     //fileList.Q =$"mimeType!='application/vnd.google-apps.folder' and '{folder}' in parents";
        //     //fileList.Fields = "nextPageToken, files(id, name, size, mimeType)";
        //
        //     var result = new List<Google.Apis.Drive.v3.Data.File>();
        //     string pageToken = null;
        //     do
        //     {
        //         fileList.PageToken = pageToken;
        //         var filesResult = fileList.Execute();
        //         var files = filesResult.Files;
        //         pageToken = filesResult.NextPageToken;
        //         result.AddRange(files);
        //     } while (pageToken != null);
        //
        //     return result;
        // }

        public string GetFileWebLink(string idFile)
        {
            var fileList = service.Files.List();
            fileList.Fields = "files(id, webViewLink, size)";
            var filesResult = fileList.Execute();
            var file = filesResult.Files.FirstOrDefault(f => f.Id == idFile);
            return file?.WebViewLink ?? string.Empty;
        }
        
        // У Гугла почему-то folder это и папка, и файл.
        public string CreateFolder(string folderName) 
        {                                       
            var driveFolder = new Google.Apis.Drive.v3.Data.File();
            driveFolder.Name = folderName;
            driveFolder.MimeType = "application/vnd.google-apps.folder";
            //driveFolder.Parents = new string[] { parent };
            var command = service.Files.Create(driveFolder);
            var file = command.Execute();
            return file.Id;
        }

        public void CreatePublicPermissionForFile(string idFile)
        {
            var permission = new Permission() { Type = "anyone", Role = "reader"};
            var addPermissionRequest = service.Permissions.Create(permission, idFile);
            addPermissionRequest.Execute();
        }
        
        public string UploadFile(Stream file, string fileName, string fileMime, string fileDescription)
        {
            var driveFile = new Google.Apis.Drive.v3.Data.File();
            driveFile.Name = fileName;
            driveFile.Description = fileDescription;
            driveFile.MimeType = fileMime;
            //driveFile.Parents = new [] {folder};
    
            var request = service.Files.Create(driveFile, file, fileMime);
            request.Fields = "id";
    
            var response = request.Upload();
            if (response.Status != Google.Apis.Upload.UploadStatus.Completed)
                throw response.Exception;
    
            return request.ResponseBody.Id;
        }

        public void DeleteFile(string fileId)
        {
            var command = service.Files.Delete(fileId);
            var result = command.Execute();
        }
    }
}

// usage example:

// var service = new GoogleDriveService();
//
// //var files = serviceWrapper.GetAllFiles();
//
// // foreach (var file in files)
// // {
// //     var permission = new Permission() { Type = "anyone", Role = "reader"};
// //     var createRequest = service.Permissions.Create(permission, file.Id);
// //     createRequest.Execute();
// //     Console.WriteLine(file.WebViewLink);   
// // }
//
// var path = "/home/cult/First.xlsx";
// var fileInfo = new FileInfo(path);
// var fileStream = System.IO.File.Open(path, FileMode.Open);
// var uploadedFileId = service.UploadFileAsync(fileStream, fileInfo.Name, "", "uploaded");
// service.CreatePublicPermissionForFileAsync(uploadedFileId);
// var webLink = service.GetFileWebLinkAsync(uploadedFileId);
// Console.WriteLine(webLink);