using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Windows.System;
using YMhut.Box.Core.Plugins;
using YMhut.Box.Core.Settings;
using YMhut.Box.Core.Tools;
using YMhut.Box.WinUI.Services;
using YMhut.Box.WinUI.ViewModels;

namespace YMhut.Box.WinUI.Views;

public sealed class ToolboxPage : Page
{
    private const int BatchSize = 48;

    private readonly ToolCatalog _catalog;
    private readonly Action<IToolModule> _openTool;
    private readonly Action<ToolboxNavigationState>? _stateChanged;
    private readonly ISettingsService _settingsService = AppServices.GetRequiredService<ISettingsService>();
    private readonly IUiPerformanceCoordinator _uiPerformanceCoordinator = AppServices.GetRequiredService<IUiPerformanceCoordinator>();
    private readonly IReadOnlyDictionary<string, IToolModule> _modulesById;
    private readonly Dictionary<ToolCategory, int> _categoryCounts = [];
    private readonly StackPanel _categoryPanel = new() { Spacing = 8, Margin = new Thickness(0, 0, 10, 0) };
    private readonly StackPanel _scopePanel = new() { Orientation = Orientation.Horizontal, Spacing = 8 };
    private readonly StackPanel _detailPanel = new() { Spacing = 12 };
    private readonly GridView _toolGridView = new()
    {
        SelectionMode = ListViewSelectionMode.None,
        IsItemClickEnabled = false,
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch,
        Padding = new Thickness(0, 0, 20, 20)
    };
    private readonly ProgressBar _loadingBar = new()
    {
        IsIndeterminate = true,
        Visibility = Visibility.Collapsed,
        Height = 3
    };
    private readonly AutoSuggestBox _toolSearchBox = new()
    {
        PlaceholderText = AppLocalizer.T("搜索工具名称、ID、分类或关键词", "Search tool name, id, category, or keyword"),
        QueryIcon = new SymbolIcon(Symbol.Find),
        MinWidth = 220,
        HorizontalAlignment = HorizontalAlignment.Stretch
    };
    private readonly TextBlock _visibleCountText = ModernUi.Text(AppLocalizer.ToolCount(0), 14, FontWeights.SemiBold, ModernUi.TextSecondary);
    private readonly TextBlock _scopeText = ModernUi.Text(AppLocalizer.T("全部工具", "All tools"), 14, FontWeights.SemiBold, ModernUi.Accent);
    private readonly DispatcherTimer _searchDebounce = new() { Interval = TimeSpan.FromMilliseconds(180) };
    private readonly DispatcherTimer _resizeLightModeDebounce = new() { Interval = TimeSpan.FromMilliseconds(240) };

    private string _query;
    private bool _syncingSearchBox;
    private int _loadGeneration;
    private ToolCategory _selectedCategory = ToolCategory.All;
    private string _selectedScope = "all";
    private string? _selectedDetailToolId;
    private double _toolCardWidth = 310;
    private ToolboxGridLayout _currentGridLayout = ToolboxLayoutCalculator.Calculate(0);
    private ToolboxGridLayout? _pendingGridLayout;
    private string _lastRenderedToolSignature = string.Empty;
    private string _lastRenderedLayoutSignature = string.Empty;
    private bool _performanceLightMode;
    private IDisposable? _resizeLightModeScope;

    public ToolboxPage(
        ToolCatalog catalog,
        Action<IToolModule> openTool,
        string query = "",
        ToolboxNavigationState? state = null,
        Action<ToolboxNavigationState>? stateChanged = null)
    {
        _catalog = catalog.Modules.Count == 0 ? new ToolCatalog() : catalog;
        _openTool = openTool;
        _stateChanged = stateChanged;
        _selectedCategory = state?.SelectedCategory ?? ToolCategory.All;
        _query = !string.IsNullOrWhiteSpace(query) ? query : state?.SearchQuery ?? string.Empty;
        _selectedScope = NormalizeScope(_settingsService.Current.ToolboxDefaultScope);
        _modulesById = _catalog.Modules.ToDictionary(module => module.Id, StringComparer.OrdinalIgnoreCase);
        Background = ModernUi.AppBackground;

        ConfigureCollections();
        ConfigureSearch();
        _performanceLightMode = _uiPerformanceCoordinator.IsLightMode;
        _uiPerformanceCoordinator.LightModeChanged += UiPerformanceCoordinator_LightModeChanged;
        _resizeLightModeDebounce.Tick += (_, _) =>
        {
            _resizeLightModeDebounce.Stop();
            _resizeLightModeScope?.Dispose();
            _resizeLightModeScope = null;
            if (_pendingGridLayout is { } pending && ShouldReflowForLayout(pending))
            {
                _pendingGridLayout = null;
                ApplyGridLayout(pending);
                RefreshTools(force: true);
            }
            else
            {
                _pendingGridLayout = null;
            }
        };

        Content = BuildContent();
        RefreshCategories();
        RefreshScopes();
        Loaded += (_, _) =>
        {
            ApplySearch(_query);
        };
        _toolGridView.SizeChanged += (_, e) =>
        {
            BeginTransientResizeLightMode();
            var next = ToolboxLayoutCalculator.Calculate(e.NewSize.Width);
            if (ShouldReflowForLayout(next))
            {
                _pendingGridLayout = next;
            }
        };
        Unloaded += (_, _) =>
        {
            _uiPerformanceCoordinator.LightModeChanged -= UiPerformanceCoordinator_LightModeChanged;
            _resizeLightModeScope?.Dispose();
            _resizeLightModeScope = null;
        };
    }

    public void ApplySearch(string query)
    {
        _query = query;
        if (!string.Equals(_toolSearchBox.Text, query, StringComparison.Ordinal))
        {
            _syncingSearchBox = true;
            _toolSearchBox.Text = query;
            _syncingSearchBox = false;
        }

        RefreshTools();
        NotifyStateChanged();
    }

    public ToolboxNavigationState CaptureState(string lastOpenedToolId = "")
    {
        return new ToolboxNavigationState(_selectedCategory, _query, 0, lastOpenedToolId);
    }

    private void ConfigureCollections()
    {
        _categoryCounts[ToolCategory.All] = _catalog.Modules.Count;
        foreach (var group in _catalog.Modules.GroupBy(module => module.Metadata.Category))
        {
            _categoryCounts[group.Key] = group.Count();
        }
    }

    private void ConfigureSearch()
    {
        AutomationProperties.SetName(_toolSearchBox, AppLocalizer.T("搜索工具", "Search tools"));
        _searchDebounce.Tick += (_, _) =>
        {
            _searchDebounce.Stop();
            _query = _toolSearchBox.Text;
            RefreshTools();
        };

        _toolSearchBox.TextChanged += (_, args) =>
        {
            if (_syncingSearchBox || args.Reason == AutoSuggestionBoxTextChangeReason.ProgrammaticChange)
            {
                return;
            }

            _searchDebounce.Stop();
            _searchDebounce.Start();
        };
        _toolSearchBox.QuerySubmitted += (_, _) =>
        {
            _searchDebounce.Stop();
            _query = _toolSearchBox.Text;
            RefreshTools();
        };
    }

    private void UiPerformanceCoordinator_LightModeChanged(object? sender, UiPerformanceModeChangedEventArgs args)
    {
        if (DispatcherQueue.HasThreadAccess)
        {
            _performanceLightMode = args.IsLightMode;
            return;
        }

        DispatcherQueue.TryEnqueue(() => _performanceLightMode = args.IsLightMode);
    }

    private void BeginTransientResizeLightMode()
    {
        _resizeLightModeScope ??= _uiPerformanceCoordinator.EnterLightMode("toolbox-resize");
        _resizeLightModeDebounce.Stop();
        _resizeLightModeDebounce.Start();
    }

    private bool ShouldReflowForLayout(ToolboxGridLayout next)
    {
        if (_performanceLightMode &&
            next.Columns == _currentGridLayout.Columns &&
            next.ShowCategoryRail == _currentGridLayout.ShowCategoryRail &&
            next.IsCompact == _currentGridLayout.IsCompact)
        {
            return false;
        }

        return next.Columns != _currentGridLayout.Columns ||
            next.ShowCategoryRail != _currentGridLayout.ShowCategoryRail ||
            next.IsCompact != _currentGridLayout.IsCompact ||
            Math.Abs(next.CardWidth - _toolCardWidth) >= 32;
    }

    private void ApplyGridLayout(ToolboxGridLayout layout)
    {
        _currentGridLayout = layout;
        _toolCardWidth = layout.CardWidth;
    }

    private string CurrentLayoutSignature()
    {
        var compact = _currentGridLayout.IsCompact ||
            _settingsService.Current.ToolboxCompactCards ||
            string.Equals(_settingsService.Current.ToolDisplayMode, "list", StringComparison.OrdinalIgnoreCase);
        return $"{_currentGridLayout.Columns}:{Math.Round(_toolCardWidth)}:{compact}:{_currentGridLayout.ShowCategoryRail}";
    }

    private UIElement BuildContent()
    {
        return BuildNativeContent();
    }

    private UIElement BuildNativeContent()
    {
        var root = new Grid
        {
            Padding = new Thickness(28, 18, 28, 24),
            RowSpacing = 16,
            Transitions = new TransitionCollection
            {
                new EntranceThemeTransition { FromVerticalOffset = 12 }
            }
        };
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        root.RowDefinitions.Add(new RowDefinition());
        root.SizeChanged += (_, e) =>
        {
            BeginTransientResizeLightMode();
            var phone = e.NewSize.Width < 520;
            root.Padding = phone ? new Thickness(12, 12, 12, 16) : new Thickness(28, 18, 28, 24);
            _toolGridView.Padding = phone ? new Thickness(0, 0, 4, 16) : new Thickness(0, 0, 20, 20);
        };

        root.Children.Add(BuildHeader());

        var scopeBar = BuildScopeBar();
        Grid.SetRow(scopeBar, 1);
        root.Children.Add(scopeBar);

        var body = new Grid { ColumnSpacing = 18 };
        body.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(252) });
        body.ColumnDefinitions.Add(new ColumnDefinition());
        Grid.SetRow(body, 2);
        root.Children.Add(body);

        var categories = BuildCategoryPane();
        body.Children.Add(categories);

        var gridHost = new Grid();
        gridHost.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        gridHost.RowDefinitions.Add(new RowDefinition());
        gridHost.Children.Add(_loadingBar);
        Grid.SetRow(_toolGridView, 1);
        gridHost.Children.Add(_toolGridView);

        var toolsHost = new Border
        {
            Padding = new Thickness(6),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.SurfaceAlt,
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Child = gridHost
        };
        Grid.SetColumn(toolsHost, 1);
        body.Children.Add(toolsHost);

        body.SizeChanged += (_, e) =>
        {
            BeginTransientResizeLightMode();
            var layout = ToolboxLayoutCalculator.Calculate(e.NewSize.Width);
            var narrow = !layout.ShowCategoryRail;
            body.ColumnSpacing = narrow ? 0 : 18;
            body.ColumnDefinitions[0].Width = narrow ? new GridLength(0) : new GridLength(252);
            categories.Visibility = narrow ? Visibility.Collapsed : Visibility.Visible;
        };

        return root;
    }

    private FrameworkElement BuildHeader()
    {
        var title = new StackPanel
        {
            Spacing = 4,
            Children =
            {
                ModernUi.Text(AppLocalizer.T("工具箱", "Toolbox"), 26, FontWeights.SemiBold),
                ModernUi.Text(
                    AppLocalizer.T(
                        "按分类查找、搜索并打开工具。",
                        "Find, search, and open tools by category."),
                    14,
                    foreground: ModernUi.TextSecondary,
                    maxLines: 1)
            }
        };

        var right = new StackPanel
        {
            Spacing = 8,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            Children =
            {
                _toolSearchBox,
                new StackPanel
                {
                    Orientation = Orientation.Horizontal,
                    Spacing = 10,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    Children = { _scopeText, _visibleCountText }
                }
            }
        };

        var grid = new Grid { ColumnSpacing = 20, RowSpacing = 12 };
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.72, GridUnitType.Star) });
        grid.Children.Add(title);
        Grid.SetColumn(right, 1);
        grid.Children.Add(right);
        grid.SizeChanged += (_, e) =>
        {
            var narrow = e.NewSize.Width < 940;
            grid.ColumnDefinitions.Clear();
            grid.RowDefinitions.Clear();
            grid.ColumnDefinitions.Add(new ColumnDefinition());
            if (narrow)
            {
                grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
                grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
                Grid.SetColumn(right, 0);
                Grid.SetRow(right, 1);
            }
            else
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.72, GridUnitType.Star) });
                Grid.SetColumn(right, 1);
                Grid.SetRow(right, 0);
            }
        };
        return grid;
    }

    private FrameworkElement BuildScopeBar()
    {
        return new ScrollViewer
        {
            HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
            HorizontalScrollMode = ScrollMode.Enabled,
            VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
            VerticalScrollMode = ScrollMode.Disabled,
            Content = _scopePanel
        };
    }

    private Border BuildCategoryPane()
    {
        var header = new StackPanel
        {
            Spacing = 4,
            Children =
            {
                ModernUi.Text(AppLocalizer.T("分类", "Categories"), 20, FontWeights.SemiBold),
                ModernUi.Text(AppLocalizer.T("选择一个分类过滤工具列表。", "Choose a group to filter the tool list."), 13, foreground: ModernUi.TextSecondary, maxLines: 2)
            }
        };

        var scrollViewer = new ScrollViewer
        {
            Content = _categoryPanel,
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
            Padding = new Thickness(0, 0, 8, 0)
        };

        var grid = new Grid { RowSpacing = 14 };
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition());
        grid.Children.Add(header);
        Grid.SetRow(scrollViewer, 1);
        grid.Children.Add(scrollViewer);
        return ModernUi.Card(grid, new Thickness(14), radius: 8);
    }

    private Border BuildDetailPane()
    {
        var header = new StackPanel
        {
            Spacing = 3,
            Children =
            {
                ModernUi.Text(AppLocalizer.T("详情预览", "Details"), 18, FontWeights.SemiBold),
                ModernUi.Text(AppLocalizer.T("选中工具后在这里查看来源、风险和操作。", "Select a tool to inspect source, risk, and actions."), 12.5, foreground: ModernUi.TextSecondary, maxLines: 2)
            }
        };

        var scrollViewer = new ScrollViewer
        {
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
            Content = _detailPanel,
            Padding = new Thickness(0, 0, 8, 0)
        };

        var grid = new Grid { RowSpacing = 14 };
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition());
        grid.Children.Add(header);
        Grid.SetRow(scrollViewer, 1);
        grid.Children.Add(scrollViewer);

        UpdateDetail(null);
        return ModernUi.Card(grid, new Thickness(16), radius: 8);
    }

    private void UpdateDetail(IToolModule? module)
    {
        _detailPanel.Children.Clear();
        _selectedDetailToolId = module?.Id;
        if (module is null)
        {
            _detailPanel.Children.Add(BuildDetailEmptyState());
            return;
        }

        var viewModel = new ToolCardViewModel(module);
        var favorite = IsFavorite(module.Id);
        var recent = IsRecent(module.Id);

        _detailPanel.Children.Add(BuildDetailHero(module, viewModel, favorite, recent));
        _detailPanel.Children.Add(ModernUi.Text(viewModel.Description, 13, foreground: ModernUi.TextSecondary, maxLines: 6));
        if (viewModel.Spec is not null)
        {
            _detailPanel.Children.Add(BuildDetailExperienceCard(viewModel.Spec));
        }
        _detailPanel.Children.Add(BuildDetailActions(module, favorite));
        _detailPanel.Children.Add(BuildDetailSectionTitle(AppLocalizer.T("工具信息", "Tool information")));
        foreach (var row in DetailRows(module, viewModel))
        {
            _detailPanel.Children.Add(BuildDetailRow(row.Label, row.Value));
        }
    }

    private UIElement BuildDetailEmptyState()
    {
        return ModernUi.Card(new StackPanel
        {
            Spacing = 8,
            Children =
            {
                ModernUi.IconTile("\uE946", 44, ModernUi.SurfaceAlt, ModernUi.TextSecondary, 19),
                ModernUi.Text(AppLocalizer.T("没有可预览的工具", "No tool selected"), 15, FontWeights.SemiBold),
                ModernUi.Text(AppLocalizer.T("调整搜索、分类或范围后，工具详情会显示在这里。", "Adjust search, category, or scope to show tool details here."), 12.5, foreground: ModernUi.TextSecondary)
            }
        }, new Thickness(14), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private UIElement BuildDetailHero(IToolModule module, ToolCardViewModel viewModel, bool favorite, bool recent)
    {
        var title = new StackPanel
        {
            Spacing = 4,
            Children =
            {
                ModernUi.Text(viewModel.Name, 20, FontWeights.SemiBold, maxLines: 2),
                ModernUi.Text($"{viewModel.CategoryLabel} / {SourceLabel(module)}", 12.5, foreground: ModernUi.TextSecondary, maxLines: 1)
            }
        };

        var row = new Grid { ColumnSpacing = 12 };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.Children.Add(ModernUi.IconTile(viewModel.IconGlyph, 52, ModernUi.AccentSoft, ModernUi.Accent, 23));
        Grid.SetColumn(title, 1);
        row.Children.Add(title);

        var badges = ModernUi.BadgeRow(
            new UIElement[]
            {
                ModernUi.Badge(favorite ? AppLocalizer.T("已收藏", "Favorite") : viewModel.SourceLabel, favorite ? ModernUi.Bronze : ModernUi.TextSecondary, ModernUi.SurfaceAlt),
                ModernUi.Badge(recent ? AppLocalizer.T("最近使用", "Recent") : viewModel.ResultLabel, recent ? ModernUi.Accent : ModernUi.TextSecondary, recent ? ModernUi.AccentSoft : ModernUi.SurfaceAlt),
                ModernUi.Badge(viewModel.SafetyLabel, IsRisky(module) ? ModernUi.Danger : ModernUi.TextSecondary, ModernUi.SurfaceAlt)
            },
            itemWidth: 106,
            maxHeight: 58);

        return new StackPanel { Spacing = 10, Children = { row, badges } };
    }

    private static UIElement BuildDetailExperienceCard(ToolPageSpec spec)
    {
        var grid = new VariableSizedWrapGrid
        {
            Orientation = Orientation.Horizontal,
            ItemWidth = 146,
            ItemHeight = 64
        };

        grid.Children.Add(BuildDetailMetric(
            AppLocalizer.T("体验", "Experience"),
            ExperienceText(spec.PageExperience),
            "\uE7C3"));
        grid.Children.Add(BuildDetailMetric(
            AppLocalizer.T("输入", "Input"),
            InputText(spec.PrimaryInput),
            "\uE8D2"));
        grid.Children.Add(BuildDetailMetric(
            AppLocalizer.T("结果", "Result"),
            ResultPriorityText(spec.ResultPriority),
            "\uE9D9"));

        return ModernUi.Card(grid, new Thickness(10), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static UIElement BuildDetailMetric(string label, string value, string glyph)
    {
        var row = new Grid { ColumnSpacing = 8, Padding = new Thickness(6, 4, 6, 4) };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.Children.Add(ModernUi.IconTile(glyph, 30, ModernUi.Surface, ModernUi.Accent, 13));
        var text = new StackPanel
        {
            Spacing = 1,
            Children =
            {
                ModernUi.Text(label, 11.5, FontWeights.SemiBold, ModernUi.TextSecondary, maxLines: 1),
                ModernUi.Text(value, 13, FontWeights.SemiBold, maxLines: 1)
            }
        };
        Grid.SetColumn(text, 1);
        row.Children.Add(text);
        return row;
    }

    private UIElement BuildDetailActions(IToolModule module, bool favorite)
    {
        var open = StretchButton(ModernUi.PillButton(AppLocalizer.T("打开工具", "Open tool"), "\uE8A7", () => OpenRegisteredTool(module), primary: true));
        var favoriteButton = StretchButton(ModernUi.PillButton(
            favorite ? AppLocalizer.T("取消收藏", "Remove favorite") : AppLocalizer.T("收藏", "Add favorite"),
            favorite ? "\uE735" : "\uE734",
            () => _ = ToggleFavoriteAsync(module.Id, favorite)));

        var actions = new StackPanel
        {
            Spacing = 8,
            Children = { open, favoriteButton }
        };

        if (module is ExternalToolModule external)
        {
            actions.Children.Add(StretchButton(ModernUi.PillButton(
                AppLocalizer.T("打开目录", "Open folder"),
                "\uE838",
                async () => await Launcher.LaunchFolderPathAsync(external.Tool.ToolDirectory))));
            actions.Children.Add(ModernUi.Text(
                AppLocalizer.T("启动和管理员运行会在工具页内继续进行风险确认。", "Launch and administrator run continue with risk confirmation on the tool page."),
                12,
                foreground: ModernUi.TextSecondary,
                maxLines: 3));
        }
        else if (IsRisky(module))
        {
            actions.Children.Add(ModernUi.Text(
                AppLocalizer.T("执行前会弹出二次确认，取消和执行结果都会写入日志。", "A second confirmation appears before execution; cancellation and results are logged."),
                12,
                foreground: ModernUi.TextSecondary,
                maxLines: 3));
        }

        return actions;
    }

    private static Button StretchButton(Button button)
    {
        button.HorizontalAlignment = HorizontalAlignment.Stretch;
        button.HorizontalContentAlignment = HorizontalAlignment.Center;
        return button;
    }

    private static TextBlock BuildDetailSectionTitle(string text)
    {
        return ModernUi.Text(text, 13, FontWeights.SemiBold, ModernUi.Accent, maxLines: 1);
    }

    private static UIElement BuildDetailRow(string label, string value)
    {
        var grid = new Grid { RowSpacing = 2 };
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.Children.Add(ModernUi.Text(label, 11.5, FontWeights.SemiBold, ModernUi.TextSecondary, maxLines: 1));
        var valueText = new TextBlock
        {
            Text = string.IsNullOrWhiteSpace(value) ? AppLocalizer.T("未提供", "Not provided") : value,
            FontSize = 12.5,
            Foreground = ModernUi.TextPrimary,
            TextWrapping = TextWrapping.Wrap,
            IsTextSelectionEnabled = true
        };
        Grid.SetRow(valueText, 1);
        grid.Children.Add(valueText);
        return ModernUi.Card(grid, new Thickness(10), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static IEnumerable<(string Label, string Value)> DetailRows(IToolModule module, ToolCardViewModel viewModel)
    {
        yield return (AppLocalizer.T("工具 ID", "Tool ID"), module.Id);
        yield return (AppLocalizer.T("分类", "Category"), viewModel.CategoryLabel);
        yield return (AppLocalizer.T("来源", "Source"), SourceLabel(module));
        yield return (AppLocalizer.T("能力", "Capability"), viewModel.CapabilityLabel);
        if (viewModel.Spec is not null)
        {
            yield return (AppLocalizer.T("体验", "Experience"), ExperienceText(viewModel.Spec.PageExperience));
            yield return (AppLocalizer.T("输入", "Input"), InputText(viewModel.Spec.PrimaryInput));
            yield return (AppLocalizer.T("结果优先级", "Result priority"), ResultPriorityText(viewModel.Spec.ResultPriority));
        }

        switch (module)
        {
            case ExternalToolModule external:
                yield return (AppLocalizer.T("启动文件", "Launch file"), external.Tool.RelativePath);
                yield return (AppLocalizer.T("工具目录", "Tool directory"), external.Tool.ToolDirectory);
                yield return (AppLocalizer.T("架构", "Architecture"), external.Tool.PrimaryArchitecture ?? AppLocalizer.T("默认架构", "Default"));
                yield return (AppLocalizer.T("发布者", "Publisher"), external.Tool.Publisher ?? AppLocalizer.T("未知", "Unknown"));
                yield return (AppLocalizer.T("版本", "Version"), external.Tool.Version ?? AppLocalizer.T("未知", "Unknown"));
                yield return (AppLocalizer.T("风险等级", "Risk level"), RiskLabel(external.Tool.RiskLevel));
                yield return (AppLocalizer.T("管理员权限", "Administrator"), external.Tool.RequiresAdministrator ? AppLocalizer.T("需要", "Required") : AppLocalizer.T("不需要", "Not required"));
                yield return (AppLocalizer.T("标签", "Tags"), string.Join(", ", external.Tool.Tags));
                break;
            case BuiltinReferenceToolModule builtin:
                yield return (AppLocalizer.T("内置类型", "Built-in kind"), builtin.Definition.Kind.ToString());
                yield return (AppLocalizer.T("风险等级", "Risk level"), RiskLabel(builtin.Definition.RiskLevel));
                yield return (AppLocalizer.T("主操作", "Primary action"), builtin.Definition.PrimaryAction);
                yield return (AppLocalizer.T("关键词", "Keywords"), string.Join(", ", builtin.Definition.Keywords));
                break;
            case PluginToolModule plugin:
                yield return (AppLocalizer.T("插件", "Plugin"), $"{plugin.Plugin.Manifest.Name} v{plugin.Plugin.Manifest.Version}");
                yield return (AppLocalizer.T("作者", "Author"), plugin.Plugin.Manifest.Author);
                yield return (AppLocalizer.T("挂载项", "Surface"), plugin.Surface.Id);
                yield return (AppLocalizer.T("入口", "Entry"), plugin.Surface.EffectiveEntry(plugin.Plugin.Manifest.Entry));
                yield return (AppLocalizer.T("插件目录", "Plugin directory"), plugin.Plugin.RootPath);
                yield return (AppLocalizer.T("权限", "Permissions"), string.Join(", ", plugin.Plugin.Manifest.Permissions));
                break;
            default:
                yield return (AppLocalizer.T("布局", "Layout"), viewModel.LayoutLabel);
                yield return (AppLocalizer.T("结果", "Result"), viewModel.ResultLabel);
                yield return (AppLocalizer.T("关键词", "Keywords"), string.Join(", ", module.Metadata.Keywords));
                break;
        }
    }

    private void RefreshCategories()
    {
        _categoryPanel.Children.Clear();
        AddCategory(ToolCategory.All);
        foreach (var category in _catalog.Modules
            .Select(module => module.Metadata.Category)
            .Distinct()
            .OrderBy(CategoryOrder))
        {
            AddCategory(category);
        }
    }

    private void AddCategory(ToolCategory category)
    {
        var count = _categoryCounts.TryGetValue(category, out var value) ? value : 0;
        var selected = category == _selectedCategory;
        var button = new Button
        {
            HorizontalAlignment = HorizontalAlignment.Stretch,
            HorizontalContentAlignment = HorizontalAlignment.Stretch,
            Padding = new Thickness(8),
            CornerRadius = new CornerRadius(8),
            Background = selected ? ModernUi.AccentSoft : ModernUi.Surface,
            BorderBrush = selected ? ModernUi.Accent : ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Content = BuildCategoryContent(
                category == ToolCategory.All ? AppLocalizer.T("全部工具", "All tools") : ToolText.CategoryLabel(category),
                ToolText.CategoryHint(category),
                count,
                ToolText.CategoryGlyph(category))
        };

        button.Click += (_, _) =>
        {
            _selectedCategory = category;
            RefreshCategories();
            RefreshTools();
            NotifyStateChanged();
        };
        ToolTipService.SetToolTip(button, ToolText.CategoryLabel(category));
        AutomationProperties.SetName(button, ToolText.CategoryLabel(category));
        _categoryPanel.Children.Add(button);
    }

    private static UIElement BuildCategoryContent(string label, string hint, int count, string glyph)
    {
        var grid = new Grid { ColumnSpacing = 10, MinHeight = 38 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

        grid.Children.Add(ModernUi.IconTile(glyph, 32, ModernUi.SurfaceAlt, ModernUi.Accent, 14));

        var text = new StackPanel
        {
            VerticalAlignment = VerticalAlignment.Center,
            Spacing = 1,
            Children =
            {
                ModernUi.Text(label, 14, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text(hint, 12, foreground: ModernUi.TextSecondary, maxLines: 1)
            }
        };
        Grid.SetColumn(text, 1);
        grid.Children.Add(text);

        var countText = ModernUi.Text(count.ToString(), 12, FontWeights.SemiBold, ModernUi.TextSecondary, maxLines: 1);
        countText.VerticalAlignment = VerticalAlignment.Center;
        Grid.SetColumn(countText, 2);
        grid.Children.Add(countText);
        return grid;
    }

    private void RefreshScopes()
    {
        _scopePanel.Children.Clear();
        foreach (var scope in new[] { "all", "favorites", "recent", "external", "builtin", "plugin", "risk" })
        {
            AddScope(scope, ScopeCount(scope));
        }
    }

    private void AddScope(string scope, int count)
    {
        var selected = string.Equals(_selectedScope, scope, StringComparison.OrdinalIgnoreCase);
        var button = new Button
        {
            Padding = new Thickness(12, 6, 12, 7),
            CornerRadius = new CornerRadius(6),
            Background = selected ? ModernUi.AccentSoft : ModernUi.Surface,
            BorderBrush = selected ? ModernUi.Accent : ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Content = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                Spacing = 8,
                Children =
                {
                    new FontIcon { Glyph = ScopeGlyph(scope), FontSize = 14, Foreground = selected ? ModernUi.Accent : ModernUi.TextSecondary },
                    ModernUi.Text($"{ScopeLabel(scope)} {count}", 13, FontWeights.SemiBold, selected ? ModernUi.Accent : ModernUi.TextSecondary, maxLines: 1)
                }
            }
        };
        button.Click += async (_, _) =>
        {
            _selectedScope = scope;
            await _settingsService.UpdateAsync(settings => settings.ToolboxDefaultScope = scope);
            RefreshScopes();
            RefreshTools();
        };
        ToolTipService.SetToolTip(button, $"{ScopeLabel(scope)} {count}");
        AutomationProperties.SetName(button, $"{ScopeLabel(scope)} {count}");
        _scopePanel.Children.Add(button);
    }

    private void RefreshTools(bool force = false)
    {
        try
        {
            var modules = _catalog.Modules
                .Where(module => _selectedCategory == ToolCategory.All || module.Metadata.Category == _selectedCategory)
                .Where(MatchesScope)
                .Where(module => ToolText.Matches(module, _query))
                .OrderBy(SortGroup)
                .ThenBy(module => ToolText.Name(module), StringComparer.CurrentCulture)
                .ToArray();

            var layout = ToolboxLayoutCalculator.Calculate(_toolGridView.ActualWidth);
            if (ShouldReflowForLayout(layout))
            {
                ApplyGridLayout(layout);
                force = true;
            }

            _visibleCountText.Text = AppLocalizer.ToolCount(modules.Length);
            _scopeText.Text = _selectedCategory == ToolCategory.All ? ScopeLabel(_selectedScope) : ToolText.CategoryLabel(_selectedCategory);
            var toolSignature = string.Join('\u001F', modules.Select(module => module.Id));
            var layoutSignature = CurrentLayoutSignature();
            if (!force &&
                string.Equals(toolSignature, _lastRenderedToolSignature, StringComparison.Ordinal) &&
                string.Equals(layoutSignature, _lastRenderedLayoutSignature, StringComparison.Ordinal))
            {
                return;
            }

            _lastRenderedToolSignature = toolSignature;
            _lastRenderedLayoutSignature = layoutSignature;
            _toolGridView.Items.Clear();
            _loadingBar.Visibility = modules.Length > 0 ? Visibility.Visible : Visibility.Collapsed;
            var generation = ++_loadGeneration;
            LoadToolBatch(modules, generation, startIndex: 0);
        }
        catch (Exception exception)
        {
            CrashLog.Write(exception);
            _toolGridView.Items.Clear();
            _toolGridView.Items.Add(BuildErrorCard(exception));
            _loadingBar.Visibility = Visibility.Collapsed;
            _lastRenderedToolSignature = string.Empty;
            _lastRenderedLayoutSignature = string.Empty;
        }
    }

    private void LoadToolBatch(IReadOnlyList<IToolModule> modules, int generation, int startIndex)
    {
        if (generation != _loadGeneration)
        {
            return;
        }

        var endIndex = Math.Min(startIndex + BatchSize, modules.Count);
        for (var index = startIndex; index < endIndex; index++)
        {
            _toolGridView.Items.Add(BuildToolCard(modules[index]));
        }

        if (endIndex >= modules.Count)
        {
            _loadingBar.Visibility = Visibility.Collapsed;
            return;
        }

        if (!DispatcherQueue.TryEnqueue(() => LoadToolBatch(modules, generation, endIndex)))
        {
            LoadToolBatch(modules, generation, endIndex);
        }
    }

    private FrameworkElement BuildToolCard(IToolModule module)
    {
        var viewModel = new ToolCardViewModel(module);
        var favorite = IsFavorite(module.Id);
        var recent = IsRecent(module.Id);
        var compact = _currentGridLayout.IsCompact ||
            _settingsService.Current.ToolboxCompactCards ||
            string.Equals(_settingsService.Current.ToolDisplayMode, "list", StringComparison.OrdinalIgnoreCase);
        var buttonWidth = Math.Max(ToolboxLayoutCalculator.MinCardWidth, _toolCardWidth);
        var contentWidth = Math.Max(232, buttonWidth - 26);
        var grid = new Grid
        {
            Width = contentWidth,
            Height = compact ? 142 : 202,
            Padding = new Thickness(14),
            RowSpacing = compact ? 8 : 10
        };
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition());
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

        var header = new Grid { ColumnSpacing = 10 };
        header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        header.ColumnDefinitions.Add(new ColumnDefinition());
        header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        header.Children.Add(ModernUi.IconTile(viewModel.IconGlyph, compact ? 38 : 48, ModernUi.SurfaceAlt, ModernUi.Accent, compact ? 17 : 22));

        var title = new StackPanel
        {
            VerticalAlignment = VerticalAlignment.Center,
            Children =
            {
                ModernUi.Text(viewModel.Name, compact ? 15 : 16, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text($"{viewModel.CategoryLabel} / {viewModel.LayoutLabel}", 12, foreground: ModernUi.TextSecondary, maxLines: 1)
            }
        };
        Grid.SetColumn(title, 1);
        header.Children.Add(title);

        var favoriteButton = ModernUi.IconButton(
            favorite ? "\uE735" : "\uE734",
            favorite ? AppLocalizer.T("取消收藏", "Remove favorite") : AppLocalizer.T("收藏", "Add favorite"),
            async () => await ToggleFavoriteAsync(module.Id, favorite));
        favoriteButton.Width = 34;
        favoriteButton.Height = 32;
        favoriteButton.Background = favorite ? ModernUi.AccentSoft : ModernUi.SurfaceAlt;
        favoriteButton.BorderBrush = favorite ? ModernUi.Bronze : ModernUi.Stroke;
        favoriteButton.ContextFlyout = BuildToolFlyout(module, favorite);
        favoriteButton.VerticalAlignment = VerticalAlignment.Top;
        AutomationProperties.SetName(favoriteButton, favorite ? AppLocalizer.T("取消收藏", "Remove favorite") : AppLocalizer.T("收藏", "Add favorite"));
        grid.Children.Add(header);

        var description = ModernUi.Text(viewModel.Description, 12.5, foreground: ModernUi.TextSecondary, maxLines: compact ? 1 : 2);
        Grid.SetRow(description, 1);
        grid.Children.Add(description);

        var badgeWidth = Math.Clamp(Math.Floor((contentWidth - 12) / 3), 86, 118);
        var badges = ModernUi.BadgeRow(
            new UIElement[]
            {
                favorite ? ModernUi.Badge(AppLocalizer.T("已收藏", "Favorite"), ModernUi.Bronze, ModernUi.SurfaceAlt, badgeWidth - 14) : ModernUi.Badge(viewModel.SourceLabel, maxWidth: badgeWidth - 14),
                recent ? ModernUi.Badge(AppLocalizer.T("最近使用", "Recent"), ModernUi.Accent, ModernUi.AccentSoft, badgeWidth - 14) : ModernUi.Badge(viewModel.ResultLabel, maxWidth: badgeWidth - 14),
                ModernUi.Badge(viewModel.Spec is not null && !compact ? ExperienceText(viewModel.Spec.PageExperience) : viewModel.SafetyLabel, maxWidth: badgeWidth - 14)
            },
            itemWidth: badgeWidth,
            maxHeight: compact ? 30 : 58);
        Grid.SetRow(badges, 2);
        grid.Children.Add(badges);

        var button = new Button
        {
            Width = buttonWidth,
            Height = compact ? 170 : 236,
            Padding = new Thickness(0),
            HorizontalContentAlignment = HorizontalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Stretch,
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Brush("#00FFFFFF"),
            BorderBrush = ModernUi.Brush("#00FFFFFF"),
            BorderThickness = new Thickness(0),
            ContextFlyout = BuildToolFlyout(module, favorite)
        };
        grid.IsHitTestVisible = false;
        ToolTipService.SetToolTip(button, $"{viewModel.Name}\n{viewModel.Description}");
        AutomationProperties.SetName(button, viewModel.Name);
        AutomationProperties.SetHelpText(button, viewModel.Description);
        button.Click += (_, _) => OpenRegisteredTool(module);
        Canvas.SetZIndex(button, 0);
        Canvas.SetZIndex(grid, 1);
        favoriteButton.HorizontalAlignment = HorizontalAlignment.Right;
        favoriteButton.VerticalAlignment = VerticalAlignment.Top;
        favoriteButton.Margin = new Thickness(0, 12, 12, 0);
        Canvas.SetZIndex(favoriteButton, 2);
        return new Border
        {
            Width = buttonWidth,
            Height = compact ? 170 : 236,
            Margin = new Thickness(7),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Surface,
            BorderBrush = favorite ? ModernUi.Bronze : IsRisky(module) ? ModernUi.Danger : ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Child = new Grid
            {
                Children = { button, grid, favoriteButton }
            },
            ContextFlyout = BuildToolFlyout(module, favorite)
        };
    }

    private MenuFlyout BuildToolFlyout(IToolModule module, bool favorite)
    {
        var menu = new MenuFlyout();
        var open = new MenuFlyoutItem { Text = AppLocalizer.T("打开工具", "Open tool"), Icon = new SymbolIcon(Symbol.OpenFile) };
        open.Click += (_, _) => OpenRegisteredTool(module);
        menu.Items.Add(open);

        var details = new MenuFlyoutItem
        {
            Text = AppLocalizer.T("查看详情", "View details"),
            Icon = new FontIcon { Glyph = "\uE946" }
        };
        details.Click += async (_, _) => await ShowToolDetailsDialogAsync(module);
        menu.Items.Add(details);

        var favoriteItem = new MenuFlyoutItem
        {
            Text = favorite ? AppLocalizer.T("取消收藏", "Remove favorite") : AppLocalizer.T("收藏", "Add favorite"),
            Icon = new FontIcon { Glyph = favorite ? "\uE735" : "\uE734" }
        };
        favoriteItem.Click += async (_, _) => await ToggleFavoriteAsync(module.Id, favorite);
        menu.Items.Add(favoriteItem);

        if (module is ExternalToolModule external)
        {
            var folder = new MenuFlyoutItem { Text = AppLocalizer.T("打开工具目录", "Open tool folder"), Icon = new SymbolIcon(Symbol.Folder) };
            folder.Click += async (_, _) => await Launcher.LaunchFolderPathAsync(external.Tool.ToolDirectory);
            menu.Items.Add(folder);
        }

        menu.Items.Add(new MenuFlyoutSeparator());
        menu.Items.Add(new MenuFlyoutItem
        {
            Text = $"{ToolText.CategoryLabel(module.Metadata.Category)} / {SourceLabel(module)}",
            IsEnabled = false
        });
        return menu;
    }

    private async Task ShowToolDetailsDialogAsync(IToolModule module)
    {
        if (XamlRoot is null)
        {
            return;
        }

        var viewModel = new ToolCardViewModel(module);
        var favorite = IsFavorite(module.Id);
        var recent = IsRecent(module.Id);
        var panel = new StackPanel
        {
            Spacing = 14,
            MaxWidth = 680,
            Children =
            {
                BuildDetailHero(module, viewModel, favorite, recent),
                ModernUi.Text(viewModel.Description, 13.5, foreground: ModernUi.TextSecondary, maxLines: 5)
            }
        };

        if (viewModel.Spec is not null)
        {
            panel.Children.Add(BuildDetailExperienceCard(viewModel.Spec));
        }

        panel.Children.Add(BuildDetailActions(module, favorite));
        panel.Children.Add(BuildDetailSectionTitle(AppLocalizer.T("工具信息", "Tool information")));
        foreach (var row in DetailRows(module, viewModel))
        {
            panel.Children.Add(BuildDetailRow(row.Label, row.Value));
        }

        var dialog = new ContentDialog
        {
            XamlRoot = XamlRoot,
            Title = viewModel.Name,
            Content = new ScrollViewer
            {
                MaxHeight = 620,
                VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
                Content = panel
            },
            CloseButtonText = AppLocalizer.T("关闭", "Close"),
            DefaultButton = ContentDialogButton.Close
        };

        await dialog.ShowAsync();
    }

    private void OpenRegisteredTool(IToolModule module)
    {
        if (_modulesById.TryGetValue(module.Id, out var registered))
        {
            _stateChanged?.Invoke(CaptureState(registered.Id));
            _openTool(registered);
        }
    }

    private async Task ToggleFavoriteAsync(string toolId, bool wasFavorite)
    {
        await _settingsService.UpdateAsync(settings =>
        {
            PinnedToolSettings.Toggle(settings.PinnedToolIds, toolId, wasFavorite);
        });
        RefreshScopes();
        RefreshTools(force: true);
        NotifyStateChanged();
    }

    private void NotifyStateChanged()
    {
        _stateChanged?.Invoke(CaptureState());
    }

    private bool MatchesScope(IToolModule module)
    {
        return _selectedScope switch
        {
            "favorites" => IsFavorite(module.Id),
            "recent" => IsRecent(module.Id),
            "external" => module is ExternalToolModule,
            "builtin" => module is BuiltinReferenceToolModule,
            "plugin" => module is PluginToolModule,
            "risk" => IsRisky(module),
            _ => true
        };
    }

    private int ScopeCount(string scope)
    {
        return _catalog.Modules.Count(module => scope switch
        {
            "favorites" => IsFavorite(module.Id),
            "recent" => IsRecent(module.Id),
            "external" => module is ExternalToolModule,
            "builtin" => module is BuiltinReferenceToolModule,
            "plugin" => module is PluginToolModule,
            "risk" => IsRisky(module),
            _ => true
        });
    }

    private int SortGroup(IToolModule module)
    {
        if (_settingsService.Current.ToolboxShowRecentFirst && IsRecent(module.Id))
        {
            return 0;
        }

        return IsFavorite(module.Id) ? 1 : 2;
    }

    private bool IsFavorite(string toolId)
    {
        return _settingsService.Current.PinnedToolIds.Any(id => string.Equals(id, toolId, StringComparison.OrdinalIgnoreCase));
    }

    private bool IsRecent(string toolId)
    {
        return _settingsService.Current.RecentToolIds.Any(id => string.Equals(id, toolId, StringComparison.OrdinalIgnoreCase));
    }

    private static bool IsRisky(IToolModule module)
    {
        return module switch
        {
            ExternalToolModule external => external.Tool.IsRisky,
            BuiltinReferenceToolModule builtin => builtin.Definition.IsRisky,
            _ => false
        };
    }

    private static double CalculateCardWidth(double availableWidth)
        => ToolboxLayoutCalculator.Calculate(availableWidth).CardWidth;

    private static UIElement BuildErrorCard(Exception exception)
    {
        var stack = new StackPanel
        {
            Width = 420,
            Padding = new Thickness(12),
            Spacing = 8,
            Children =
            {
                ModernUi.Text(AppLocalizer.T("工具箱渲染失败", "Toolbox failed to render"), 16, FontWeights.SemiBold, ModernUi.Danger),
                ModernUi.Text(exception.Message, 13, foreground: ModernUi.TextSecondary, maxLines: 4)
            }
        };

        return ModernUi.Card(stack, new Thickness(0), radius: 8);
    }

    private static string NormalizeScope(string scope)
    {
        return (scope ?? string.Empty).Trim().ToLowerInvariant() switch
        {
            "favorites" or "favorite" or "pinned" => "favorites",
            "recent" or "history" => "recent",
            "external" => "external",
            "builtin" or "reference" => "builtin",
            "plugin" or "plugins" => "plugin",
            "risk" or "risky" => "risk",
            _ => "all"
        };
    }

    private static string ScopeLabel(string scope)
    {
        return scope switch
        {
            "favorites" => AppLocalizer.T("收藏", "Favorites"),
            "recent" => AppLocalizer.T("最近", "Recent"),
            "external" => AppLocalizer.T("外部工具", "Tools"),
            "builtin" => AppLocalizer.T("内置", "Built-in"),
            "plugin" => AppLocalizer.T("插件", "Plugins"),
            "risk" => AppLocalizer.T("风险", "Risk"),
            _ => AppLocalizer.T("全部", "All")
        };
    }

    private static string ScopeGlyph(string scope)
    {
        return scope switch
        {
            "favorites" => "\uE735",
            "recent" => "\uE823",
            "external" => "\uE8B7",
            "builtin" => "\uE950",
            "plugin" => "\uECAA",
            "risk" => "\uE7BA",
            _ => "\uE90F"
        };
    }

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

    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")
        };
    }

    private static string ExperienceText(ToolPageExperienceKind experience)
    {
        return experience switch
        {
            ToolPageExperienceKind.LivePreview => AppLocalizer.T("实时预览", "Live preview"),
            ToolPageExperienceKind.OneShotTransform => AppLocalizer.T("单次处理", "One-shot"),
            ToolPageExperienceKind.FormCalculator => AppLocalizer.T("表单计算", "Calculator"),
            ToolPageExperienceKind.LookupBrowser => AppLocalizer.T("资料查询", "Lookup"),
            ToolPageExperienceKind.RemoteDashboard => AppLocalizer.T("数据看板", "Dashboard"),
            ToolPageExperienceKind.FileWorkflow => AppLocalizer.T("文件流程", "File workflow"),
            ToolPageExperienceKind.NativeWindow => AppLocalizer.T("原生窗口", "Native window"),
            ToolPageExperienceKind.SystemLauncher => AppLocalizer.T("系统入口", "System entry"),
            ToolPageExperienceKind.MediaViewer => AppLocalizer.T("媒体视图", "Media view"),
            _ => AppLocalizer.T("工具页", "Tool page")
        };
    }

    private static string InputText(ToolPrimaryInputKind input)
    {
        return input switch
        {
            ToolPrimaryInputKind.None => AppLocalizer.T("无需输入", "No input"),
            ToolPrimaryInputKind.Text => AppLocalizer.T("单行文本", "Text"),
            ToolPrimaryInputKind.MultilineText => AppLocalizer.T("多行文本", "Multiline text"),
            ToolPrimaryInputKind.Query => AppLocalizer.T("查询条件", "Query"),
            ToolPrimaryInputKind.Url => AppLocalizer.T("URL", "URL"),
            ToolPrimaryInputKind.Token => AppLocalizer.T("密钥/令牌", "Token"),
            ToolPrimaryInputKind.Color => AppLocalizer.T("颜色值", "Color"),
            ToolPrimaryInputKind.FixedOptions => AppLocalizer.T("固定选项", "Fixed options"),
            ToolPrimaryInputKind.FilePath => AppLocalizer.T("文件路径", "File path"),
            ToolPrimaryInputKind.DateRange => AppLocalizer.T("日期范围", "Date range"),
            ToolPrimaryInputKind.Number => AppLocalizer.T("数值", "Number"),
            ToolPrimaryInputKind.NumberPair => AppLocalizer.T("双数值", "Number pair"),
            ToolPrimaryInputKind.NumberTriple => AppLocalizer.T("三数值", "Number triple"),
            ToolPrimaryInputKind.NumberQuad => AppLocalizer.T("四数值", "Number quad"),
            _ => AppLocalizer.T("输入", "Input")
        };
    }

    private static string ResultPriorityText(ToolResultPriority priority)
    {
        return priority switch
        {
            ToolResultPriority.Value => AppLocalizer.T("值", "Value"),
            ToolResultPriority.List => AppLocalizer.T("列表", "List"),
            ToolResultPriority.Table => AppLocalizer.T("表格", "Table"),
            ToolResultPriority.Preview => AppLocalizer.T("预览", "Preview"),
            ToolResultPriority.Document => AppLocalizer.T("文档", "Document"),
            ToolResultPriority.Status => AppLocalizer.T("状态", "Status"),
            ToolResultPriority.Media => AppLocalizer.T("媒体", "Media"),
            _ => AppLocalizer.T("结果", "Result")
        };
    }

    private static int CategoryOrder(ToolCategory category)
    {
        return category switch
        {
            ToolCategory.Plugin => 1,
            ToolCategory.Dev => 2,
            ToolCategory.Network => 3,
            ToolCategory.Security => 4,
            ToolCategory.Data => 5,
            ToolCategory.Calculator => 6,
            ToolCategory.Text => 7,
            ToolCategory.Image => 8,
            ToolCategory.Design => 9,
            ToolCategory.Life => 10,
            ToolCategory.System => 11,
            _ => 0
        };
    }
}
