using System.ComponentModel;
using System.Runtime.CompilerServices;
using YMhut.Box.Core.Plugins;
using YMhut.Box.Core.Tools;

namespace YMhut.Box.WinUI.ViewModels;

public sealed class ToolCardViewModel : INotifyPropertyChanged
{
    private bool _inlinePreviewLoaded;

    public ToolCardViewModel(ToolMetadata metadata)
        : this(new ToolModule(metadata))
    {
    }

    public ToolCardViewModel(IToolModule module)
    {
        Module = module;
        Metadata = module.Metadata;
        Spec = module is ExternalToolModule or BuiltinReferenceToolModule or PluginToolModule
            ? null
            : ToolPageSpecCatalog.For(module);
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    public IToolModule Module { get; }

    public ToolMetadata Metadata { get; }

    public ToolPageSpec? Spec { get; }

    public string Id => Metadata.Id;

    public string Name => ToolText.Name(Module);

    public string Description => ToolText.Description(Module);

    public string IconGlyph => Metadata.IconGlyph;

    public string CategoryLabel => ToolText.CategoryLabel(Metadata.Category);

    public string CapabilityLabel => AppLocalizer.Capability(Metadata.OfflineCapable);

    public string SourceLabel => Module switch
    {
        ExternalToolModule => AppLocalizer.T("外部工具", "External"),
        BuiltinReferenceToolModule => AppLocalizer.T("YMhut 内置", "YMhut built-in"),
        PluginToolModule => AppLocalizer.T("插件工具", "Plugin"),
        _ => AppLocalizer.T("原生工具", "Native")
    };

    public string SafetyLabel => Module switch
    {
        ExternalToolModule { Tool.IsRisky: true } => AppLocalizer.T("需确认", "Confirm"),
        BuiltinReferenceToolModule { Definition.IsRisky: true } => AppLocalizer.T("需确认", "Confirm"),
        PluginToolModule => AppLocalizer.T("隔离", "Isolated"),
        _ => CapabilityLabel
    };

    public string LayoutLabel
    {
        get
        {
            if (Module is ExternalToolModule external)
            {
                return external.Tool.CategoryName;
            }

            if (Module is BuiltinReferenceToolModule)
            {
                return AppLocalizer.T("参考内置", "Reference built-in");
            }

            if (Module is PluginToolModule)
            {
                return AppLocalizer.T("Bridge", "Bridge");
            }

            return Spec?.Layout switch
            {
                ToolLayoutKind.FormatterWorkbench => AppLocalizer.T("格式化", "Formatter"),
                ToolLayoutKind.CodecWorkbench => AppLocalizer.T("编解码", "Codec"),
                ToolLayoutKind.QueryDashboard => AppLocalizer.T("查询", "Query"),
                ToolLayoutKind.Dashboard => AppLocalizer.T("看板", "Dashboard"),
                ToolLayoutKind.CalculatorForm => AppLocalizer.T("计算", "Calculator"),
                ToolLayoutKind.UnitConverter => AppLocalizer.T("换算", "Converter"),
                ToolLayoutKind.ReferenceBrowser => AppLocalizer.T("速查", "Reference"),
                ToolLayoutKind.FileWorkflow => AppLocalizer.T("文件", "File"),
                ToolLayoutKind.MediaNative => AppLocalizer.T("媒体", "Media"),
                ToolLayoutKind.BrowserNative => AppLocalizer.T("浏览器", "Browser"),
                ToolLayoutKind.RandomCinema => AppLocalizer.T("远程媒体", "Remote media"),
                ToolLayoutKind.SystemLauncher => AppLocalizer.T("Windows", "Windows"),
                ToolLayoutKind.SecurityWorkbench => AppLocalizer.T("安全", "Security"),
                _ => AppLocalizer.T("文本", "Text")
            };
        }
    }

    public string ResultLabel
    {
        get
        {
            if (Module is ExternalToolModule external)
            {
                return external.Tool.PrimaryArchitecture ?? external.Tool.Extension;
            }

            if (Module is BuiltinReferenceToolModule builtin)
            {
                return RiskLabel(builtin.Definition.RiskLevel);
            }

            if (Module is PluginToolModule)
            {
                return AppLocalizer.T("挂载项", "Surface");
            }

            return Spec?.Result switch
            {
                ToolResultKind.JsonTree => AppLocalizer.T("JSON 树", "JSON tree"),
                ToolResultKind.CodePreview => AppLocalizer.T("代码预览", "Code preview"),
                ToolResultKind.Table => AppLocalizer.T("表格", "Table"),
                ToolResultKind.RankedList => AppLocalizer.T("榜单", "Ranked list"),
                ToolResultKind.NewsCards => AppLocalizer.T("新闻卡片", "News cards"),
                ToolResultKind.ImagePreview => AppLocalizer.T("图片预览", "Image preview"),
                ToolResultKind.LinkCards => AppLocalizer.T("链接", "Links"),
                ToolResultKind.FileCards => AppLocalizer.T("文件", "Files"),
                ToolResultKind.Diff => AppLocalizer.T("差异", "Diff"),
                ToolResultKind.StatusList => AppLocalizer.T("状态", "Status"),
                ToolResultKind.ColorSwatch => AppLocalizer.T("颜色", "Color"),
                ToolResultKind.CalculatorTable => AppLocalizer.T("结果表", "Result table"),
                ToolResultKind.SystemCards => AppLocalizer.T("系统卡片", "System cards"),
                ToolResultKind.Media => AppLocalizer.T("媒体", "Media"),
                ToolResultKind.ReferenceRows => AppLocalizer.T("参考数据", "Reference"),
                _ => AppLocalizer.T("文本", "Text")
            };
        }
    }

    public string PreviewHint => InlinePreviewLoaded
        ? AppLocalizer.T("预览已按需加载。", "Preview loaded on demand.")
        : AppLocalizer.T("预览会延后加载，以保持工具箱响应。", "Preview is deferred to keep the toolbox responsive.");

    public bool InlinePreviewLoaded
    {
        get => _inlinePreviewLoaded;
        set
        {
            if (_inlinePreviewLoaded == value)
            {
                return;
            }

            _inlinePreviewLoaded = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(PreviewHint));
        }
    }

    private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public override string ToString()
    {
        return $"{Name} / {CategoryLabel} / {Description}";
    }

    private static string RiskLabel(ReferenceToolRiskLevel risk)
    {
        return risk switch
        {
            ReferenceToolRiskLevel.High => AppLocalizer.T("高风险", "High risk"),
            ReferenceToolRiskLevel.Medium => AppLocalizer.T("中风险", "Medium risk"),
            ReferenceToolRiskLevel.Low => AppLocalizer.T("低风险", "Low risk"),
            _ => AppLocalizer.T("安全", "Safe")
        };
    }
}
