using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using YMhut.Box.Core.Logging;
using YMhut.Box.Core.Settings;
using YMhut.Box.Core.Tools;
using YMhut.Box.WinUI.Services;

namespace YMhut.Box.WinUI.Views;

public sealed partial class BuiltinReferenceToolPage : ToolPageBase
{
    private readonly BuiltinReferenceToolModule _module;
    private readonly Action? _goBack;
    private readonly IBuiltinReferenceToolService _toolService = AppServices.GetRequiredService<IBuiltinReferenceToolService>();
    private readonly IRiskConfirmationStore _riskStore = AppServices.GetRequiredService<IRiskConfirmationStore>();
    private readonly ISettingsService _settingsService = AppServices.GetRequiredService<ISettingsService>();
    private readonly ILogService _logService = AppServices.GetRequiredService<ILogService>();
    private readonly InfoBar _status = new()
    {
        IsOpen = true,
        Severity = InfoBarSeverity.Informational,
        Title = "YMhut Box 内置工具",
        Message = "参考项目内置工具已接入 YMhut Box。风险操作会先确认，执行结果会写入日志。"
    };
    private readonly TextBox _resultBox = new()
    {
        IsReadOnly = true,
        AcceptsReturn = true,
        MinHeight = 260,
        Header = "结果",
        TextWrapping = TextWrapping.Wrap
    };
    private readonly ProgressRing _progress = new()
    {
        Width = 24,
        Height = 24,
        IsActive = false,
        Visibility = Visibility.Collapsed
    };

    public BuiltinReferenceToolPage(BuiltinReferenceToolModule module, Action? goBack = null)
    {
        _module = module;
        _goBack = goBack;
        Background = ModernUi.AppBackground;
        BindModule(module);
        Content = BuildLayout();
    }

    private UIElement BuildLayout()
    {
        var root = new Grid
        {
            Padding = new Thickness(24, 20, 24, 24),
            RowSpacing = 16
        };
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        root.RowDefinitions.Add(new RowDefinition());

        root.Children.Add(BuildModernHeader());
        Grid.SetRow(_status, 1);

        var body = new Grid { ColumnSpacing = 16 };
        body.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.8, GridUnitType.Star) });
        body.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.2, GridUnitType.Star) });
        Grid.SetRow(body, 1);
        root.Children.Add(body);

        body.Children.Add(new StackPanel
        {
            Spacing = 14,
            Children =
            {
                _status,
                BuildActionPanel(),
                BuildRiskPanel()
            }
        });

        Grid.SetColumn(_resultBox, 1);
        body.Children.Add(_resultBox);
        return root;
    }

    private UIElement BuildHeader()
    {
        var definition = _module.Definition;
        var grid = new Grid { ColumnSpacing = 14 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition());

        grid.Children.Add(ModernUi.IconButton("\uE72B", "返回工具箱", () => _goBack?.Invoke()));
        var icon = ModernUi.IconTile(definition.Glyph, 50, ModernUi.AccentSoft, ModernUi.Accent, 22);
        Grid.SetColumn(icon, 1);
        grid.Children.Add(icon);

        var title = new StackPanel
        {
            Spacing = 5,
            Children =
            {
                ModernUi.Text(definition.Name, 26, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text($"{ToolText.CategoryLabel(definition.Category)} / {definition.Kind} / {RiskLabel(definition.RiskLevel)}", 14, foreground: ModernUi.TextSecondary, maxLines: 1),
                ModernUi.Text(definition.Description, 14, foreground: ModernUi.TextSecondary, maxLines: 2)
            }
        };
        Grid.SetColumn(title, 2);
        grid.Children.Add(title);
        return ModernUi.Card(grid, new Thickness(18), radius: 8);
    }

    private UIElement BuildActionPanel()
    {
        var runButton = ModernUi.PillButton(_module.Definition.PrimaryAction, "\uE768", RunAsync, primary: true);
        return ModernUi.Card(new StackPanel
        {
            Spacing = 12,
            Children =
            {
                ModernUi.Text("操作", 18, FontWeights.SemiBold),
                new StackPanel { Orientation = Orientation.Horizontal, Spacing = 10, Children = { runButton, _progress } },
                ModernUi.Text("Windows 激活相关仅提供合规入口：查看激活状态、打开系统激活设置、企业 KMS 配置说明；不提供绕过授权或自动盗版激活流程。", 13, foreground: ModernUi.TextSecondary)
            }
        }, new Thickness(16), radius: 8);
    }

    private UIElement BuildRiskPanel()
    {
        var definition = _module.Definition;
        var severity = definition.RiskLevel switch
        {
            ReferenceToolRiskLevel.High => InfoBarSeverity.Error,
            ReferenceToolRiskLevel.Medium => InfoBarSeverity.Warning,
            ReferenceToolRiskLevel.Low => InfoBarSeverity.Informational,
            _ => InfoBarSeverity.Success
        };

        return new InfoBar
        {
            IsOpen = true,
            Severity = severity,
            Title = definition.IsRisky ? "需要二次确认" : "低风险入口",
            Message = definition.IsRisky
                ? "该工具可能涉及管理员运行、注册表、Hosts、证书、Defender、文件删除或敏感信息。执行前会再次确认。"
                : "该工具不会直接修改系统；成功、失败和降级仍会写入日志。"
        };
    }

    private async void RunAsync()
    {
        if (!await ConfirmRiskIfNeededAsync())
        {
            var cancelled = ReferenceToolExecutionResult.Cancel("已取消执行。");
            SetResult(cancelled);
            await _logService.WriteAsync("Warning", "risk", "Builtin tool execution cancelled", _module.Id);
            return;
        }

        _progress.Visibility = Visibility.Visible;
        _progress.IsActive = true;
        try
        {
            SetResult(await _toolService.ExecuteAsync(_module.Definition, confirmed: true));
        }
        finally
        {
            _progress.IsActive = false;
            _progress.Visibility = Visibility.Collapsed;
        }
    }

    private async Task<bool> ConfirmRiskIfNeededAsync()
    {
        const string operation = "execute";
        if (!_module.Definition.IsRisky)
        {
            return true;
        }

        if (!_settingsService.Current.RequireRiskConfirmation)
        {
            await _logService.WriteAsync(
                "Warning",
                "risk",
                "Builtin tool risk confirmation bypassed by settings",
                _module.Id);
            return true;
        }

        if (await _riskStore.IsRememberedAsync(_module.Id, operation))
        {
            return true;
        }

        var remember = new CheckBox { Content = "记住此工具确认", Margin = new Thickness(0, 10, 0, 0) };
        var content = new StackPanel
        {
            Spacing = 8,
            Children =
            {
                ModernUi.Text(_module.Definition.Description, 14, foreground: ModernUi.TextSecondary),
                ModernUi.Text("请确认你理解该操作可能修改系统设置、文件、注册表或读取敏感配置。", 14, foreground: ModernUi.TextSecondary),
                remember
            }
        };

        var dialog = new ContentDialog
        {
            Title = "确认执行风险功能",
            Content = content,
            PrimaryButtonText = "确认执行",
            CloseButtonText = "取消",
            DefaultButton = ContentDialogButton.Close,
            XamlRoot = XamlRoot
        };
        var result = await dialog.ShowAsync();
        if (result != ContentDialogResult.Primary)
        {
            return false;
        }

        await _logService.WriteAsync("Information", "risk", "Builtin tool risk confirmed", $"{_module.Id}; remembered={remember.IsChecked == true}");
        if (remember.IsChecked == true)
        {
            await _riskStore.RememberAsync(_module.Id, operation);
        }

        return true;
    }

    private void SetResult(ReferenceToolExecutionResult result)
    {
        _status.Severity = result.Success ? InfoBarSeverity.Success : result.Cancelled ? InfoBarSeverity.Warning : InfoBarSeverity.Error;
        _status.Title = result.Success ? "完成" : result.Cancelled ? "已取消" : "未完成";
        _status.Message = result.Message;
        _resultBox.Text = string.Join(Environment.NewLine, new[]
        {
            result.Message,
            result.Detail,
            result.OutputPath is null ? null : $"Output: {result.OutputPath}",
            result.ExitCode is null ? null : $"ExitCode: {result.ExitCode}"
        }.Where(value => !string.IsNullOrWhiteSpace(value)));
    }

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