using DeviceCommand.Devices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UIShare.GlobalVariable;
using UIShare.ViewModelBase;

namespace DeviceEditModule.ViewModels
{
    public class IT6015CViewModel : NavigateViewModelBase, IDisposable
    {
        #region 私有字段
        private readonly DeviceManager _deviceManager;
        private IT6015C? _device;
        private CancellationTokenSource? _cts;
        #endregion
        #region 属性
        private string _deviceName = "IT6015C";
        public string DeviceName
        {
            get => _deviceName;
            set => SetProperty(ref _deviceName, value);
        }

        private bool _isConnected;
        public bool IsConnected
        {
            get => _isConnected;
            set => SetProperty(ref _isConnected, value);
        }
        private bool _isBusy;
        /// <summary>正在执行设备命令时为 true，用于 UI 忙碌状态指示。</summary>
        public bool IsBusy
        {
            get => _isBusy;
            set => SetProperty(ref _isBusy, value);
        }
        private string _responseLog = string.Empty;
        /// <summary>命令响应日志（最新消息在顶部）。</summary>
        public string ResponseLog
        {
            get => _responseLog;
            set => SetProperty(ref _responseLog, value);
        }

        #endregion
        #region 命令
        #endregion
        public IT6015CViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            _deviceManager = containerProvider.Resolve<DeviceManager>();
        }
        public void Dispose()
        {
            _cts?.Cancel();
            _cts?.Dispose();
        }
        #region 初始化 / Navigation

        /// <summary>
        /// 从 DeviceManager 中查找IT6015C设备实例。
        /// 优先按 <paramref name="deviceName"/> 查找，否则取第一个匹配类型的设备。
        /// </summary>
        public void Initialize(string? deviceName = null)
        {
            IT6015C? found = null;
            string? foundName = null;
            if (deviceName != null &&
                _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) &&
                d is IT6015C e)
            {
                found = e;
                foundName = deviceName;
            }
            else
            {
                foreach (var kv in _deviceManager.DeviceMap)
                {
                    if (kv.Value is IT6015C it)
                    {
                        found = it;
                        foundName = kv.Key;
                        break;
                    }
                }
            }

            _device = found;
            DeviceName = foundName ?? "IT7800E (未找到)";
            IsConnected = _device?.IsConnected ?? false;

            AppendLog(found != null
                ? $"已关联设备 [{DeviceName}]，连接状态：{(IsConnected ? "已连接" : "未连接")}"
                : "未在 DeviceManager 中找到 IT7800E 设备，请先初始化设备配置。");
        }
        #region 辅助

        private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;

        private async Task Exec(Func<Task> action)
        {
            if (_device == null)
            {
                AppendLog("错误：未关联到设备实例，请检查设备配置。");
                return;
            }
            if (IsBusy) return;
            IsBusy = true;
            try
            {
                await action();
                IsConnected = _device.IsConnected;
            }
            catch (OperationCanceledException)
            {
                AppendLog("命令超时或已取消。");
            }
            catch (Exception ex)
            {
                AppendLog($"错误：{ex.Message}");
            }
            finally
            {
                IsBusy = false;
            }
        }

        private void AppendLog(string message)
        {
            var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
            ResponseLog = ResponseLog.Length > 4000
                ? line + "\n" + ResponseLog[..3000]
                : line + "\n" + ResponseLog;
        }

        #endregion
        public override void OnNavigatedTo(NavigationContext context)
        {
            var name = context.Parameters.GetValue<string?>("DeviceName");
            Initialize(name);
        }

        #endregion
    }
}
