using Google.Apis.Auth.OAuth2;
using Google.Apis.Download;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using PDF_Office.Model.CloudDrive;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PDF_Office.ViewModels.HomePanel.CloudDrive.CloudDriveType
{

    /// <summary>
    /// 单个用户
    /// </summary>
    public class GoogleDriveUserItem: UserBaseItem
    {
       
        public  DriveService Service { get; set; }//Google提供服务
        private List<GoogleDriveFiles> FilesList = new List<GoogleDriveFiles>();//文件

        public UserCredential CurrentCredential { get; set; }//当前用户访问令牌

        public GoogleDriveUserItem()
        {
         //   User = new User();
            
        }
      
        #region   对用户账号处理

        /// <summary>
        /// 移除用户帐号
        /// </summary>
        /// <returns>移除后的状态</returns>
        public async Task<bool> RemoveUser()
        {
            bool result = false;
            if (CurrentCredential != null)
            {
                result = await CurrentCredential.RevokeTokenAsync(CancellationToken.None);
            }
            if (result == true)
            {
                CurrentCredential = null;
                FilesList.Clear();
            }
               

            return result;
        }

        /// <summary>
        /// 获取帐号
        /// </summary>
        /// <returns>返回用户帐号地址</returns>
        private async Task<UserInfo> GetUserAcount()
        {
            UserInfo userInfo = null;
            if (Service != null)
            {
                userInfo = new UserInfo();
                var about = Service.About.Get();
                about.Fields = "user";
                var uss = await about.ExecuteAsync();
                User user = uss.User;
                userInfo.UserAccount = user.EmailAddress;
                userInfo.Name = user.DisplayName;
            }

            return userInfo;
        }

        /// <summary>
        /// 获取帐号
        /// </summary>
        /// <returns>返回用户帐号地址</returns>
        public async Task<UserInfo> GetUserAcountAsync()
        {
            return await GetUserAcount();
        }


        #endregion


        #region   文件夹



        #endregion

        #region  文件

        /// <summary>
        /// 对单个用户，获取文件列表
        /// </summary>
        public async Task<List<GoogleDriveFiles>> GetDriveFiles(DriveService service = null)
        {
            if (service == null)
                return null;

            // define parameters of request.
            FilesResource.ListRequest FileListRequest = service.Files.List(); 

            //listRequest.PageSize = 10;
            //listRequest.PageToken = 10;
            FileListRequest.Fields = "nextPageToken, files(id, name, size, version, createdTime)";

            //get file list.
            IList<Google.Apis.Drive.v3.Data.File> files = FileListRequest.Execute().Files;
            List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();

            if (files != null && files.Count > 0)
            {
                foreach (var file in files)
                {
                       GoogleDriveFiles File = new GoogleDriveFiles
                    {
                        Id = file.Id,
                        Name = file.Name,
                        Size = file.Size,
                        Version = file.Version,
                        CreatedTime = file.CreatedTime
                    };
                    FileList.Add(File);
                }
                this.FilesList = FileList;
            }
            return FileList;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="filepath">本地文件路径</param>
        public  async Task<bool> FileUpload(string filepath)
        {
            if (Service == null)
                return false;

            var FileMetaData = new Google.Apis.Drive.v3.Data.File();
            var str = filepath.LastIndexOf("\\");
            var str2 = filepath.Substring(str + 1, filepath.Length - str - 1);

            FileMetaData.Name = str2;
            FileMetaData.MimeType = "";

            FilesResource.CreateMediaUpload request;
            try
            {
                using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Open))
                {
                    request = Service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
                    request.Fields = "id";
                    request.Upload();
                }

                return true;
            }
            catch
            {
               return false;
            }

        }


        /// <summary>
        /// Download file from Google Drive by fileId.
        /// </summary>
        /// <param name="googleDriveFiles"></param>
        /// <param name="savePath"></param>
        /// <returns></returns>
        //
        public  async Task<string> DownloadGoogleFile(GoogleDriveFiles googleDriveFiles, string savePath)
        {
            if (Service == null)
                return "";

            string fileId = googleDriveFiles.Id;
            if (string.IsNullOrEmpty(fileId))
                return "";

            //fileId = DriveFiles[0].Id;

            FilesResource.GetRequest request = Service.Files.Get(fileId);

            string FileName = request.Execute().Name;
            string FilePath = System.IO.Path.Combine(savePath, FileName);

            MemoryStream stream = new MemoryStream();

            // Add a handler which will be notified on progress changes.
            // It will notify on each chunk download and when the
            // download is completed or failed.
            request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
            {
                switch (progress.Status)
                {
                    case DownloadStatus.Downloading:
                        {
                            Console.WriteLine(progress.BytesDownloaded);
                            break;
                        }
                    case DownloadStatus.Completed:
                        {
                            Console.WriteLine("Download complete.");
                            SaveStream(stream, FilePath);
                            break;
                        }
                    case DownloadStatus.Failed:
                        {
                            Console.WriteLine("Download failed.");
                            break;
                        }
                }
            };
            request.Download(stream);

            if (string.IsNullOrEmpty(savePath) == false)
            {

            }
            return FilePath;
        }

        private static void SaveStream(MemoryStream stream, string FilePath)
        {
            using (System.IO.FileStream file = new FileStream(FilePath, FileMode.Create, FileAccess.ReadWrite))
            {
                stream.WriteTo(file);
            }
        }

        #endregion
    }


    public static class GoogleDriveStatic
    {
        public static string[] Scopes = { DriveService.Scope.Drive };
        //Google Drive应用名称
        private static readonly string GoogleDriveAppName = "PDF Office";
        //请求应用进行身份验证的信息
        public static string CredentialsPath { get; private set; }

        //存放已通过身份验证的用户信息，以便下次不用登录便可使用云文档
        public static string FilesPathTemp { get; private set; }
        /// <summary>
        ///  异步获取Google服务的包信息，避免UI线程卡死
        /// </summary>
        /// <param name="userInfoFile"></param>
        [Obsolete]
        public static async Task<Tuple<DriveService, UserCredential>> GetServiceAsync(string userInfoFile = "")
        {
            Tuple<DriveService, UserCredential> tuple = null;
            await Task.Run(() =>
            {
                tuple = GetService(userInfoFile);
            });
            return tuple;
        }

        /// <summary>
        /// 获取Google服务的包信息（包含访问令牌，App Key密钥等）
        /// </summary>
        /// <param name="FilePath">登录过的用户文件；若为空，则为新用户登录</param>
        /// <returns></returns>
        [Obsolete]
        public static Tuple<DriveService, UserCredential> GetService(string FilePath = "")
        {
            Tuple<DriveService, UserCredential> tuple = null;
            UserCredential credential;

            if (FilePath == "")
            {
                var time = DateTime.Now.ToString("yyyyMMddHHmmss");
                FilePath = System.IO.Path.Combine(FilesPathTemp, time + ".json");
            }

            try
            {
                using (var stream = new FileStream(CredentialsPath, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        Scopes,
                        "user",
                        CancellationToken.None,
                        new FileDataStore(FilePath, true)).Result;
                }

                //create Drive API service.
                DriveService service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = GoogleDriveAppName
                });

                return tuple = new Tuple<DriveService, UserCredential>(service, credential);
            }
            catch (Exception e)
            {
                //网络连接失败的情况
                return null;
            }
            
        }


        /// <summary>
        /// 获取登录过的账号
        /// </summary>
        /// <returns>历史账号</returns>
        public static async Task<List<Tuple<DriveService, UserCredential>>> GetHistoryService()
        {
            DirectoryInfo TheFolder = new DirectoryInfo(FilesPathTemp);
            List<Tuple<DriveService, UserCredential>> DriveServices = new List<Tuple<DriveService, UserCredential>>();

            foreach (var directorieItem in TheFolder.GetDirectories())
            {
                var driveServiceItem = await GetServiceAsync(directorieItem.Name);

                if (driveServiceItem != null)
                {
                    DriveServices.Add(driveServiceItem);
                }
            }
            return DriveServices;
        }



        #region  云文档的用户帐户缓存路径和身份验证文件

        /// <summary>
        /// 获取或创建缓存登录帐户信息
        /// </summary>
        public static string GetFilesPathTemp()
        {
            string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
            String FolderPath = str_1 + "GoogleDriveUsers";

            if (Directory.Exists(FolderPath) == false)
                Directory.CreateDirectory(FolderPath);

            FilesPathTemp = FolderPath;
            return FolderPath;
        }

        public static bool ClearFilesPathTemp()
        {
            bool result = false;
            string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
            String FolderPath = str_1 + "GoogleDriveUsers";

            if (Directory.Exists(FolderPath) == false)
            {
                Directory.Delete(FolderPath);
                result = true;
            }
            return result;
        }


        /// <summary>
        /// 获取本地身份验证文件
        /// </summary>
        public static string GetCredentialsPath()
        {
            string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
            String filePath = str_1 + @"\credentials.json";
            CredentialsPath = filePath;
            return filePath;
        }

        #endregion
    }
}
