using UIShare.UIViewModel;
using UIShare.GlobalVariable;
using UIShare.PubEvent;
using Logger;
using MaterialDesignThemes.Wpf;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows.Input;
using System.Xml;
using UIShare.ViewModelBase;
using Prism.Events;

namespace TestingModule.ViewModels
{
    public class ParametersManagerViewModel:NavigateViewModelBase, IDisposable
    {
        #region 属性
        private ObservableCollection<DeviceInfoVM> _DeviceInfoModel;

        public ObservableCollection<DeviceInfoVM> DeviceInfoVM
        {
            get { return _DeviceInfoModel; }
            set { SetProperty(ref _DeviceInfoModel, value); }
        }

        public ProgramVM Program
        {
            get => _ScopedContext.Program;
            set
            {
                if (_ScopedContext.Program != value)
                {
                    _ScopedContext.Program = value;
                    RaisePropertyChanged();
                }
            }
        }
        private ParameterVM _SelectedParameter;
        public ParameterVM SelectedParameter
        {
            get => _SelectedParameter;
            set
            {
                if (SetProperty(ref _SelectedParameter, value))
                {
                    _ScopedContext.SelectedParameter = value;
                }
            }
        }
        private DeviceInfoVM _SelectedDevice;

        

        public DeviceInfoVM SelectedDevice
        {
            get { return _SelectedDevice; }
            set { SetProperty(ref _SelectedDevice, value); }
        }
        #endregion
        private ScopedContext _ScopedContext { get; set; }
        private readonly SystemConfig _systemConfig;
        private readonly GlobalInfo _globalInfo;
        private readonly DeviceManager _deviceManager;
        private readonly IContainerProvider _containerProvider;
        #region 命令
        public ICommand ParameterAddCommand { get; set; }
        public ICommand ParameterEditCommand { get; set; }
        public ICommand ParameterDeleteCommand { get; set; }
        public ICommand DeviceEditCommand { get; set; }
        public ICommand ReConnectCommand { get; set; }
        public ICommand CloseCommand { get; set; }
        public ICommand LoadedCommand { get; set; }
        #endregion

        public ParametersManagerViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            _ScopedContext = containerProvider.Resolve<ScopedContext>();
            _systemConfig = containerProvider.Resolve<SystemConfig>();
            _deviceManager = containerProvider.Resolve<DeviceManager>();
            _globalInfo = containerProvider.Resolve<GlobalInfo>();
            _containerProvider = containerProvider;
            Program = _ScopedContext.Program;
            ParameterAddCommand = new DelegateCommand(ParameterAdd);
            ParameterEditCommand = new DelegateCommand(ParameterEdit);
            ParameterDeleteCommand = new DelegateCommand(ParameterDelete);
            DeviceEditCommand = new DelegateCommand(DeviceEdit);
            ReConnectCommand = new AsyncDelegateCommand(OnReConnect);
            CloseCommand = new AsyncDelegateCommand(OnClose);
            LoadedCommand = new DelegateCommand(OnLoad);
            InitParameters();
        }


        #region 委托命令 
        private void InitParameters()
        {
            foreach(var item in _systemConfig.ParameterList)
            {
                var copy=new ParameterVM(item);
                var param = _systemConfig.SharedParameterList.FirstOrDefault(x => x.ParameterName == copy.Name);
                if (param != null)
                {
                    copy.Value = param.Value;
                }
                Program.Parameters.Add(copy);
            }
        }
        private void OnLoad()
        {
            DeviceInfoVM = _systemConfig.DeviceList;
        }  private async Task OnReConnect()
        {
            await _deviceManager.ConnectSpecifiedDevice(SelectedDevice.DeviceName);
        }  private async Task OnClose()
        {
            await _deviceManager.CloseDeviceAsync(SelectedDevice.DeviceName);
        }
        /// <summary>
        /// 跟踪已打开的弹窗管理器窗口实例，避免重复打开多个 DialogMangerView 窗口。
        /// </summary>
        private static System.Windows.Window? _dialogWindow;

        private void DeviceEdit()
        {
            if (!_globalInfo.IsAdmin) return;
            if (SelectedDevice == null) return;
            var type = SelectedDevice.DeviceType.Split('.').Last();
            var viewName = type + "View";
            var vmName = type + "ViewModel"; // 按照命名规范拼接出对应的 VM 类型名

            try
            {
                // 1. 先确保弹窗管理器窗口已打开
                if (_dialogWindow == null || !_dialogWindow.IsVisible)
                {
                    _dialogService.Show("DialogMangerView");
                    _dialogWindow = System.Windows.Application.Current.Windows
                        .OfType<System.Windows.Window>()
                        .FirstOrDefault(w => w.DataContext?.GetType().Name == "DialogMangerViewModel");
                }

                // 2. 从当前专属容器解析设备编辑 View 实例
                var view = _containerProvider.Resolve<object>(viewName) as System.Windows.FrameworkElement;
                if (view == null) return;

                // 3. 关键：从同一个台架的专属容器中解析出该设备对应的 ViewModel 实例
                // 从而实现：不同的台架（不同的专属 _containerProvider）解析出各自独立的 VM 实例
                var vmType = Assembly.Load("DeviceEditModule").GetType($"DeviceEditModule.ViewModels.{vmName}");
                if (vmType != null)
                {
                    var scopedViewModel = _containerProvider.Resolve(vmType);
                    if (scopedViewModel != null)
                    {
                        // 手动绑定 DataContext，将其锁死在当前作用域内
                        view.DataContext = scopedViewModel;
                    }
                }

                // 4. 调用 ViewModel 上的 Initialize 方法
                var vm = view.DataContext;
                if (vm != null)
                {
                    var initMethod = vm.GetType().GetMethod("Initialize", new[] { typeof(string) });
                    initMethod?.Invoke(vm, new object[] { SelectedDevice.DeviceName });
                }

                // 5. 发布事件，将绑定好独立 VM 的 View 实例作为 Tab 载入
                var fingerprint = DeviceManager.ExtractHardwareFingerprint(SelectedDevice);
                _eventAggregator.GetEvent<AddDialogTabEvent>().Publish(new DialogTabInfo
                {
                    Title = $"{_globalInfo.CurrentScope} - {SelectedDevice.DeviceName}",
                    Fingerprint = fingerprint,
                    Content = view
                });

                // 6. 窗口置顶
                if (_dialogWindow != null && _dialogWindow.IsVisible)
                {
                    if (_dialogWindow.WindowState == System.Windows.WindowState.Minimized)
                        _dialogWindow.WindowState = System.Windows.WindowState.Normal;
                    _dialogWindow.Activate();
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.ErrorWithNotify(_globalInfo.CurrentScope, $"打开设备编辑窗口 [{type}] 失败：{ex.Message}");
            }
        }

        private void ParameterDelete()
        {
            if (!_globalInfo.IsAdmin || !SelectedParameter.IsEditable) return;
            Program.Parameters.Remove(SelectedParameter);
        }

        private void ParameterEdit()
        {
            if (!_globalInfo.IsAdmin) return;
            var param = new DialogParameters
            {
                { "Mode",SelectedParameter==null?"ADD":"Edit" },
                { "ScopedContext",_ScopedContext }
            };
            _dialogService.ShowDialog("ParameterSetting", param, (r) =>
            {
                if (r.Result == ButtonResult.OK)
                {
                    _eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
                    ShowInfoMessageBox("保存成功", () => { });
                }
                else if (r.Result == ButtonResult.Yes)
                {
                ShowErrorMessageBox("公共变量只能设置变量类型（Input,Temp）", ()=>{ });
                }
                
            });
        }

        private void ParameterAdd()
        {
            if (!_globalInfo.IsAdmin) return;
            var param = new DialogParameters
            {
                { "Mode", "ADD" },
                { "ScopedContext",_ScopedContext }
            };
            _dialogService.ShowDialog("ParameterSetting", param, (r) =>
            {
                if (r.Result == ButtonResult.OK)
                {
                    _eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
                }
                else
                {

                }
                
            });
        }


        #endregion
        public void Dispose()
        {
            try
            {
                DeviceInfoVM?.Clear();
                DeviceInfoVM = null!;
                SelectedParameter = null!;
                SelectedDevice = null!;
                if (_ScopedContext != null)
                {
                    _ScopedContext.SelectedParameter = null;
                    _ScopedContext = null!;
                }
            }
            catch (Exception ex)
            {
                Logger.LoggerHelper.Error($"释放参数管理组件（ParametersManagerViewModel）资源失败: {ex.Message}");
            }
        }
    }
}
