using DevExpress.Mvvm.Xpf;
using log4net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// GH资源面板
    /// </summary>
    public class GHResourcePanelModel : ViewModelBase
    {
        /// <summary>
        /// 日志
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(GHResourcePanelModel));

        public GHResourcePanelModel()
        {
            // 初始化控制器
            this.initController();

            // 初始化命令
            this.initCommand();
        }

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void initCommand()
        {
            this.LoadedCommand = new VCommand(this.Loaded);
            this.FolderExpandCommand = new VCommand<DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs>(this.FolderExpand);
            this.FileRowFilterCommand = new DevExpress.Mvvm.DelegateCommand<RowFilterArgs>(this.FileRowFilter);

            this.RefreshFolderCommand = new VCommand(this.RefreshFolder);
            this.RefreshFileCommand = new VCommand(this.RefreshFile);
            this.FileFilterCommand = new VCommand<ResourceFileType>(this.FileFilter);
            this.FileDoubleClickCommand = new VCommand(this.FileDoubleClick);
        }

        /// <summary>
        /// 初始化控制器
        /// </summary>
        private void initController()
        {
            this.ghResourceFileController = new GHResourceFileController(this);
        }


        // ==================================================================================
        // Event
        // ==================================================================================

        /// <summary>
        /// 选择文件改变时触发
        /// </summary>
        public event EventHandler<GHResourceSelectedFileChangedEventArgs> OnSelectedFileModelChanged;

        /// <summary>
        /// 文件双击时触发
        /// </summary>
        public event EventHandler<GHResourceFileDoubleClickEventArgs> OnFileDoubleClick;

        // ==================================================================================
        // Property
        // ==================================================================================

        #region FolderModels -- 文件夹目录集合

        private ObservableCollection<GHResourceFolderModel> folderModels;
        /// <summary>
        /// 文件夹目录集合
        /// </summary>
        public ObservableCollection<GHResourceFolderModel> FolderModels
        {
            get { return folderModels; }
            set { folderModels = value; this.RaisePropertyChanged(nameof(FolderModels)); }
        }

        #endregion

        #region SelectedFolderModel -- 当前选中的文件夹

        private GHResourceFolderModel selectedFolderModel;
        /// <summary>
        /// 当前选中的文件夹
        /// </summary>
        public GHResourceFolderModel SelectedFolderModel
        {
            get { return selectedFolderModel; }
            set
            {
                selectedFolderModel = value;
                this.RaisePropertyChanged(nameof(SelectedFolderModel));
                // 更新文件模型
                this.ghResourceFileController.UpdateFileModels(value);
            }
        }

        #endregion

        #region FileModels -- 文件集合

        private ObservableCollection<GHResourceFileModel> fileModels;
        /// <summary>
        /// 文件集合
        /// </summary>
        public ObservableCollection<GHResourceFileModel> FileModels
        {
            get { return fileModels; }
            set { fileModels = value; this.RaisePropertyChanged(nameof(FileModels)); }
        }

        #endregion

        #region SelectedFileModel -- 选中的文件模型

        private GHResourceFileModel selectedFileModel;
        /// <summary>
        /// 选中的文件模型
        /// </summary>
        public GHResourceFileModel SelectedFileModel
        {
            get { return selectedFileModel; }
            set
            {
                selectedFileModel = value;
                this.RaisePropertyChanged(nameof(SelectedFileModel));

                this.OnSelectedFileModelChanged?.Invoke(this, new GHResourceSelectedFileChangedEventArgs { File = value });
            }
        }

        #endregion

        #region SelectedFileModels -- 选中的文件模型集合

        private ObservableCollection<GHResourceFileModel> selectedFileModels = new ObservableCollection<GHResourceFileModel>();
        /// <summary>
        /// 选中的文件模型集合
        /// </summary>
        public ObservableCollection<GHResourceFileModel> SelectedFileModels
        {
            get { return selectedFileModels; }
        }

        #endregion

        #region IsFolderLoading -- 是否正在加载文件夹

        private bool isFolderLoading;
        /// <summary>
        /// 是否正在加载文件夹
        /// </summary>
        public bool IsFolderLoading
        {
            get { return isFolderLoading; }
            set { isFolderLoading = value; this.RaisePropertyChanged(nameof(IsFolderLoading)); }
        }

        #endregion

        #region IsFileLoading -- 是否正在加载文件

        private bool isFileLoading;
        /// <summary>
        /// 是否正在加载文件
        /// </summary>
        public bool IsFileLoading
        {
            get { return isFileLoading; }
            set { isFileLoading = value; this.RaisePropertyChanged(nameof(IsFileLoading)); }
        }

        #endregion

        #region FilterResourceFileType -- 资源文件类型

        private ResourceFileType filterResourceFileType;
        /// <summary>
        /// 资源文件类型
        /// </summary>
        public ResourceFileType FilterResourceFileType
        {
            get { return filterResourceFileType; }
            set { filterResourceFileType = value; this.RaisePropertySaveChanged(nameof(FilterResourceFileType)); }
        }

        #endregion

        // ==================================================================================
        // Service & Controller
        // ==================================================================================

        /// <summary>
        /// GH 资源服务
        /// </summary>
        private GHResourceService ghResourceService = new GHResourceService();

        /// <summary>
        /// VIZ资源文件控制器
        /// </summary>
        private GHResourceFileController ghResourceFileController;

        // ==================================================================================
        // Command
        // ==================================================================================

        #region LoadedCommand -- 加载命令

        /// <summary>
        /// 加载命令
        /// </summary>
        public VCommand LoadedCommand { get; set; }

        /// <summary>
        /// 加载
        /// </summary>
        private void Loaded()
        {
            if (this.IsAlreadyLoaded)
                return;

            this.IsFolderLoading = true;

            // 刷新文件夹
            this.RefreshFolder();

            this.IsAlreadyLoaded = true;
        }

        #endregion

        #region FolderExpandCommand -- 文件夹展开命令

        /// <summary>
        /// 文件夹展开命令
        /// </summary>
        public VCommand<DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs> FolderExpandCommand { get; set; }

        /// <summary>
        /// 文件夹展开
        /// </summary>
        private void FolderExpand(DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs e)
        {
            if (this.SelectedFolderModel == null || e.ChangedButton != System.Windows.Input.MouseButton.Left)
                return;

            this.SelectedFolderModel.IsExpand = !this.SelectedFolderModel.IsExpand;
        }

        #endregion

        #region FileRowFilterCommand -- 文件行筛选命令

        /// <summary>
        /// 文件行筛选命令, 该命令必须使用Dev的命令基类
        /// </summary>
        public DevExpress.Mvvm.DelegateCommand<RowFilterArgs> FileRowFilterCommand { get; set; }

        /// <summary>
        /// 文件行筛选
        /// </summary>
        /// <param name="e">赛选参数</param>
        private void FileRowFilter(RowFilterArgs e)
        {
            GHResourceFileModel fileModel = e.Item as GHResourceFileModel;
            if (fileModel == null)
            {
                e.Visible = false;
                return;
            }

            if (this.FilterResourceFileType == ResourceFileType.NONE)
            {
                e.Visible = true;
                return;
            }

            e.Visible = fileModel.FileType == this.FilterResourceFileType;
        }

        #endregion

        #region RefreshFolderCommand -- 刷新文件夹命令

        /// <summary>
        /// 刷新文件夹命令
        /// </summary>
        public VCommand RefreshFolderCommand { get; set; }

        #endregion

        #region RefreshFileCommand -- 刷新文件命令

        /// <summary>
        /// 刷新文件命令
        /// </summary>
        public VCommand RefreshFileCommand { get; set; }

        #endregion

        #region FileFilterCommand -- 文件过滤命令

        /// <summary>
        /// 文件过滤命令
        /// </summary>
        public VCommand<ResourceFileType> FileFilterCommand { get; set; }

        #endregion

        #region FileDoubleClickCommand -- 文件双击命令

        /// <summary>
        /// 文件双击命令
        /// </summary>
        public VCommand FileDoubleClickCommand { get; set; }

        /// <summary>
        /// 文件双击
        /// </summary>
        private void FileDoubleClick()
        {
            this.OnFileDoubleClick?.Invoke(this, new GHResourceFileDoubleClickEventArgs { File = this.SelectedFileModel });
        }

        #endregion

        // ==================================================================================
        // Public Function
        // ==================================================================================

        /// <summary>
        /// 文件过滤
        /// </summary>
        /// <param name="type"></param>
        public void FileFilter(ResourceFileType type)
        {
            this.FilterResourceFileType = type;

            GHResourcePanel view = this.GetView<GHResourcePanel>();
            if (view == null)
                return;

            view.fileGrid.RefreshData();
        }

        /// <summary>
        /// 刷新文件夹
        /// </summary>
        public void RefreshFolder()
        {
            this.IsFolderLoading = true;

            Task.Run(() =>
            {
                try
                {
                    VizConfigEntity vizConfig = ApplicationDomainEx.VizConfig;

                    string url = $"http://{vizConfig.GH_IP}:{vizConfig.GH_Port}/folders/";
                    List<GHResourceFolderModel> list = this.ghResourceService.GetGHResourceFolders(url, null);

                    WPFHelper.BeginInvoke(() =>
                    {
                        this.FolderModels = list.FirstOrDefault(p => p.EntryNode.title == "data")?.Children?
                                                .Select(p => (GHResourceFolderModel)p).ToObservableCollection();

                        this.IsFolderLoading = false;
                    });
                }
                catch (Exception ex)
                {
                    log.Error(ex);
                }
            });
        }

        /// <summary>
        /// 刷新文件
        /// </summary>
        public void RefreshFile()
        {
            GHResourceFolderModel folder = this.SelectedFolderModel;

            if (folder == null)
                return;

            this.ghResourceFileController.DisposeFileModels(folder);

            folder.IsRefreshedFiles = false;

            this.ghResourceFileController.UpdateFileModels(this.SelectedFolderModel);
        }
    }
}