using Common;
using Common.DevicesModels;
using Common.Models;
using CommunityToolkit.Mvvm.Input;
using MegaRobo.C00225155.DataAccess;
using MegaRobo.Contract;
using MegaRobo.Entities;
using MegaRobo.WpfInfrastructure.Abstractions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MegaRobo.C00225155App.MenuViewModels
{
    public class SuckFluidViewModel : ViewModelBaseEx
    {
        public List<EnumItem<SuckMode>> SuckModeItems { get; set; }
        public List<EnumItem<DrainageMode>> DrainageModeItems { get; set; }

        private SuckMode selectedsuckmode;
        /// <summary>
        /// 选择的吸液模式
        /// </summary>
        public SuckMode SelectedSuckMode
        {
            get => selectedsuckmode;
            set
            {
                if (SetProperty(ref selectedsuckmode, value))
                {
                    UpdateSuckFluidPropByMode(value);
                }
            }
        }

        private DrainageMode selecteddrainagemode;
        /// <summary>
        /// 选择的排液模式
        /// </summary>
        public DrainageMode SelectedDrainageMode
        {
            get => selecteddrainagemode;
            set
            {
                if (SetProperty(ref selecteddrainagemode, value))
                {
                    UpdateDrainagePropByMode(value);
                }
            }
        }

        private object suckfluidprop;
        public object SuckFluidProp
        {
            get => suckfluidprop;
            set
            {
                if (SetProperty(ref suckfluidprop, value))
                {
                    ParseProperties();
                }
            }
        }

        private object drainageprop;
        public object DrainageProp
        {
            get => drainageprop;
            set
            {
                if (SetProperty(ref drainageprop, value))
                {
                    ParseDrainageProperties();
                }
            }
        }

        private double ratio;

        public double Ratio
        {
            get { return ratio; }
            set { ratio = value; }
        }


        private string liquidname;
        public string LiquidName
        {
            get => liquidname;
            set => SetProperty(ref liquidname, value);
        }

        private ObservableCollection<PropertyItem> _properties = new ObservableCollection<PropertyItem>();
        public ObservableCollection<PropertyItem> Properties
        {
            get => _properties;
            set => SetProperty(ref _properties, value);
        }

        private ObservableCollection<PropertyItem> _drainageproperties = new ObservableCollection<PropertyItem>();
        public ObservableCollection<PropertyItem> DrainageProperties
        {
            get => _drainageproperties;
            set => SetProperty(ref _drainageproperties, value);
        }

        public override void Initialize(ICoreService coreService, string title, params object[] args)
        {
            base.Initialize(coreService, title, args);
        }

        protected override void LoadServices()
        {
            base.LoadServices();
        }

        protected override void LoadDatas()
        {
            base.LoadDatas();
        }

        protected override void Register()
        {
            base.Register();
        }

        public SuckFluidViewModel()
        {
            SuckModeItems = EnumHelperr.GetEnumDescriptionList<SuckMode>();
            DrainageModeItems = EnumHelperr.GetEnumDescriptionList<DrainageMode>();
        }

        /// <summary>
        /// 根据选中的吸液模式，更新吸液参数配置实例
        /// </summary>
        /// <param name="mode">选中的吸液模式</param>
        private void UpdateSuckFluidPropByMode(SuckMode mode)
        {
            // 保存当前模式的参数（如果已有配置，用于保留可复用的参数值）
            var currentValues = SuckFluidProp != null ? GetCurrentPropertyValues(SuckFluidProp) : null;

            // 根据新模式创建对应的参数配置实例（如 MA→SuckFluidByMA）
            SuckFluidProp = mode switch
            {
                SuckMode.MA => new SuckFluidByMA(),
                SuckMode.ME => new SuckFluidByME(),
                SuckMode.MG => new SuckFluidByMG(),
                _ => new SuckFluidByMA() // 默认值
            };

            // 如果有旧参数，尝试将可复用的值同步到新实例（可选逻辑）
            if (currentValues != null)
            {
                SyncPropertyValues(SuckFluidProp, currentValues);
            }

            // 重新解析参数列表，更新界面显示
            ParseProperties();
        }

        private void ParseProperties()
        {
            Properties.Clear(); // 清空现有内容

            if (SuckFluidProp == null)
                return;

            // 反射获取 SuckFluidProp（实际是 MA/ME/MG 实例）的所有公共属性
            var props = SuckFluidProp.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var prop in props)
            {
                // 跳过不需要编辑的属性（如 CmdCode）
                if (prop.Name == "CmdCode")
                    continue;

                // 获取 [Numeric] 特性
                var numericAttr = prop.GetCustomAttribute<NumericAttribute>();

                // 添加到 Properties 集合（供界面显示）
                Properties.Add(new PropertyItem
                {
                    Name = prop.Name,
                    Description = numericAttr?.Descr ?? "无描述",
                    Value = prop.GetValue(SuckFluidProp), // 初始值
                    Type = prop.PropertyType,
                    NumericAttribute = numericAttr,
                    TargetObject = SuckFluidProp,
                    PropertyInfo = prop
                });
            }
        }

        /// <summary>
        /// 根据选中的分液模式，更新分液参数配置实例
        /// </summary>
        /// <param name="mode">选中的分液模式</param>
        private void UpdateDrainagePropByMode(DrainageMode mode)
        {
            // 保存当前模式的参数（如果已有配置）
            var currentValues = DrainageProp != null ? GetCurrentPropertyValues(DrainageProp) : null;

            // 根据新模式创建对应的参数配置实例（如 ML→DrainageFluidByML）
            DrainageProp = mode switch
            {
                DrainageMode.ML => new DrainageFluidByML(),
                DrainageMode.MH => new DrainageFluidByMH(),
                _ => new DrainageFluidByML() // 默认值
            };

            // 同步可复用的旧参数到新实例（可选逻辑）
            if (currentValues != null)
            {
                SyncPropertyValues(DrainageProp, currentValues);
            }

            // 重新解析参数列表，更新界面显示
            ParseDrainageProperties();
        }

        private void ParseDrainageProperties()
        {
            DrainageProperties.Clear(); // 清空现有内容

            if (DrainageProp == null)
                return;

            // 反射获取 SuckFluidProp（实际是 MA/ME/MG 实例）的所有公共属性
            var props = DrainageProp.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var prop in props)
            {
                // 跳过不需要编辑的属性（如 CmdCode）
                if (prop.Name == "CmdCode")
                    continue;

                // 获取 [Numeric] 特性
                var numericAttr = prop.GetCustomAttribute<NumericAttribute>();

                // 添加到 Properties 集合（供界面显示）
                DrainageProperties.Add(new PropertyItem
                {
                    Name = prop.Name,
                    Description = numericAttr?.Descr ?? "无描述",
                    Value = prop.GetValue(DrainageProp), // 初始值
                    Type = prop.PropertyType,
                    NumericAttribute = numericAttr,
                    TargetObject = DrainageProp,
                    PropertyInfo = prop
                });
            }
        }

        /// <summary>
        /// 获取当前参数实例的所有属性值（用于模式切换时暂存）
        /// </summary>
        private Dictionary<string, object> GetCurrentPropertyValues(object obj)
        {
            if (obj == null) return null;

            var values = new Dictionary<string, object>();
            var props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var prop in props)
            {
                // 只保存需要复用的属性（排除 CmdCode 等模式专属字段）
                if (prop.Name != "CmdCode")
                {
                    values[prop.Name] = prop.GetValue(obj);
                }
            }
            return values;
        }

        /// <summary>
        /// 将旧参数值同步到新实例（仅同步名称和类型匹配的属性）
        /// </summary>
        private void SyncPropertyValues(object newObj, Dictionary<string, object> oldValues)
        {
            if (newObj == null || oldValues == null) return;

            var newProps = newObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var prop in newProps)
            {
                // 只同步名称存在于旧参数且类型匹配的属性
                if (oldValues.TryGetValue(prop.Name, out var oldValue)
                    && prop.PropertyType.IsAssignableFrom(oldValue.GetType()))
                {
                    prop.SetValue(newObj, oldValue);
                }
            }
        }

    }
}
