using Prism.Commands;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using UIShare.PubEvent;
using UIShare.UIViewModel;
using UIShare.ViewModelBase;

namespace DeviceEditModule.ViewModels
{
    /// <summary>
    /// 弹窗管理器 ViewModel。
    /// <para>
    /// 职责：<br/>
    /// 1. 订阅 <see cref="AddDialogTabEvent"/>，将外部弹窗注册为 Tab；<br/>
    /// 2. 维护 <see cref="TagItems"/> 集合，控制选中/关闭逻辑；<br/>
    /// 3. 最小化：通过 <see cref="MinimizeRequested"/> 事件通知 View 执行 P/Invoke 窗口操作；<br/>
    /// 4. 关闭：调用 <see cref="RequestClose"/>。
    /// </para>
    /// </summary>
    public class DialogMangerViewModel : DialogViewModelBase, IDisposable
    {
        #region 属性

        /// <summary>所有 Tab 项集合，绑定到标签条的 ItemsControl。</summary>
        public ObservableCollection<DialogTabItemVM> TagItems { get; } = new();

        /// <summary>以设备指纹为 key 追踪已打开的 Tab，防止同一物理设备重复打开。</summary>
        private readonly Dictionary<string, DialogTabItemVM> _tabDictionary = new();

        private DialogTabItemVM? _selectedTag;
        /// <summary>当前激活的 Tab，其 Content 显示在内容区。</summary>
        public DialogTabItemVM? SelectedTag
        {
            get => _selectedTag;
            set => SetProperty(ref _selectedTag, value);
        }

        /// <summary>是否没有任何 Tab（用于绑定空状态提示的 Visibility）。</summary>
        public bool HasNoTabs => TagItems.Count == 0;

        #endregion

        #region 命令

        public ICommand MinimizeCommand { get; }
        public ICommand CloseCommand    { get; }

        #endregion

        #region 事件

        /// <summary>
        /// View 订阅此事件后，在事件回调里执行 P/Invoke 最小化。
        /// 这样 ViewModel 无需引用任何 UI 或 Win32 类型。
        /// </summary>
        public event EventHandler? MinimizeRequested;
        public event EventHandler? RestoreRequested;
        #endregion

        public DialogMangerViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            MinimizeCommand = new DelegateCommand(OnMinimize);
            CloseCommand    = new DelegateCommand(OnClose);

            // 订阅来自其他模块的"添加 Tab"事件
            _eventAggregator.GetEvent<AddDialogTabEvent>().Subscribe(OnAddTab, ThreadOption.UIThread);
            _eventAggregator.GetEvent<CancelMinimizeEvent>().Subscribe(()=>RestoreRequested.Invoke(this, EventArgs.Empty));
        }

        #region 命令处理

        private void OnMinimize() => MinimizeRequested?.Invoke(this, EventArgs.Empty);

        private void OnClose()
        {
            // 关闭前清空所有 Tab，释放内容引用，并清除去重字典
            _tabDictionary.Clear();
            TagItems.Clear();
            SelectedTag = null;
            RequestClose.Invoke();
        }

        #endregion

        #region Tab 管理

        /// <summary>收到事件：若指纹已存在则激活，否则创建并追加到集合。</summary>
        private void OnAddTab(DialogTabInfo info)
        {
            // 已有相同指纹的 Tab → 直接激活，不重复创建
            if (!string.IsNullOrEmpty(info.Fingerprint) && _tabDictionary.TryGetValue(info.Fingerprint, out var existing))
            {
                ActivateTab(existing);
                return;
            }

            var tab = new DialogTabItemVM(OnSelectTab, OnCloseTab)
            {
                Title      = info.Title,
                Fingerprint = info.Fingerprint,
                Content    = info.Content
            };

            if (!string.IsNullOrEmpty(info.Fingerprint))
                _tabDictionary[info.Fingerprint] = tab;

            TagItems.Add(tab);
            RaisePropertyChanged(nameof(HasNoTabs));
            ActivateTab(tab);
        }

        /// <summary>激活（选中）指定 Tab，其余全部取消选中。</summary>
        private void OnSelectTab(DialogTabItemVM tab) => ActivateTab(tab);

        /// <summary>关闭指定 Tab，自动选中相邻 Tab（或清空内容区）。</summary>
        private void OnCloseTab(DialogTabItemVM tab)
        {
            int idx = TagItems.IndexOf(tab);
            if (!string.IsNullOrEmpty(tab.Fingerprint))
                _tabDictionary.Remove(tab.Fingerprint);
            TagItems.Remove(tab);
            RaisePropertyChanged(nameof(HasNoTabs));

            if (TagItems.Count == 0)
            {
                SelectedTag = null;
                return;
            }

            // 优先选左侧邻 Tab，无左侧则选当前索引（已向左移一位）
            ActivateTab(TagItems[Math.Max(0, idx - 1)]);
        }

        private void ActivateTab(DialogTabItemVM tab)
        {
            foreach (var t in TagItems)
                t.IsSelected = false;

            tab.IsSelected = true;
            SelectedTag = tab;
        }

        #endregion

        public void Dispose()
        {
            _eventAggregator.GetEvent<AddDialogTabEvent>().Unsubscribe(OnAddTab);
        }
    }
}
