using System.Diagnostics;
using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Windows.ApplicationModel.DataTransfer;
using YMhut.Box.Core.Api;
using YMhut.Box.Core.Data;
using YMhut.Box.Core.Logging;
using YMhut.Box.Core.Net;
using YMhut.Box.Core.Startup;
using YMhut.Box.Core.System;
using YMhut.Box.Core.Tools;
using YMhut.Box.WinUI.Services;

namespace YMhut.Box.WinUI.Views;

public sealed class ServiceStatusPage : Page
{
    private static readonly Uri MediaConfigUri = new("https://update.ymhut.cn/media-types.json");
    private static string T(string zh, string en) => AppLocalizer.T(zh, en);

    private readonly IApiManager _apiManager = AppServices.GetRequiredService<IApiManager>();
    private readonly IReferenceDataService _referenceDataService = AppServices.GetRequiredService<IReferenceDataService>();
    private readonly ISystemMetricsService _metricsService = AppServices.GetRequiredService<ISystemMetricsService>();
    private readonly IAppInstallerUpdateService _updateService = AppServices.GetRequiredService<IAppInstallerUpdateService>();
    private readonly IHttpService _httpService = AppServices.GetRequiredService<IHttpService>();
    private readonly IToolWorkerService _workerService = AppServices.GetRequiredService<IToolWorkerService>();
    private readonly ILogService _logService = AppServices.GetRequiredService<ILogService>();
    private readonly IInstallIntegrityCheckService _integrityCheckService = AppServices.GetRequiredService<IInstallIntegrityCheckService>();
    private readonly ToolCatalog _catalog = AppServices.GetRequiredService<ToolCatalog>();
    private readonly Action<StartupCheckResultPayload>? _openStartupCheckResults;

    private readonly StackPanel _statusList = new() { Spacing = 10 };
    private readonly TextBlock _summaryText = ModernUi.Text(T("尚未运行健康检查。", "No health check has run yet."), 14, foreground: ModernUi.TextSecondary);
    private readonly TextBlock _overallText = ModernUi.Text(T("待检查", "Pending"), 18, FontWeights.SemiBold, ModernUi.Info);
    private readonly TextBlock _availableCountText = ModernUi.Text("0", 18, FontWeights.SemiBold, ModernUi.Accent);
    private readonly TextBlock _issueCountText = ModernUi.Text("0", 18, FontWeights.SemiBold, ModernUi.Danger);
    private readonly TextBlock _warningCountText = ModernUi.Text("0", 18, FontWeights.SemiBold, ModernUi.Bronze);
    private readonly TextBlock _startupSummaryText = ModernUi.Text(T("启动自检结果尚未加载。", "Startup check result has not been loaded yet."), 14, foreground: ModernUi.TextSecondary);
    private readonly TextBlock _startupOverallText = ModernUi.Text(T("待检查", "Pending"), 18, FontWeights.SemiBold, ModernUi.Info);
    private readonly TextBlock _startupIssueStateText = ModernUi.Text(T("未知", "Unknown"), 18, FontWeights.SemiBold, ModernUi.TextSecondary);
    private readonly TextBlock _startupTimeText = ModernUi.Text(T("上次检查：-", "Last check: -"), 12, foreground: ModernUi.TextSecondary, maxLines: 2);
    private readonly TextBlock _startupBasisText = ModernUi.Text("", 12, foreground: ModernUi.TextSecondary, maxLines: 2);
    private readonly ProgressBar _startupResultPreloadBar = new()
    {
        Minimum = 0,
        Maximum = 100,
        Height = 4,
        Visibility = Visibility.Collapsed
    };
    private readonly TextBlock _startupResultTipText = ModernUi.Text(T("这里只显示当前安装的问题；打开结果页可查看路径、警告和历史记录。", "Only current-install issues are shown here; open the result page for paths, warnings, and history."), 12, foreground: ModernUi.TextSecondary, maxLines: 2);
    private Button? _startupViewResultsButton;
    private readonly List<ServiceCheckResult> _lastResults = [];
    private bool _checking;
    private bool _checkingStartupIntegrity;
    private bool _preloadingStartupResults;

    public ServiceStatusPage(Action<StartupCheckResultPayload>? openStartupCheckResults = null)
    {
        _openStartupCheckResults = openStartupCheckResults;
        Background = ModernUi.AppBackground;
        Content = BuildContent();
        Loaded += async (_, _) =>
        {
            await RefreshStartupCheckSummaryAsync();
            await RunChecksAsync(issuesOnly: false);
        };
    }

    private UIElement BuildContent()
    {
        var root = new StackPanel
        {
            Padding = new Thickness(28, 24, 40, 28),
            Spacing = 18,
            Children =
            {
                BuildHero(),
                BuildStartupCheckCard(),
                BuildExplanation(),
                ModernUi.Card(new StackPanel
                {
                    Spacing = 12,
                    Children =
                    {
                        ModernUi.Text(T("健康面板", "Health Panel"), 18, FontWeights.SemiBold),
                        _statusList
                    }
                }, new Thickness(18), radius: 8)
            }
        };

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

    private Border BuildHero()
    {
        var actions = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 12 };
        actions.Children.Add(ModernUi.PillButton(T("检查全部", "Check all"), "\uE9D9", async () => await RunChecksAsync(false), primary: true));
        actions.Children.Add(ModernUi.PillButton(T("复检问题", "Recheck issues"), "\uE946", async () => await RunChecksAsync(true)));
        actions.Children.Add(ModernUi.PillButton(T("复制摘要", "Copy summary"), "\uE8C8", CopySummary));

        var grid = new Grid { ColumnSpacing = 18, RowSpacing = 14 };
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.Children.Add(new StackPanel
        {
            Spacing = 16,
            Children =
            {
                ModernUi.Text(T("服务状态", "Service Status"), 24, FontWeights.SemiBold),
                _summaryText,
                new StackPanel
                {
                    Orientation = Orientation.Horizontal,
                    Spacing = 12,
                    Children =
                    {
                        StatusTile(T("总体", "Overall"), _overallText, ModernUi.Brush("#EDF2F3")),
                        StatusTile(T("可用", "Available"), _availableCountText, ModernUi.AccentSoft),
                        StatusTile(T("降级", "Degraded"), _warningCountText, ModernUi.Brush("#F8EFD8")),
                        StatusTile(T("问题", "Issues"), _issueCountText, ModernUi.Brush("#F7E8E3"))
                    }
                }
            }
        });
        Grid.SetColumn(actions, 1);
        grid.Children.Add(actions);
        grid.SizeChanged += (_, e) => ApplyTwoColumnState(grid, actions, e.NewSize.Width < 900);
        return ModernUi.Card(grid, new Thickness(20), radius: 8);
    }

    private Border BuildStartupCheckCard()
    {
        var runButton = ModernUi.PillButton(T("重新自检", "Run check"), "\uE9D9", async () => await RunManualStartupIntegrityCheckAsync(), primary: true);
        var viewButton = ModernUi.PillButton(T("查看结果", "View results"), "\uE8A7", async () => await ConfirmAndOpenStartupCheckResultsAsync());
        _startupViewResultsButton = viewButton;
        viewButton.IsEnabled = _openStartupCheckResults is not null;

        var actions = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Spacing = 10,
            Children = { runButton, viewButton }
        };

        var grid = new Grid { ColumnSpacing = 18, RowSpacing = 14 };
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.Children.Add(new StackPanel
        {
            Spacing = 14,
            Children =
            {
                ModernUi.Text(T("启动自检 / 安装完整性", "Startup Check / Install Integrity"), 18, FontWeights.SemiBold),
                _startupSummaryText,
                new StackPanel
                {
                    Orientation = Orientation.Horizontal,
                    Spacing = 12,
                    Children =
                    {
                        StatusTile(T("状态", "Status"), _startupOverallText, ModernUi.Brush("#EDF2F3")),
                        StatusTile(T("当前问题", "Current issues"), _startupIssueStateText, ModernUi.SurfaceAlt)
                    }
                },
                _startupTimeText,
                _startupBasisText,
                _startupResultTipText,
                _startupResultPreloadBar
            }
        });
        Grid.SetColumn(actions, 1);
        grid.Children.Add(actions);
        grid.SizeChanged += (_, e) => ApplyTwoColumnState(grid, actions, e.NewSize.Width < 900);
        return ModernUi.Card(grid, new Thickness(18), radius: 8);
    }

    private static void ApplyTwoColumnState(Grid grid, FrameworkElement actions, bool narrow)
    {
        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(actions, 0);
            Grid.SetRow(actions, 1);
        }
        else
        {
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
            Grid.SetColumn(actions, 1);
            Grid.SetRow(actions, 0);
        }
    }

    private static Border StatusTile(string title, TextBlock value, Microsoft.UI.Xaml.Media.Brush background)
    {
        return new Border
        {
            MinWidth = 92,
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(14, 10, 14, 10),
            Background = background,
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1),
            Child = new StackPanel
            {
                Spacing = 3,
                Children =
                {
                    ModernUi.Text(title, 13, FontWeights.SemiBold, ModernUi.TextSecondary),
                    value
                }
            }
        };
    }

    private Border BuildExplanation()
    {
        var panel = new VariableSizedWrapGrid
        {
            Orientation = Orientation.Horizontal,
            ItemWidth = 250,
            ItemHeight = 82
        };
        foreach (var item in new[]
        {
            (T("可用", "Available"), T("服务返回了预期数据。", "The service returned expected data."), ModernUi.Accent),
            (T("降级", "Degraded"), T("可连接，但响应较慢或为空。", "Reachable, but slow or empty."), ModernUi.Bronze),
            (T("问题", "Issue"), T("连接失败、超时或发生错误。", "Connection failed, timed out, or errored."), ModernUi.Danger),
            (T("跳过", "Skipped"), T("因筛选或当前不需要而跳过。", "Skipped by filter or not needed here."), ModernUi.TextSecondary)
        })
        {
            panel.Children.Add(ModernUi.Card(new StackPanel
            {
                Spacing = 4,
                Children =
                {
                    ModernUi.Text(item.Item1, 13, FontWeights.SemiBold, ModernUi.TextSecondary),
                    ModernUi.Text(item.Item2, 13, FontWeights.SemiBold, item.Item3, maxLines: 2)
                }
            }, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt));
        }

        return ModernUi.Card(new Expander
        {
            Header = ModernUi.Text(T("状态说明", "Status guide"), 18, FontWeights.SemiBold),
            IsExpanded = false,
            Content = panel
        }, new Thickness(18), radius: 8);
    }

    private async Task RunChecksAsync(bool issuesOnly)
    {
        if (_checking)
        {
            return;
        }

        _checking = true;
        _summaryText.Text = T("正在依次检查核心服务、API 来源和本地组件。", "Checking core services, API sources, and local components in sequence.");
        _overallText.Text = T("检查中", "Checking");
        _overallText.Foreground = ModernUi.Info;
        _statusList.Children.Clear();

        try
        {
            var previousIssues = _lastResults
                .Where(result => result.Status is ServiceHealthStatus.Issue or ServiceHealthStatus.Failed or ServiceHealthStatus.Timeout or ServiceHealthStatus.Degraded)
                .Select(result => result.Id)
                .ToHashSet(StringComparer.OrdinalIgnoreCase);

            var checks = BuildChecks();
            if (issuesOnly && previousIssues.Count > 0)
            {
                checks = checks.Where(check => previousIssues.Contains(check.Id)).ToList();
            }

            _lastResults.Clear();
            for (var index = 0; index < checks.Count; index++)
            {
                _statusList.Children.Add(StatusRow(ServiceCheckResult.Pending(checks[index])));
            }

            for (var index = 0; index < checks.Count; index++)
            {
                var check = checks[index];
                _statusList.Children[index] = StatusRow(ServiceCheckResult.Checking(check));
                var result = await RunSingleCheckAsync(check);
                _lastResults.Add(result);
                _statusList.Children[index] = StatusRow(result);
                RenderSummary(index < checks.Count - 1);
            }

            RenderSummary();
            await _logService.WriteAsync("Information", "service", "Service status check completed", BuildPlainSummary());
        }
        finally
        {
            _checking = false;
        }
    }

    private async Task RefreshStartupCheckSummaryAsync()
    {
        try
        {
            var report = await Task.Run(async () => await _integrityCheckService.GetLatestCurrentReportAsync(StartupCheckKind.FastPreflight).ConfigureAwait(false));
            ApplyStartupReport(report);
        }
        catch (Exception exception)
        {
            _startupOverallText.Text = T("加载失败", "Load failed");
            _startupOverallText.Foreground = ModernUi.Bronze;
            _startupSummaryText.Text = T($"无法加载启动自检摘要：{FriendlyError(exception.Message)}", $"Could not load startup check summary: {FriendlyError(exception.Message)}");
        }
    }

    private async Task RunManualStartupIntegrityCheckAsync()
    {
        if (_checkingStartupIntegrity)
        {
            return;
        }

        _checkingStartupIntegrity = true;
        _startupOverallText.Text = T("检查中", "Checking");
        _startupOverallText.Foreground = ModernUi.Info;
        _startupSummaryText.Text = T("正在检查当前安装目录、语言资源、关键文件、Tools、Metadata 和安装清单。", "Checking the current install root, language resources, critical files, Tools, Metadata, and manifest.");

        try
        {
            var report = await Task.Run(async () => await _integrityCheckService.RunManualIntegrityCheckAsync().ConfigureAwait(false));
            ApplyStartupReport(report);
            _startupResultTipText.Text = report.HasVisibleIssues
                ? T("检查完成：发现当前安装问题。打开结果页可查看详情。", "Check complete: current-install issues found. Open the result page for details.")
                : T("检查完成：当前安装没有问题。", "Check complete: no current-install issues found.");
        }
        catch (Exception exception)
        {
            CrashLog.Write(exception);
            _startupOverallText.Text = T("检查失败", "Check failed");
            _startupOverallText.Foreground = ModernUi.Danger;
            _startupIssueStateText.Text = T("是", "Yes");
            _startupIssueStateText.Foreground = ModernUi.Danger;
            _startupSummaryText.Text = T("检查失败。请打开结果页或日志页查看详情。", "Check failed. Open the results or logs page for details.");
            _startupResultTipText.Text = FriendlyError(exception.Message);
        }
        finally
        {
            _checkingStartupIntegrity = false;
        }
    }

    private async Task ConfirmAndOpenStartupCheckResultsAsync()
    {
        if (_openStartupCheckResults is null || _preloadingStartupResults)
        {
            return;
        }

        _preloadingStartupResults = true;
        SetStartupResultPreloadState(true, 8, T("正在准备当前安装报告...", "Preparing current-install report..."));
        try
        {
            SetStartupResultPreloadState(true, 32, T("正在读取当前安装历史...", "Reading current-install history..."));
            var history = await Task.Run(async () => await _integrityCheckService.GetCurrentHistoryAsync(30).ConfigureAwait(false));

            SetStartupResultPreloadState(true, 68, T("正在读取最新当前报告...", "Reading latest current report..."));
            var latest = await Task.Run(async () => await _integrityCheckService.GetLatestCurrentReportAsync(StartupCheckKind.FastPreflight).ConfigureAwait(false));

            StartupCheckReport? selected = latest;
            if (selected is null && history.Count > 0)
            {
                selected = await Task.Run(async () => await _integrityCheckService.GetReportAsync(history[0].Id).ConfigureAwait(false));
            }

            SetStartupResultPreloadState(true, 100, T("正在打开结果...", "Opening results..."));
            _openStartupCheckResults(new StartupCheckResultPayload(selected, history));
        }
        catch (Exception exception)
        {
            CrashLog.Write(exception);
            ToastService.Show(T("无法预加载启动自检结果。", "Could not preload startup check results."), ToastKind.Error);
            _startupResultTipText.Text = T($"预加载失败：{FriendlyError(exception.Message)}", $"Preload failed: {FriendlyError(exception.Message)}");
        }
        finally
        {
            _preloadingStartupResults = false;
            SetStartupResultPreloadState(false, 0, T("这里只显示当前安装的问题；打开结果页可查看路径、警告和历史记录。", "Only current-install issues are shown here; open the result page for paths, warnings, and history."));
        }
    }

    private void SetStartupResultPreloadState(bool loading, double value, string message)
    {
        _startupResultPreloadBar.Visibility = loading ? Visibility.Visible : Visibility.Collapsed;
        _startupResultPreloadBar.IsIndeterminate = loading && value <= 0;
        _startupResultPreloadBar.Value = Math.Clamp(value, 0, 100);
        _startupResultTipText.Text = message;

        if (_startupViewResultsButton is null)
        {
            return;
        }

        _startupViewResultsButton.IsEnabled = !loading && _openStartupCheckResults is not null;
    }

    private void ApplyStartupReport(StartupCheckReport? report)
    {
        if (report is null)
        {
            _startupOverallText.Text = T("待检查", "Pending");
            _startupOverallText.Foreground = ModernUi.Info;
            _startupIssueStateText.Text = T("未知", "Unknown");
            _startupIssueStateText.Foreground = ModernUi.TextSecondary;
            _startupSummaryText.Text = T("当前安装尚未运行启动自检。", "No current-install startup check has run yet.");
            _startupTimeText.Text = T("上次检查：-", "Last check: -");
            _startupBasisText.Text = string.Empty;
            return;
        }

        var hasIssues = report.HasVisibleIssues;
        _startupOverallText.Text = hasIssues ? T("有问题", "Issues") : T("健康", "Healthy");
        _startupOverallText.Foreground = hasIssues ? ModernUi.Bronze : ModernUi.Accent;
        _startupIssueStateText.Text = hasIssues ? report.VisibleIssueCount.ToString() : "0";
        _startupIssueStateText.Foreground = hasIssues ? ModernUi.Bronze : ModernUi.Accent;
        _startupSummaryText.Text = hasIssues
            ? T("启动自检发现当前安装问题。打开结果页可查看详情。", "Startup check found current-install issues. Open the result page for details.")
            : T("启动自检完成，当前安装没有问题。", "Startup check completed with no current-install issues.");
        _startupTimeText.Text = T($"上次检查：{report.CompletedAt:yyyy-MM-dd HH:mm}", $"Last check: {report.CompletedAt:yyyy-MM-dd HH:mm}");
        _startupBasisText.Text = T($"基准：{report.CheckBasis} / {report.InstallRoot}", $"Basis: {report.CheckBasis} / {report.InstallRoot}");
    }

    private List<ServiceCheck> BuildChecks()
    {
        var checks = new List<ServiceCheck>
        {
            new("update", T("更新服务", "Update service"), T("远程发布", "Remote release"), CheckUpdateAsync),
            new("media-config", T("媒体配置", "Media configuration"), T("远程媒体", "Remote media"), CheckMediaConfigAsync),
            new("reference-data", T("参考数据", "Reference data"), T("本地数据", "Local data"), CheckReferenceDataAsync),
            new("webview2", "WebView2", T("系统组件", "System component"), CheckWebView2Async),
            new("worker", T("工具进程", "Tool worker"), T("进程隔离", "Process isolation"), CheckWorkerAsync),
            new("sqlite", T("日志与 SQLite", "Logs and SQLite"), T("本地存储", "Local storage"), CheckSqliteAsync),
            new("system-metrics", T("系统指标", "System metrics"), T("本机", "Local machine"), CheckSystemMetricsAsync)
        };

        foreach (var endpoint in ApiEndpoints.All.OrderBy(endpoint => endpoint.Id, StringComparer.OrdinalIgnoreCase))
        {
            checks.Add(new ServiceCheck(
                $"api:{endpoint.Id}",
                SafeEndpointName(endpoint),
                endpoint.IsOfficial ? T("官方 / 公开 API", "Official / public API") : T("公开数据源", "Public data source"),
                token => CheckApiAsync(endpoint.Id, token)));
        }

        return checks;
    }

    private async Task<ServiceCheckResult> RunSingleCheckAsync(ServiceCheck check)
    {
        var sw = Stopwatch.StartNew();
        try
        {
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(8));
            var result = await check.Run(cts.Token);
            sw.Stop();
            return result with
            {
                Id = check.Id,
                Name = check.Name,
                Type = check.Type,
                Latency = result.Latency == TimeSpan.Zero ? sw.Elapsed : result.Latency,
                CheckedAt = DateTimeOffset.Now
            };
        }
        catch (OperationCanceledException)
        {
            return ServiceCheckResult.Timeout(check.Id, check.Name, check.Type, "Timeout", sw.Elapsed);
        }
        catch (Exception exception)
        {
            return ServiceCheckResult.Failed(check.Id, check.Name, check.Type, FriendlyError(exception.Message), sw.Elapsed);
        }
    }

    private async Task<ServiceCheckResult> CheckApiAsync(string id, CancellationToken cancellationToken)
    {
        var sw = Stopwatch.StartNew();
        var response = await _apiManager.FetchAsync(id, string.Empty, cancellationToken);
        sw.Stop();
        if (!response.Success)
        {
            return ServiceCheckResult.Failed(id, string.Empty, string.Empty, FriendlyError(response.Error), sw.Elapsed);
        }

        return string.IsNullOrWhiteSpace(response.Content)
            ? ServiceCheckResult.Degraded(id, string.Empty, string.Empty, T("响应为空", "Empty response"), sw.Elapsed)
            : sw.Elapsed > TimeSpan.FromSeconds(2.5)
                ? ServiceCheckResult.Degraded(id, string.Empty, string.Empty, T("可访问，但延迟较高", "Reachable but latency is high"), sw.Elapsed)
                : ServiceCheckResult.Available(id, string.Empty, string.Empty, T("健康", "Healthy"), sw.Elapsed);
    }

    private async Task<ServiceCheckResult> CheckUpdateAsync(CancellationToken cancellationToken)
    {
        var sw = Stopwatch.StartNew();
        var info = await _updateService.GetUpdateInfoAsync(cancellationToken);
        sw.Stop();
        return info is null
            ? ServiceCheckResult.Failed("update", string.Empty, string.Empty, T("无法获取发布信息", "Could not fetch release info"), sw.Elapsed)
            : ServiceCheckResult.Available("update", string.Empty, string.Empty, T("发布信息可用", "Release info available"), sw.Elapsed);
    }

    private async Task<ServiceCheckResult> CheckMediaConfigAsync(CancellationToken cancellationToken)
    {
        var sw = Stopwatch.StartNew();
        var response = await _httpService.GetAsync(MediaConfigUri, cancellationToken);
        sw.Stop();
        return string.IsNullOrWhiteSpace(response.Content)
            ? ServiceCheckResult.Degraded("media-config", string.Empty, string.Empty, T("媒体配置为空", "Media config is empty"), sw.Elapsed)
            : ServiceCheckResult.Available("media-config", string.Empty, string.Empty, T("媒体配置可用", "Media configuration available"), sw.Elapsed);
    }

    private Task<ServiceCheckResult> CheckReferenceDataAsync(CancellationToken cancellationToken)
    {
        var validation = _referenceDataService.ValidateRequiredAssets(
            "data/reference/ymhut_reference_data.json",
            "data/sanguosha/skin_config.json",
            "data/AMap_adcode_citycode.csv");
        return Task.FromResult(validation.IsHealthy
            ? ServiceCheckResult.Available("reference-data", string.Empty, string.Empty, T("参考数据就绪", "Reference data ready"), TimeSpan.Zero)
            : ServiceCheckResult.Failed("reference-data", string.Empty, string.Empty, T("参考数据缺失", "Reference data missing"), TimeSpan.Zero));
    }

    private static Task<ServiceCheckResult> CheckWebView2Async(CancellationToken cancellationToken)
    {
        try
        {
            var type = Type.GetType("Microsoft.Web.WebView2.Core.CoreWebView2Environment, Microsoft.Web.WebView2.Core");
            var method = type?.GetMethod("GetAvailableBrowserVersionString", Type.EmptyTypes);
            var version = method?.Invoke(null, null) as string;
            return Task.FromResult(string.IsNullOrWhiteSpace(version)
                ? ServiceCheckResult.Degraded("webview2", string.Empty, string.Empty, T("未检测到运行时版本", "Runtime version not detected"), TimeSpan.Zero)
                : ServiceCheckResult.Available("webview2", string.Empty, string.Empty, T($"运行时 {version}", $"Runtime {version}"), TimeSpan.Zero));
        }
        catch (Exception exception)
        {
            return Task.FromResult(ServiceCheckResult.Failed("webview2", string.Empty, string.Empty, FriendlyError(exception.Message), TimeSpan.Zero));
        }
    }

    private async Task<ServiceCheckResult> CheckWorkerAsync(CancellationToken cancellationToken)
    {
        var module = _catalog.GetById("uuid_generator");
        if (module is null)
        {
            return ServiceCheckResult.Failed("worker", string.Empty, string.Empty, T("冒烟测试工具缺失", "Smoke tool missing"), TimeSpan.Zero);
        }

        var sw = Stopwatch.StartNew();
        var result = await _workerService.ExecuteToolAsync(module, "1", _apiManager, _referenceDataService, cancellationToken, AppLocalizer.CurrentLanguage);
        sw.Stop();
        return result.Ok
            ? ServiceCheckResult.Available("worker", string.Empty, string.Empty, T("工具进程已响应", "Worker responded"), sw.Elapsed)
            : ServiceCheckResult.Failed("worker", string.Empty, string.Empty, FriendlyError(result.Error), sw.Elapsed);
    }

    private async Task<ServiceCheckResult> CheckSqliteAsync(CancellationToken cancellationToken)
    {
        var sw = Stopwatch.StartNew();
        await _logService.WriteAsync("Information", "service", "SQLite health check", cancellationToken: cancellationToken);
        sw.Stop();
        return ServiceCheckResult.Available("sqlite", string.Empty, string.Empty, T("日志写入成功", "Log write succeeded"), sw.Elapsed);
    }

    private Task<ServiceCheckResult> CheckSystemMetricsAsync(CancellationToken cancellationToken)
    {
        var metrics = _metricsService.Capture();
        var detail = $"{metrics.ProcessorCount} cores / {metrics.WorkingSetBytes / 1024 / 1024} MB";
        return Task.FromResult(ServiceCheckResult.Available("system-metrics", string.Empty, string.Empty, detail, TimeSpan.Zero));
    }

    private UIElement StatusRow(ServiceCheckResult result)
    {
        var grid = new Grid
        {
            Padding = new Thickness(10),
            ColumnSpacing = 12
        };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        if (result.Status == ServiceHealthStatus.Checking)
        {
            grid.Children.Add(new ProgressRing
            {
                Width = 18,
                Height = 18,
                IsActive = true,
                VerticalAlignment = VerticalAlignment.Center
            });
        }
        else
        {
            grid.Children.Add(new Border
            {
                Width = 10,
                Height = 10,
                CornerRadius = new CornerRadius(5),
                Background = StatusBrush(result.Status),
                VerticalAlignment = VerticalAlignment.Center
            });
        }

        var text = new StackPanel
        {
            Spacing = 3,
            Children =
            {
                ModernUi.Text(result.Name, 15, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text($"{result.Type}  {result.Detail}", 12, foreground: ModernUi.TextSecondary, maxLines: 2)
            }
        };
        Grid.SetColumn(text, 1);
        grid.Children.Add(text);

        var right = new StackPanel
        {
            HorizontalAlignment = HorizontalAlignment.Right,
            Spacing = 4,
            Children =
            {
                ModernUi.SmallBadge(StatusText(result.Status), StatusBrush(result.Status), ModernUi.SurfaceAlt),
                ModernUi.Text(result.Latency == TimeSpan.Zero ? "-" : $"{result.Latency.TotalMilliseconds:0} ms", 12, FontWeights.SemiBold, ModernUi.TextSecondary)
            }
        };
        Grid.SetColumn(right, 2);
        grid.Children.Add(right);
        return ModernUi.Card(grid, new Thickness(0), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private void RenderSummary(bool inProgress = false)
    {
        var ok = _lastResults.Count(result => result.Status == ServiceHealthStatus.Available);
        var degraded = _lastResults.Count(result => result.Status == ServiceHealthStatus.Degraded);
        var issues = _lastResults.Count(result => result.Status is ServiceHealthStatus.Issue or ServiceHealthStatus.Failed or ServiceHealthStatus.Timeout);
        _availableCountText.Text = ok.ToString();
        _warningCountText.Text = degraded.ToString();
        _issueCountText.Text = issues.ToString();
        if (inProgress)
        {
            _overallText.Text = T("检查中", "Checking");
            _overallText.Foreground = ModernUi.Info;
            _summaryText.Text = T(
                $"检查中：已完成 {_lastResults.Count} 项，{ok} 项可用，{degraded} 项降级，{issues} 项问题。",
                $"Checking: {_lastResults.Count} completed, {ok} available, {degraded} degraded, {issues} issues.");
            return;
        }

        _overallText.Text = issues > 0 ? T("有问题", "Issue") : degraded > 0 ? T("降级", "Degraded") : T("可用", "Available");
        _overallText.Foreground = issues > 0 ? ModernUi.Danger : degraded > 0 ? ModernUi.Bronze : ModernUi.Accent;
        _summaryText.Text = T(
            $"检查完成：{ok} 项可用，{degraded} 项降级，{issues} 项问题。",
            $"Check complete: {ok} available, {degraded} degraded, {issues} issues.");
    }

    private void CopySummary()
    {
        var data = new DataPackage();
        data.SetText(BuildPlainSummary());
        Clipboard.SetContent(data);
        ToastService.Show(T("已复制脱敏摘要。", "Sanitized summary copied"), ToastKind.Success);
    }

    private string BuildPlainSummary()
    {
        IEnumerable<string> lines = _lastResults.Count == 0
            ? [T("尚未运行健康检查。", "No health check has run yet.")]
            : _lastResults.Select(result => $"{result.Name} | {StatusText(result.Status)} | {(result.Latency == TimeSpan.Zero ? "-" : $"{result.Latency.TotalMilliseconds:0} ms")} | {result.Detail}");
        return string.Join(Environment.NewLine, lines);
    }

    private static string SafeEndpointName(ApiEndpoint endpoint)
    {
        return endpoint.Id switch
        {
            "media_types" => T("媒体配置", "Media configuration"),
            _ => ToolText.Name(endpoint.Id, endpoint.Name)
        };
    }

    private static string FriendlyError(string? message)
        => AppLocalizer.SanitizeSensitiveText(message, 110);

    private static Microsoft.UI.Xaml.Media.Brush StatusBrush(ServiceHealthStatus status)
    {
        return status switch
        {
            ServiceHealthStatus.Available => ModernUi.Accent,
            ServiceHealthStatus.Degraded => ModernUi.Bronze,
            ServiceHealthStatus.Timeout => ModernUi.Bronze,
            ServiceHealthStatus.Failed => ModernUi.Danger,
            ServiceHealthStatus.Issue => ModernUi.Danger,
            ServiceHealthStatus.Checking => ModernUi.Info,
            _ => ModernUi.TextSecondary
        };
    }

    private static string StatusText(ServiceHealthStatus status)
    {
        return status switch
        {
            ServiceHealthStatus.Available => T("可用", "Available"),
            ServiceHealthStatus.Degraded => T("降级", "Degraded"),
            ServiceHealthStatus.Timeout => T("超时", "Timeout"),
            ServiceHealthStatus.Failed => T("失败", "Failed"),
            ServiceHealthStatus.Issue => T("问题", "Issue"),
            ServiceHealthStatus.Pending => T("待检查", "Pending"),
            ServiceHealthStatus.Checking => T("检查中", "Checking"),
            _ => T("跳过", "Skipped")
        };
    }

    private sealed record ServiceCheck(
        string Id,
        string Name,
        string Type,
        Func<CancellationToken, Task<ServiceCheckResult>> Run);

    private sealed record ServiceCheckResult(
        string Id,
        string Name,
        string Type,
        ServiceHealthStatus Status,
        string Detail,
        TimeSpan Latency,
        DateTimeOffset CheckedAt)
    {
        public static ServiceCheckResult Available(string id, string name, string type, string detail, TimeSpan latency)
            => new(id, name, type, ServiceHealthStatus.Available, detail, latency, DateTimeOffset.Now);

        public static ServiceCheckResult Degraded(string id, string name, string type, string detail, TimeSpan latency)
            => new(id, name, type, ServiceHealthStatus.Degraded, detail, latency, DateTimeOffset.Now);

        public static ServiceCheckResult Timeout(string id, string name, string type, string detail, TimeSpan latency)
            => new(id, name, type, ServiceHealthStatus.Timeout, detail, latency, DateTimeOffset.Now);

        public static ServiceCheckResult Failed(string id, string name, string type, string detail, TimeSpan latency)
            => new(id, name, type, ServiceHealthStatus.Failed, detail, latency, DateTimeOffset.Now);

        public static ServiceCheckResult Pending(ServiceCheck check)
            => new(check.Id, check.Name, check.Type, ServiceHealthStatus.Pending, T("等待中", "Waiting"), TimeSpan.Zero, DateTimeOffset.Now);

        public static ServiceCheckResult Checking(ServiceCheck check)
            => new(check.Id, check.Name, check.Type, ServiceHealthStatus.Checking, T("检查中", "Checking"), TimeSpan.Zero, DateTimeOffset.Now);
    }

    private enum ServiceHealthStatus
    {
        Available,
        Degraded,
        Issue,
        Timeout,
        Failed,
        Skipped,
        Pending,
        Checking
    }
}
