using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Data;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.UI.Client.CenterViews.Editors.Sequence;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel;
using OpenSEMI.ClientBase;

namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
{
    public class RecipeSelectDialogViewModel : DialogViewModel<string>
    {

        #region Variables

        private readonly RecipeType _fileTypes;
        private readonly bool _isFolderOnly;
        private readonly bool _isShowRootNode;
        private FileNode _currentFileNode;

        #endregion

        #region Constructors

        public RecipeSelectDialogViewModel(string model = null)
        {
            _fileTypes = RecipeType.Process | RecipeType.Routine | RecipeType.Clean;
            _isFolderOnly = false;
            _isShowRootNode = false;

            BuildFileTree(_isShowRootNode, _isFolderOnly, _fileTypes, model);
        }

        public RecipeSelectDialogViewModel(bool isShowRootNode, bool isFolderOnly, RecipeType fileType, string model=null)
        {
            _fileTypes = fileType;
            _isFolderOnly = isFolderOnly;
            _isShowRootNode = isShowRootNode;

            BuildFileTree(isShowRootNode, isFolderOnly, fileType, model);
        }

        #endregion

        #region Properties

        public List<ProcessTypeFileItem> ProcessTypeFileList { get; set; }

        public FileNode CurrentFileNode { get; set; }

        public int ProcessTypeIndexSelection { get; set; }

        public ObservableCollection<FileNode> Files { get; set; }

        public ListCollectionView FileView { get; set; }

        private string _currentCriteria = string.Empty;

        public string CurrentCriteria
        {
            get => _currentCriteria;
            set
            {
                if (value == _currentCriteria)
                    return;

                _currentCriteria = value;
                NotifyOfPropertyChange(nameof(CurrentCriteria));

                ApplyFilter();
            }
        }

        #endregion

        #region Private Methods

        private void BuildFileTree(bool isShowRootNode, bool isFolderOnly, RecipeType fileType, string model=null)
        {
            string modelName = model == null ? "" : "\\" + model;

            var recipeProvider = new RecipeProvider();
            var scProcessType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedProcessType").ToString();
            var supportedRecipeType = new List<RecipeType>(new[] { RecipeType.Process, RecipeType.Routine });
            
            if (!string.IsNullOrEmpty(scProcessType))
            {
                supportedRecipeType.Clear();

                if (fileType.HasFlag(RecipeType.Process) && scProcessType.Contains(RecipeType.Process.ToString()))
                    supportedRecipeType.Add(RecipeType.Process);

                if (fileType.HasFlag(RecipeType.Routine) && scProcessType.Contains(RecipeType.Routine.ToString()))
                    supportedRecipeType.Add(RecipeType.Routine);

                if (fileType.HasFlag(RecipeType.Clean) && scProcessType.Contains(RecipeType.Clean.ToString()))
                    supportedRecipeType.Add(RecipeType.Clean);
            }

            var processTypeFileList = new List<ProcessTypeFileItem>();

            for (var i = 0; i < supportedRecipeType.Count; i++)
            {
                var type = new ProcessTypeFileItem
                {
                    ProcessType = supportedRecipeType[i]
                };
                var prefix = $"Sic{modelName}\\{supportedRecipeType[i]}";
                var recipes = recipeProvider.GetXmlRecipeList(prefix);
                type.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, "", false, recipes, isFolderOnly, isShowRootNode)[0].Files;
                processTypeFileList.Add(type);
            }

            this.ProcessTypeFileList = processTypeFileList;
        }

        #endregion

        #region Methods

        private void ApplyFilter()
        {
            foreach (var node in ProcessTypeFileList[ProcessTypeIndexSelection].FileListByProcessType)
                node.ApplyCriteria(CurrentCriteria, new Stack<FileNode>());
        }

        public void ClearFilter()
        {
            CurrentCriteria = "";
        }

        public void TreeSelectChanged(FileNode file)
        {
            _currentFileNode = file;
        }

        public void TreeMouseDoubleClick(FileNode file)
        {
            _currentFileNode = file;
            OK();
        }

        public void OK()
        {
            if (this._currentFileNode == null)
                return;

            if (_isFolderOnly)
            {
                if (this._currentFileNode.IsFile)
                    return;

                this.DialogResult = _currentFileNode.PrefixPath + "\\" + _currentFileNode.FullPath;
                IsCancel = false;
                TryClose(true);
            }
            else
            {
                if (!this._currentFileNode.IsFile)
                    return;

                this.DialogResult = _currentFileNode.PrefixPath + "\\" + _currentFileNode.FullPath;
                IsCancel = false;
                TryClose(true);

            }
        }

        public void Cancel()
        {
            IsCancel = true;
            TryClose(false);
        }

       

        #endregion
    }
}
