using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using PersonalToolBox.Helpers;
using PersonalToolBox.Models;
using PersonalToolBox.Services;

namespace PersonalToolBox.ViewModels;

/// <summary>
/// 工具编辑窗口 ViewModel，管理添加/编辑工具的交互逻辑
/// </summary>
public partial class ToolEditViewModel : ObservableObject
{
    private readonly IDataService _dataService;
    private readonly ILogService _logService;
    private readonly ToolItem? _editingTool;

    // ───────────────────────────── 可观察属性 ─────────────────────────────

    [ObservableProperty]
    private string _windowTitle = "添加工具";

    [ObservableProperty]
    private string _name = string.Empty;

    [ObservableProperty]
    private string _executablePath = string.Empty;

    [ObservableProperty]
    private string _arguments = string.Empty;

    [ObservableProperty]
    private string _hotKey = string.Empty;

    [ObservableProperty]
    private Category? _selectedCategory;

    [ObservableProperty]
    private IconProvider.IconOption? _selectedIcon;

    [ObservableProperty]
    private bool _autoRunOnStart;

    /// <summary>
    /// 分类下拉列表
    /// </summary>
    public ObservableCollection<Category> Categories { get; } = new();

    /// <summary>
    /// 按分类分组的可用图标列表
    /// </summary>
    public ListCollectionView AvailableIconsView { get; }

    /// <summary>
    /// 窗口关闭回调（由 View 层设置）
    /// </summary>
    public Action<bool?>? CloseAction { get; set; }

    /// <summary>
    /// 是否保存成功（供调用方判断是否需要刷新）
    /// </summary>
    public bool Saved { get; private set; }

    // ───────────────────────────── 构造函数 ─────────────────────────────

    public ToolEditViewModel(IDataService dataService, ILogService logService, ToolItem? toolToEdit = null)
    {
        _dataService = dataService;
        _logService = logService;
        _editingTool = toolToEdit;

        AvailableIconsView = new ListCollectionView(IconProvider.AvailableIcons);
        AvailableIconsView.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

        // 加载分类列表
        foreach (var cat in _dataService.Config.Categories)
            Categories.Add(cat);

        // 编辑模式
        if (toolToEdit != null)
        {
            WindowTitle = "编辑工具";
            Name = toolToEdit.Name;
            ExecutablePath = toolToEdit.ExecutablePath;
            Arguments = toolToEdit.Arguments;
            HotKey = toolToEdit.HotKey;
            SelectedCategory = Categories.FirstOrDefault(c => c.Id == toolToEdit.CategoryId);
            AutoRunOnStart = toolToEdit.AutoRunOnStart;

            if (!string.IsNullOrEmpty(toolToEdit.IconCode))
            {
                SelectedIcon = IconProvider.AvailableIcons.FirstOrDefault(i => i.Icon.ToString() == toolToEdit.IconCode);
            }
        }
    }

    // ───────────────────────────── 命令 ─────────────────────────────

    /// <summary>
    /// 浏览本地文件
    /// </summary>
    [RelayCommand]
    private void BrowseFile()
    {
        var dialog = new OpenFileDialog
        {
            Title = "选择可执行文件或脚本",
            Filter = "所有文件|*.*|可执行文件|*.exe|脚本文件|*.bat;*.cmd;*.ps1;*.py|快捷方式|*.lnk"
        };

        if (dialog.ShowDialog() == true)
        {
            ExecutablePath = dialog.FileName;
            if (string.IsNullOrWhiteSpace(Name))
            {
                Name = Path.GetFileNameWithoutExtension(dialog.FileName);
            }
        }
    }

    /// <summary>
    /// 保存工具
    /// </summary>
    [RelayCommand]
    private void Save()
    {
        try
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                _logService.Warning("工具名称不能为空");
                return;
            }

            if (string.IsNullOrWhiteSpace(ExecutablePath))
            {
                _logService.Warning($"工具 \"{Name}\" 路径不能为空");
                return;
            }

            // 编辑模式：更新已有工具
            if (_editingTool != null)
            {
                _editingTool.Name = Name.Trim();
                _editingTool.IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty;
                _editingTool.ExecutablePath = ExecutablePath.Trim();
                _editingTool.Arguments = Arguments.Trim();
                _editingTool.HotKey = HotKey.Trim();
                _editingTool.CategoryId = SelectedCategory?.Id ?? string.Empty;
                _editingTool.IsValid = IsExecutablePathValid(ExecutablePath.Trim());
                _editingTool.AutoRunOnStart = AutoRunOnStart;

                _logService.Info($"已更新工具: {Name.Trim()}");
            }
            // 添加模式：创建新工具
            else
            {
                var newTool = new ToolItem
                {
                    Name = Name.Trim(),
                    IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty,
                    ExecutablePath = ExecutablePath.Trim(),
                    Arguments = Arguments.Trim(),
                    HotKey = HotKey.Trim(),
                    CategoryId = SelectedCategory?.Id ?? string.Empty,
                    IsValid = IsExecutablePathValid(ExecutablePath.Trim()),
                    AutoRunOnStart = AutoRunOnStart
                };

                _dataService.Config.Tools.Add(newTool);
                _logService.Info($"已添加工具: {Name.Trim()}");
            }

            _dataService.Save();
            Saved = true;
            CloseAction?.Invoke(true);
        }
        catch (Exception ex)
        {
            _logService.Error($"保存工具失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 取消编辑
    /// </summary>
    [RelayCommand]
    private void Cancel()
    {
        CloseAction?.Invoke(false);
    }

    /// <summary>
    /// 验证可执行路径是否有效
    /// </summary>
    private static bool IsExecutablePathValid(string path)
    {
        if (string.IsNullOrWhiteSpace(path))
            return false;

        // URL 格式（https://...）直接通过
        if (Uri.TryCreate(path, UriKind.Absolute, out var uri) &&
            (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
            return true;

        // 纯文件名（无路径分隔符）可能位于系统 PATH 中
        if (!path.Contains('\\') && !path.Contains('/'))
            return true;

        return File.Exists(path);
    }
}
