using Avalonia.Threading;
using MES.Utility.Core;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Ursa.Controls;
using 常用工具集.Base;
using 常用工具集.Utility.Network;

namespace 常用工具集.ViewModel._02网络相关
{
    public class FTP客户端ViewModel : ViewModelBase
    {
        public List<Encoding> EncodingList { get; set; } = new List<Encoding>() { Encoding.UTF8 };

        public List<string> StrEncodingList { get; set; } = new List<string>() { "UTF-8" };

        public int EncodingIndex { get; set; } = 0;

        private object _lock = new object();
        private List<string> msgList = new List<string>();
        public string Message
        {
            get
            {
                lock (_lock)
                {
                    return msgList.GetStrArray("\r\n");
                }
            }
            set
            {
                lock (_lock)
                {
                    msgList.Add(value);
                }
                NotifyPropertyChanged();
            }
        }
        public string IpAddress { get; set; } = "127.0.0.1";
        public string UserName { get; set; } = "admin";
        public string Password { get; set; } = "123456";
        public int Port { get; set; } = 21;
        public bool IsAnonymous { get; set; } = false;
        public bool EnableFlag1 { get; set; } = true;
        public bool EnableFlag2 { get; set; } = false;
        private FtpHelper ftp;
        public DelegateCommand ConnectCmd { get; set; }
        public DelegateCommand DisconnectCmd { get; set; }
        public DelegateCommand LocalDoubleClickCommand { get; set; }
        public DelegateCommand LocalHomeClickCommand { get; set; }

        public DelegateCommand RemoteHomeClickCommand { get; set; }
        public DelegateCommand RemoteDoubleClickCommand { get; set; }

        public DelegateCommand DownloadClickCommand { get; set; }
        public DelegateCommand UploadClickCommand { get; set; }
        public DelegateCommand RemoteRenameClickCommand { get; set; }

        public DelegateCommand RemoteDeleteClickCommand { get; set; }
        public string LocalPath1 { get; set; } = "本地";
        public string CurrentLocalPath { get; set; } = "";

        public ObservableCollection<MyDir> LocalTree { get; set; }
        public MyDir LocalTreeSelectedItem { get; set; } = null;



        public string RemotePath1 { get; set; } = "远程";
        public string CurrentRemotePath { get; set; } = "";
        public ObservableCollection<MyDir> RemoteTree { get; set; }
        public MyDir RemoteTreeSelectedItem { get; set; } = null;


        public FTP客户端ViewModel()
        {
            LocalTree = GetFoldersAndFiles();
            ConnectCmd = new DelegateCommand(ConnectCmdFunc);
            DisconnectCmd = new DelegateCommand(DisconnectCmdFunc);
            RemoteHomeClickCommand = new DelegateCommand(RemoteHomeClickCommandFunc);
            LocalHomeClickCommand = new DelegateCommand(LocalHomeClickCommandFunc);
            LocalDoubleClickCommand = new DelegateCommand(LocalDoubleClickCommandFunc);
            RemoteDoubleClickCommand = new DelegateCommand(RemoteDoubleClickCommandFunc);
            DownloadClickCommand = new DelegateCommand(DownloadClickCommandFunc);
            UploadClickCommand = new DelegateCommand(UploadClickCommandFunc);
            RemoteDeleteClickCommand = new DelegateCommand(RemoteDeleteClickCommandFunc);
            RemoteRenameClickCommand = new DelegateCommand(RemoteRenameClickCommandFunc);
        }



        private void ConnectCmdFunc(object obj)
        {
            if (IsAnonymous)
            {
                try
                {
                    ftp = new FtpHelper(IpAddress, Port, EncodingList[EncodingIndex]);
                    RemoteTree = GetRemoteFoldersAndFiles();
                }
                catch
                {
                    GlobalValues.Error("FTP连接失败");
                    return;
                }
            }
            else
            {
                try
                {
                    ftp = new FtpHelper(IpAddress, Port, UserName, Password, EncodingList[EncodingIndex]);
                    RemoteTree = GetRemoteFoldersAndFiles();

                }
                catch
                {
                    GlobalValues.Error("FTP连接失败");
                    return;
                }
            }
            EnableFlag1 = false;
            EnableFlag2 = true;
        }

        private void DisconnectCmdFunc(object obj)
        {
            ftp = null;
            RemoteTree = new ObservableCollection<MyDir>();
            RemotePath1 = "远程";
            CurrentRemotePath = "";

            EnableFlag1 = true;
            EnableFlag2 = false;
        }



        private void RemoteDoubleClickCommandFunc(object obj)
        {
            try
            {
                MyDir current = (MyDir)obj;
                if (current == null)
                    return;
                if (current.IsBack)
                {
                    string path = CurrentRemotePath;
                    if (path.EndsWith("/"))
                        path = path.Substring(0, path.Length - 1);
                    int index = path.LastIndexOf("/");
                    if (index == -1)
                    {
                        path = "";
                    }
                    else
                    {
                        path = path.Substring(0, index + 1);
                    }
                    if (path == "")
                    {
                        CurrentRemotePath = "";
                        RemotePath1 = "远程";
                    }
                    else
                    {
                        CurrentRemotePath = path;
                        RemotePath1 = "远程:" + CurrentRemotePath;
                    }
                    RemoteTree = GetRemoteFoldersAndFiles();
                    return;
                }
                //文件不能双击
                if (!current.IsDirectory)
                {
                    return;
                }
                CurrentRemotePath = current.Path;
                RemotePath1 = "远程:" + CurrentRemotePath;
                RemoteTree = GetRemoteFoldersAndFiles();
            }
            catch (Exception ex)
            {
                GlobalValues.Error("FTP连接失败");
                DisconnectCmdFunc(null);
            }
        }


        private void LocalDoubleClickCommandFunc(object obj)
        {
            MyDir current = (MyDir)obj;
            if (current == null)
                return;
            if (current.IsBack)
            {

                string path = CurrentLocalPath;
                if (path.EndsWith("/"))
                    path = path.Substring(0, path.Length - 1);
                int index = path.LastIndexOf("/");
                if (index == -1)
                {
                    path = "";
                }
                else
                {
                    path = path.Substring(0, index + 1);
                }
                if (path == "")
                {
                    CurrentLocalPath = "";
                    LocalPath1 = "本地";
                }
                else
                {
                    CurrentLocalPath = path.Replace("\\", "/");
                    LocalPath1 = "本地:" + CurrentLocalPath;
                }
                LocalTree = GetFoldersAndFiles();
                return;
            }

            //文件不能双击
            if (!current.IsDirectory)
            {
                return;
            }
            CurrentLocalPath = current.Path;
            LocalPath1 = "本地:" + CurrentLocalPath;
            LocalTree = GetFoldersAndFiles();
        }


        private ObservableCollection<MyDir> GetRemoteFoldersAndFiles()
        {
            ObservableCollection<MyDir> list = new ObservableCollection<MyDir>();
            List<FtpFileInfo> list2 = ftp.GetList(CurrentRemotePath).OrderByDescending(it => it.IsDirectory).ToList();

            if (CurrentRemotePath != "")
            {
                list.Add(new MyDir
                {
                    Name = $"...",
                    Path = $"",
                    IsDirectory = true,
                    IsBack = true,
                });
            }
            foreach (var ftpFileInfo in list2)
            {
                if (ftpFileInfo.IsDirectory)
                {
                    list.Add(new MyDir
                    {
                        Name = $"{ftpFileInfo.Name}",
                        Path = $"{CurrentRemotePath}{ftpFileInfo.Name}/",
                        IsDirectory = true
                    });
                }
                else
                {
                    list.Add(new MyDir
                    {
                        Name = $"{ftpFileInfo.Name}",
                        Path = $"{CurrentRemotePath}{ftpFileInfo.Name}",
                        IsDirectory = false
                    });
                }
            }
            return list;
        }

        private ObservableCollection<MyDir> GetFoldersAndFiles()
        {
            ObservableCollection<MyDir> list = new ObservableCollection<MyDir>();
            if (CurrentLocalPath == "")
            {
                list.Add(new MyDir
                {
                    Name = "桌面",
                    Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory).Replace("\\", "/"),
                    IsDirectory = true
                });
                // 获取所有盘符
                DriveInfo[] allDrives = DriveInfo.GetDrives();
                // 过滤出固态硬盘（SSD）和机械硬盘（HDD）
                List<string> systemDrives = allDrives.Where(drive => drive.IsReady) // 确保驱动器已准备好访问
                    .Where(drive => drive.DriveType == DriveType.Fixed) // 仅固定类型的驱动器
                    .Select(drive => drive.Name.Substring(0, 1)) // 获取盘符
                    .ToList();
                // 输出系统盘符
                foreach (var drive in systemDrives)
                {
                    list.Add(new MyDir
                    {
                        Name = $"{drive}",
                        Path = $"{drive}:/",
                        IsDirectory = true
                    });
                }
            }
            else
            {
                list.Add(new MyDir
                {
                    Name = "...",
                    Path = "",
                    IsDirectory = true,
                    IsBack = true,
                });
                List<string> dirList = Directory.GetDirectories(CurrentLocalPath).Select(it => it.Replace("\\", "/")).ToList();
                foreach (string dirPath in dirList)
                {
                    list.Add(new MyDir
                    {
                        Name = System.IO.Path.GetFileName(dirPath),
                        Path = dirPath + "/",
                        IsDirectory = true,
                    });
                }
                List<string> fileList = Directory.GetFiles(CurrentLocalPath).Select(it => it.Replace("\\", "/")).ToList();
                foreach (string filePath in fileList)
                {
                    list.Add(new MyDir
                    {
                        Name = System.IO.Path.GetFileName(filePath),
                        Path = filePath,
                        IsDirectory = false,
                    });
                }
            }
            return list;
        }

        private void LocalHomeClickCommandFunc(object obj)
        {
            CurrentLocalPath = "";
            LocalPath1 = "本地";
            LocalTree = GetFoldersAndFiles();
        }

        private void RemoteHomeClickCommandFunc(object obj)
        {
            try
            {
                CurrentRemotePath = "";
                RemotePath1 = "远程";
                RemoteTree = GetRemoteFoldersAndFiles();
            }
            catch (Exception ex)
            {
                GlobalValues.Error("FTP连接失败");
                DisconnectCmdFunc(null);
            }
        }



        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="obj"></param>
        private async void UploadClickCommandFunc(object obj)
        {
            if (LocalTreeSelectedItem == null)
            {
                await MessageBox.ShowAsync("请选择要上传的文件或文件夹");
                return;
            }
            if (LocalTreeSelectedItem.IsBack)
            {
                return;
            }
            bool cover = false;

            var result = await MessageBox.ShowOverlayAsync("上传过程中可能文件存在，是否覆盖上传", "提示", button: MessageBoxButton.YesNo);
            if (result != MessageBoxResult.Yes)
            {
                cover = false;
            }
            else
            {
                cover = true;
            }
            //上传文件夹
            if (LocalTreeSelectedItem.IsDirectory)
            {
                new Thread(() =>
                {
                    UploadDir(LocalTreeSelectedItem, CurrentRemotePath, cover);
                    Message = $"文件夹上传完成：{LocalTreeSelectedItem.Name}";
                    Dispatcher.UIThread.Invoke(() =>
                    {
                        RemoteTree = GetRemoteFoldersAndFiles();
                    });
                }).Start();
            }
            //上传文件
            else
            {
                new Thread(() =>
                {
                    try
                    {
                        //判断远端是否存在文件，是否覆盖
                        bool isExist = ftp.IsFileExist(CurrentRemotePath, LocalTreeSelectedItem.Name);
                        if (isExist && !cover)
                        {
                            return;
                        }
                        Message = $"准备上传：{LocalTreeSelectedItem.Path}";
                        ftp.UploadFile(LocalTreeSelectedItem.Path, CurrentRemotePath + LocalTreeSelectedItem.Name);
                        Message = $"上传完成：{LocalTreeSelectedItem.Path}";
                    }
                    catch (Exception ex)
                    {
                        Message = $"上传失败：{LocalTreeSelectedItem.Path}";
                    }
                    Dispatcher.UIThread.Invoke(() =>
                    {
                        RemoteTree = GetRemoteFoldersAndFiles();
                    });
                }).Start();
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="obj"></param>
        private async void DownloadClickCommandFunc(object obj)
        {
            if (RemoteTreeSelectedItem == null)
            {
                await MessageBox.ShowAsync("请选择要下载的文件或文件夹");
                return;
            }
            if (CurrentLocalPath == "")
            {
                await MessageBox.ShowAsync("请选择本地路径");
                return;
            }
            if (RemoteTreeSelectedItem.IsBack)
            {
                return;
            }
            bool cover = false;
            var result = await MessageBox.ShowOverlayAsync("下载过程中可能文件存在，是否覆盖下载", "提示", button: MessageBoxButton.YesNo);
            if (result != MessageBoxResult.Yes)
            {
                cover = false;
            }
            else
            {
                cover = true;
            }
            //下载文件夹
            if (RemoteTreeSelectedItem.IsDirectory)
            {
                new Thread(() =>
                {
                    DownloadDir(RemoteTreeSelectedItem, CurrentLocalPath, cover);
                    Message = $"文件夹下载完成:{RemoteTreeSelectedItem.Name}";
                    Dispatcher.UIThread.Invoke(() =>
                    {
                        LocalTree = GetFoldersAndFiles();
                    });
                }).Start();
            }
            //下载文件
            else
            {
                new Thread(() =>
                {

                    try
                    {
                        if (File.Exists(CurrentLocalPath + "/" + RemoteTreeSelectedItem.Name) && !cover)
                        {
                            return;
                        }
                        Message = $"准备下载:{RemoteTreeSelectedItem.Name}";
                        ftp.DownloadFile(RemoteTreeSelectedItem.Path, CurrentLocalPath + "/" + RemoteTreeSelectedItem.Name);
                        Message = $"下载完成:{RemoteTreeSelectedItem.Name}";
                    }
                    catch (Exception ex)
                    {
                        Message = $"下载失败:{ex.Message}";
                    }
                    Dispatcher.UIThread.Invoke(() =>
                    {
                        LocalTree = GetFoldersAndFiles();
                    });
                }).Start();
            }
        }

        /// <summary>
        /// 删除FTP文件
        /// </summary>
        /// <param name="obj"></param>
        /// <exception cref="NotImplementedException"></exception>
        private async void RemoteDeleteClickCommandFunc(object obj)
        {
            try
            {
                if (RemoteTreeSelectedItem == null)
                {
                    await MessageBox.ShowAsync("请选择要删除的文件或文件夹");
                    return;
                }
                if (RemoteTreeSelectedItem.IsBack)
                {
                    return;
                }
                var result = await MessageBox.ShowOverlayAsync("是否确定删除", "提示", button: MessageBoxButton.YesNo);
                if (result != MessageBoxResult.Yes)
                {
                    return;
                }
                if (RemoteTreeSelectedItem.IsDirectory)
                {
                    new Thread(() =>
                    {
                        try
                        {
                            DeleteDirecory(RemoteTreeSelectedItem.Path);
                            Message = $"删除成功:{RemoteTreeSelectedItem.Path}";
                        }
                        catch (Exception ex)
                        {
                            Message = $"删除失败:{ex.Message}";
                        }
                        Dispatcher.UIThread.Invoke(() =>
                        {
                            RemoteTree = GetRemoteFoldersAndFiles();
                        });
                    }).Start();
                }
                else
                {
                    new Thread(() =>
                    {
                        Message = $"准备删除:{RemoteTreeSelectedItem.Path}";
                        try
                        {
                            ftp.DeleteFile(RemoteTreeSelectedItem.Path);
                            Message = $"删除成功:{RemoteTreeSelectedItem.Path}";
                        }
                        catch (Exception ex)
                        {
                            Message = $"删除失败:{ex.Message}";
                        }
                        Dispatcher.UIThread.Invoke(() =>
                        {
                            RemoteTree = GetRemoteFoldersAndFiles();
                        });
                    }).Start();
                }

            }
            catch (Exception ex)
            {
                await MessageBox.ShowAsync(ex.Message);
            }
        }

        private void DeleteDirecory(string path)
        {
            List<FtpFileInfo> list = ftp.GetList(path);
            foreach (FtpFileInfo info in list)
            {
                if (info.IsDirectory)
                {
                    DeleteDirecory(path + info.Name + "/");
                }
                else
                {
                    Message = $"准备删除:{path + info.Name}";
                    try
                    {
                        ftp.DeleteFile(path + info.Name);
                        Message = $"删除成功:{path + info.Name}";
                    }
                    catch (Exception ex)
                    {
                        Message = $"删除失败:{ex.Message}";
                    }
                }
            }
            ftp.DeleteDirectory(path);
        }


        /// <summary>
        /// 递归调用
        /// </summary>
        /// <param name="remoteTreeSelectedItem"></param>
        /// <param name="currentLocalPath"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void DownloadDir(MyDir remoteTreeSelectedItem, string currentLocalPath, bool cover)
        {
            //文件夹是否存在
            string localPath = currentLocalPath + "/" + remoteTreeSelectedItem.Name;
            if (!Directory.Exists(localPath))
            {
                Directory.CreateDirectory(localPath);
            }
            List<FtpFileInfo> myDirs = ftp.GetList(remoteTreeSelectedItem.Path);
            foreach (FtpFileInfo f in myDirs)
            {
                if (f.IsDirectory)
                {
                    MyDir dir = new MyDir { IsDirectory = true, Name = f.Name, Path = remoteTreeSelectedItem.Path + f.Name + "/" };
                    DownloadDir(dir, localPath, cover);
                }
                else
                {

                    try
                    {
                        if (File.Exists(localPath + "/" + f.Name) && !cover)
                        {
                            return;
                        }
                        Message = $"准备下载:{remoteTreeSelectedItem.Path + f.Name}";
                        ftp.DownloadFile(remoteTreeSelectedItem.Path + f.Name, localPath + "/" + f.Name);
                        Message = $"下载完成:{remoteTreeSelectedItem.Path + f.Name}";
                    }
                    catch (Exception ex)
                    {
                        Message = $"下载失败:{ex.Message}";
                    }
                }
            }
        }


        private void UploadDir(MyDir localTreeSelectedItem, string currentRemotePath, bool cover)
        {
            //文件夹是否存在
            string remotePath = currentRemotePath + localTreeSelectedItem.Name + "/";
            if (!ftp.FolderExists(currentRemotePath, localTreeSelectedItem.Name))
            {
                ftp.CreateFolder(remotePath);
            }
            string[] dirList = Directory.GetDirectories(localTreeSelectedItem.Path).Select(it => it.Replace("\\", "/")).ToArray();
            string[] fileList = Directory.GetFiles(localTreeSelectedItem.Path).Select(it => it.Replace("\\", "/")).ToArray();
            foreach (string f in dirList)
            {
                MyDir dir = new MyDir { IsDirectory = true, Name = System.IO.Path.GetFileName(f), Path = f };
                UploadDir(dir, remotePath, cover);
            }
            foreach (string f in fileList)
            {
                try
                {
                    bool isExist = ftp.IsFileExist(remotePath + "/", System.IO.Path.GetFileName(f));
                    if (isExist)
                    {
                        continue;
                    }
                    Message = $"准备上传:{localTreeSelectedItem.Path + System.IO.Path.GetFileName(f)}";
                    ftp.UploadFile(localTreeSelectedItem.Path + "/" + System.IO.Path.GetFileName(f), remotePath + "/" + System.IO.Path.GetFileName(f));
                    Message = $"上传完成:{localTreeSelectedItem.Path + System.IO.Path.GetFileName(f)}";
                }
                catch (Exception ex)
                {
                    Message = $"上传失败:{ex.Message}";
                }

            }
        }



        private void RemoteRenameClickCommandFunc(object obj)
        {
            if (RemoteTreeSelectedItem == null)
            {
                MessageBox.ShowAsync("请选择要重命名的文件或文件夹");
                return;
            }
            if (RemoteTreeSelectedItem.IsBack)
            {
                return;
            }
            string newName = Interaction.InputBox("请输入新名字", "", "", 200, 100);
            if (newName.IsNullOrEmpty())
            {
                MessageBox.ShowAsync("请输入新文件名");
                return;
            }
            string path = "";
            if (RemoteTreeSelectedItem.IsDirectory)
            {
                path = CurrentRemotePath;
                if (path.EndsWith("/"))
                    path = path.Substring(0, path.Length - 1);
                int index = path.LastIndexOf("/");
                if (index == -1)
                {
                    path = "";
                }
                else
                {
                    path = path.Substring(0, index + 1);
                }
                path += newName + "/";
            }
            else
            {
                path = CurrentRemotePath;
                if (path.EndsWith("/"))
                    path = path.Substring(0, path.Length - 1);
                int index = path.LastIndexOf("/");
                if (index == -1)
                {
                    path = "";
                }
                else
                {
                    path = path.Substring(0, index + 1);
                }
                string ext = System.IO.Path.GetExtension(RemoteTreeSelectedItem.Path);
                if (!newName.ToLower().EndsWith(ext.ToLower()))
                {
                    path = path + newName + ext;
                }
            }

            new Thread(() =>
            {
                try
                {
                    ftp.Rename(RemoteTreeSelectedItem.Path, path);

                    Dispatcher.UIThread.Invoke(() =>
                    {
                        RemoteTree = GetRemoteFoldersAndFiles();
                    });
                }
                catch (Exception ex)
                {
                    Message = $"重命名失败:{ex.Message}";
                }


            }).Start();
        }
    }

    public class MyDir
    {
        public string Path { get; set; }
        public string Name { get; set; }
        public bool IsDirectory { get; set; }

        public bool IsBack { get; set; }
    }
}
