using System.Text.Json;
using System.Text.RegularExpressions;
using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using YMhut.Box.Core.Tools;

namespace YMhut.Box.WinUI.Views.Tools;

public abstract partial class AdaptiveToolPage
{
    private bool TryRenderSpecializedResult(IToolModule module, string output, IReadOnlyList<string> lines)
    {
        if (string.IsNullOrWhiteSpace(output))
        {
            _resultCards.Children.Add(BuildEmptyResultCard());
            return true;
        }

        if (module.Id == "color_picker" && TryRenderColor(output))
        {
            return true;
        }

        if (module.Id == "dns_query" && TryRenderDns(lines))
        {
            return true;
        }

        if (module.Id is "ip_lookup" or "ip_info" or "rdap_ip_lookup" or "rdap_domain_lookup" or "domain_price" && TryRenderKeyValueSections(lines, "网络详情"))
        {
            return true;
        }

        if (module.Id is "mime_lookup" or "http_status_lookup" or "port_lookup" or "dns_record_lookup" or "unicode_block_lookup" or "charset_lookup" or "timezone_abbr_lookup" or "regex_preset_lookup" or "magic_number_lookup" or "car_info" or "sanguosha_skin" && TryRenderReferenceRows(lines))
        {
            return true;
        }

        if (module.Id is "text_diff" && TryRenderDiff(lines))
        {
            return true;
        }

        if (module.Id is "hash_manifest_verify" && TryRenderStatusRows(lines))
        {
            return true;
        }

        if (module.Id is "archive_tool" && TryRenderArchiveRows(lines))
        {
            return true;
        }

        if (module.Metadata.Category is ToolCategory.Image && TryRenderFileOutput(lines))
        {
            return true;
        }

        if (module.Id is "markdown_table_normalizer" && TryRenderMarkdownTable(lines))
        {
            return true;
        }

        if (module.Id == "jwt_decoder" && TryRenderMultiJson(output))
        {
            return true;
        }

        if (TryRenderJson(output, module))
        {
            return true;
        }

        if (module.Id is "text_statistics" or "line_length_analyzer" or "keyword_counter" or "list_group_statistics" or "extension_statistics" && TryRenderKeyValueSections(lines, "统计摘要"))
        {
            return true;
        }

        if (module.Metadata.Category is ToolCategory.Calculator or ToolCategory.System or ToolCategory.Life or ToolCategory.Security && TryRenderKeyValueSections(lines, ResultGroupTitle(module)))
        {
            return true;
        }

        if (module.Id is "xml_formatter" or "sql_formatter" or "html_minifier" or "js_obfuscator" or "html_text_extractor" or "unicode_codec" or "punycode_codec" && TryRenderCodeLikeOutput(module, output, lines))
        {
            return true;
        }

        if (module.Metadata.Category is ToolCategory.Text or ToolCategory.Dev or ToolCategory.Design && TryRenderTextRows(module, lines))
        {
            return true;
        }

        return false;
    }

    private bool TryRenderJson(string output, IToolModule module)
    {
        var trimmed = output.TrimStart();
        if (!trimmed.StartsWith('{') && !trimmed.StartsWith('['))
        {
            return false;
        }

        try
        {
            using var document = JsonDocument.Parse(output);
            var summaryRows = new List<(string Key, string Value)>
            {
                ("类型", document.RootElement.ValueKind == JsonValueKind.Array ? "Array" : "Object")
            };
            if (document.RootElement.ValueKind == JsonValueKind.Array)
            {
                summaryRows.Add(("项目数", document.RootElement.GetArrayLength().ToString()));
            }
            else if (document.RootElement.ValueKind == JsonValueKind.Object)
            {
                summaryRows.Add(("字段数", document.RootElement.EnumerateObject().Count().ToString()));
            }

            _resultCards.Children.Add(BuildInfoGrid(summaryRows));
            if (TryBuildJsonResultCard(module.Id.Contains("json", StringComparison.OrdinalIgnoreCase) ? "JSON" : "Structured JSON", output, out var jsonCard))
            {
                _resultCards.Children.Add(jsonCard);
            }
            else
            {
                _resultCards.Children.Add(BuildCodePreviewCard(module.Id.Contains("json", StringComparison.OrdinalIgnoreCase) ? "JSON 原文" : "结构化原文", output));
            }
            return true;
        }
        catch
        {
            return false;
        }
    }

    private bool TryRenderMultiJson(string output)
    {
        var sections = output.Replace("\r\n", "\n")
            .Split("\n\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
            .Where(section => section.TrimStart().StartsWith('{') || section.TrimStart().StartsWith('['))
            .Take(3)
            .ToList();
        if (sections.Count == 0)
        {
            return false;
        }

        for (var index = 0; index < sections.Count; index++)
        {
            try
            {
                using var document = JsonDocument.Parse(sections[index]);
                _resultCards.Children.Add(ModernUi.Text(index == 0 ? "JWT Header" : "JWT Payload", 13, FontWeights.SemiBold, ModernUi.TextSecondary));
                foreach (var property in document.RootElement.EnumerateObject().Take(12))
                {
                    _resultCards.Children.Add(BuildJsonPropertyCard(property.Name, property.Value));
                }
            }
            catch
            {
                _resultCards.Children.Add(BuildCodePreviewCard($"JWT 片段 {index + 1}", sections[index]));
            }
        }

        return true;
    }

    private bool TryRenderDns(IReadOnlyList<string> lines)
    {
        if (!lines.Any(line => line.Contains("TYPE", StringComparison.OrdinalIgnoreCase) && line.Contains("TTL", StringComparison.OrdinalIgnoreCase)))
        {
            return false;
        }

        var headerRows = lines
            .TakeWhile(line => !line.Contains("TYPE", StringComparison.OrdinalIgnoreCase))
            .Select(ParseKeyValue)
            .Where(pair => pair is not null)
            .Select(pair => pair!.Value)
            .ToList();
        if (headerRows.Count > 0)
        {
            _resultCards.Children.Add(BuildInfoGrid(headerRows));
        }

        foreach (var line in lines.Where(line => line.Contains("TYPE", StringComparison.OrdinalIgnoreCase) && line.Contains("TTL", StringComparison.OrdinalIgnoreCase)).Take(30))
        {
            var match = Regex.Match(line, @"^(?<name>.*?)\s+TYPE\s+(?<type>\S+)\s+TTL\s+(?<ttl>\S+)\s+(?<data>.*)$", RegexOptions.IgnoreCase);
            if (!match.Success)
            {
                _resultCards.Children.Add(BuildLineResultCard(line));
                continue;
            }

            _resultCards.Children.Add(BuildRecordCard(
                match.Groups["type"].Value,
                match.Groups["name"].Value,
                match.Groups["data"].Value,
                $"TTL {match.Groups["ttl"].Value}"));
        }

        return true;
    }

    private bool TryRenderReferenceRows(IReadOnlyList<string> lines)
    {
        var rows = lines
            .Where(line => !line.StartsWith("数据源：", StringComparison.Ordinal) && !line.StartsWith("说明：", StringComparison.Ordinal))
            .Where(line => line.Contains(" - ", StringComparison.Ordinal) || line.Contains(" / ", StringComparison.Ordinal) || line.Contains("adcode", StringComparison.OrdinalIgnoreCase))
            .Take(40)
            .ToList();
        if (rows.Count == 0)
        {
            return false;
        }

        foreach (var line in rows)
        {
            _resultCards.Children.Add(BuildReferenceCard(line));
        }

        return true;
    }

    private bool TryRenderDiff(IReadOnlyList<string> lines)
    {
        if (!lines.Any(line => line.StartsWith("+ ", StringComparison.Ordinal) || line.StartsWith("- ", StringComparison.Ordinal)))
        {
            return false;
        }

        var added = lines.Count(line => line.StartsWith("+ ", StringComparison.Ordinal));
        var removed = lines.Count(line => line.StartsWith("- ", StringComparison.Ordinal));
        _resultCards.Children.Add(BuildInfoGrid([("新增", added.ToString()), ("删除", removed.ToString()), ("总行数", lines.Count.ToString())]));
        foreach (var line in lines.Take(80))
        {
            var kind = line.StartsWith("+ ", StringComparison.Ordinal)
                ? "新增"
                : line.StartsWith("- ", StringComparison.Ordinal)
                    ? "删除"
                    : "相同";
            var color = kind == "新增" ? ModernUi.Success : kind == "删除" ? ModernUi.Danger : ModernUi.TextSecondary;
            _resultCards.Children.Add(BuildBadgeLineCard(kind, line, color));
        }

        return true;
    }

    private bool TryRenderStatusRows(IReadOnlyList<string> lines)
    {
        var rows = lines.Where(line => line.StartsWith("OK  ", StringComparison.Ordinal) || line.StartsWith("MISMATCH  ", StringComparison.Ordinal)).Take(80).ToList();
        if (rows.Count == 0)
        {
            return false;
        }

        _resultCards.Children.Add(BuildInfoGrid([
            ("通过", rows.Count(line => line.StartsWith("OK", StringComparison.Ordinal)).ToString()),
            ("不匹配", rows.Count(line => line.StartsWith("MISMATCH", StringComparison.Ordinal)).ToString())
        ]));
        foreach (var row in rows)
        {
            var ok = row.StartsWith("OK", StringComparison.Ordinal);
            _resultCards.Children.Add(BuildBadgeLineCard(ok ? "OK" : "异常", row, ok ? ModernUi.Success : ModernUi.Danger));
        }

        return true;
    }

    private bool TryRenderArchiveRows(IReadOnlyList<string> lines)
    {
        var rows = lines
            .Select(line => line.Split('\t'))
            .Where(parts => parts.Length == 2 && parts[1].Contains("bytes", StringComparison.OrdinalIgnoreCase))
            .Take(80)
            .ToList();
        if (rows.Count == 0)
        {
            return TryRenderFileOutput(lines);
        }

        _resultCards.Children.Add(BuildInfoGrid([("条目数", rows.Count.ToString()), ("类型", "归档内容")]));
        foreach (var parts in rows)
        {
            _resultCards.Children.Add(BuildRecordCard("FILE", parts[0], parts[1], "归档条目"));
        }

        return true;
    }

    private bool TryRenderFileOutput(IReadOnlyList<string> lines)
    {
        var pathLines = lines.Select(ExtractLocalPath).Where(path => !string.IsNullOrWhiteSpace(path)).Cast<string>().Distinct(StringComparer.OrdinalIgnoreCase).ToList();
        if (pathLines.Count == 0)
        {
            return false;
        }

        foreach (var path in pathLines.Take(12))
        {
            _resultCards.Children.Add(BuildFileCard(path));
        }

        return true;
    }

    private bool TryRenderMarkdownTable(IReadOnlyList<string> lines)
    {
        var tableRows = lines
            .Where(line => line.TrimStart().StartsWith('|'))
            .Select(ParseMarkdownCells)
            .Where(cells => cells.Count > 0 && !cells.All(cell => Regex.IsMatch(cell, "^:?-{3,}:?$")))
            .Take(20)
            .ToList();
        if (tableRows.Count < 2)
        {
            return false;
        }

        _resultCards.Children.Add(BuildSimpleTableCard("表格预览", tableRows));
        return true;
    }

    private bool TryRenderKeyValueSections(IReadOnlyList<string> lines, string title)
    {
        var rows = lines
            .Select(ParseKeyValue)
            .Where(pair => pair is not null)
            .Select(pair => pair!.Value)
            .Take(24)
            .ToList();
        if (rows.Count == 0)
        {
            return false;
        }

        _resultCards.Children.Add(ModernUi.Text(title, 13, FontWeights.SemiBold, ModernUi.TextSecondary));
        _resultCards.Children.Add(BuildInfoGrid(rows));
        return true;
    }

    private bool TryRenderCodeLikeOutput(IToolModule module, string output, IReadOnlyList<string> lines)
    {
        if (string.IsNullOrWhiteSpace(output))
        {
            return false;
        }

        _resultCards.Children.Add(BuildInfoGrid([
            ("输出类型", module.Metadata.Name),
            ("行数", lines.Count.ToString()),
            ("字符数", output.Length.ToString())
        ]));
        _resultCards.Children.Add(BuildCodePreviewCard("代码 / 文本预览", output));
        return true;
    }

    private bool TryRenderTextRows(IToolModule module, IReadOnlyList<string> lines)
    {
        if (lines.Count == 0)
        {
            return false;
        }

        if (module.Id is "qr_generator" && lines.FirstOrDefault()?.Contains("<svg", StringComparison.OrdinalIgnoreCase) == true)
        {
            _resultCards.Children.Add(BuildInfoGrid([("格式", "SVG"), ("用途", "二维码"), ("大小", $"{string.Join(Environment.NewLine, lines).Length} 字符")]));
            _resultCards.Children.Add(BuildCodePreviewCard("SVG 输出", string.Join(Environment.NewLine, lines)));
            return true;
        }

        if (lines.Count >= 2)
        {
            _resultCards.Children.Add(BuildInfoGrid([
                ("行数", lines.Count.ToString()),
                ("首行长度", lines[0].Length.ToString()),
                ("输出类型", module.Metadata.Category == ToolCategory.Text ? "文本处理" : "开发工具")
            ]));
        }

        foreach (var line in lines.Take(module.Metadata.Category == ToolCategory.Text ? 40 : 20))
        {
            _resultCards.Children.Add(BuildLineResultCard(line));
        }

        return true;
    }

    private bool TryRenderColor(string output)
    {
        var hex = Regex.Match(output, @"HEX:\s*(#[0-9A-Fa-f]{6})").Groups[1].Value;
        if (string.IsNullOrWhiteSpace(hex))
        {
            return false;
        }

        var swatch = new Border
        {
            Width = 72,
            Height = 72,
            CornerRadius = new CornerRadius(10),
            Background = ModernUi.Brush(hex),
            BorderBrush = ModernUi.Stroke,
            BorderThickness = new Thickness(1)
        };
        var rows = output.Replace("\r\n", "\n")
            .Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
            .Select(ParseKeyValue)
            .Where(pair => pair is not null)
            .Select(pair => pair!.Value)
            .ToList();
        var panel = new Grid { ColumnSpacing = 16 };
        panel.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        panel.ColumnDefinitions.Add(new ColumnDefinition());
        panel.Children.Add(swatch);
        var info = BuildInfoGrid(rows);
        Grid.SetColumn(info, 1);
        panel.Children.Add(info);
        _resultCards.Children.Add(ModernUi.Card(panel, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt));
        return true;
    }

    private static Border BuildEmptyResultCard()
    {
        return ModernUi.Card(new StackPanel
        {
            Spacing = 8,
            HorizontalAlignment = HorizontalAlignment.Center,
            Children =
            {
                ModernUi.IconTile("\uE9CE", 46, ModernUi.SurfaceAlt, ModernUi.TextSecondary, 20),
                ModernUi.Text("暂无结果", 14, FontWeights.SemiBold, ModernUi.TextSecondary)
            }
        }, new Thickness(18), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static Border BuildJsonPreviewCard(string title, JsonElement element)
    {
        var summary = element.ValueKind == JsonValueKind.Object
            ? string.Join("  ", element.EnumerateObject().Take(4).Select(property => $"{property.Name}: {JsonPreviewValue(property.Value)}"))
            : JsonPreviewValue(element);
        return BuildRecordCard("JSON", title, summary, element.ValueKind.ToString());
    }

    private static Border BuildJsonPropertyCard(string key, JsonElement value)
    {
        return BuildRecordCard(value.ValueKind.ToString().ToUpperInvariant(), key, JsonPreviewValue(value), "JSON 字段");
    }

    private static string JsonPreviewValue(JsonElement value)
    {
        return value.ValueKind switch
        {
            JsonValueKind.String => value.GetString() ?? string.Empty,
            JsonValueKind.Number => value.GetRawText(),
            JsonValueKind.True => "true",
            JsonValueKind.False => "false",
            JsonValueKind.Array => $"Array[{value.GetArrayLength()}]",
            JsonValueKind.Object => $"Object{{{value.EnumerateObject().Count()}}}",
            JsonValueKind.Null => "null",
            _ => value.GetRawText()
        };
    }

    private static Border BuildCodePreviewCard(string title, string code)
    {
        return ModernUi.Card(new StackPanel
        {
            Spacing = 8,
            Children =
            {
                ModernUi.Text(title, 13, FontWeights.SemiBold, ModernUi.TextSecondary),
                new TextBox
                {
                    Text = code.Length > 5000 ? code[..5000] + Environment.NewLine + "...(truncated)" : code,
                    AcceptsReturn = true,
                    IsReadOnly = true,
                    TextWrapping = TextWrapping.NoWrap,
                    MinHeight = 120,
                    MaxHeight = 260,
                    FontFamily = new FontFamily("Cascadia Mono")
                }
            }
        }, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static Border BuildRecordCard(string badge, string title, string value, string meta)
    {
        var row = new Grid { ColumnSpacing = 12 };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.Children.Add(ModernUi.SmallBadge(ModernUi.Ellipsize(badge, 12), ModernUi.Accent, ModernUi.AccentSoft));
        var text = new StackPanel
        {
            Spacing = 3,
            Children =
            {
                ModernUi.Text(ModernUi.Ellipsize(title, 120), 14, FontWeights.SemiBold, maxLines: 2),
                ModernUi.Text(ModernUi.Ellipsize(value, 220), 13, foreground: ModernUi.TextSecondary, maxLines: 3)
            }
        };
        if (!string.IsNullOrWhiteSpace(meta))
        {
            text.Children.Add(ModernUi.Text(meta, 12, foreground: ModernUi.TextSecondary, maxLines: 1));
        }

        Grid.SetColumn(text, 1);
        row.Children.Add(text);
        return ModernUi.Card(row, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static Border BuildReferenceCard(string line)
    {
        var badge = "REF";
        var title = line;
        var value = string.Empty;
        var meta = string.Empty;

        var dash = line.Split(" - ", 2, StringSplitOptions.TrimEntries);
        if (dash.Length == 2)
        {
            badge = dash[0];
            title = dash[1];
        }

        var aliases = title.Split(" / aliases: ", 2, StringSplitOptions.TrimEntries);
        if (aliases.Length == 2)
        {
            title = aliases[0];
            meta = $"aliases: {aliases[1]}";
        }

        var colon = title.Split(':', 2, StringSplitOptions.TrimEntries);
        if (colon.Length == 2)
        {
            title = colon[0];
            value = colon[1];
        }

        return BuildRecordCard(badge, title, string.IsNullOrWhiteSpace(value) ? line : value, meta);
    }

    private static Border BuildBadgeLineCard(string badge, string line, Brush foreground)
    {
        var row = new Grid { ColumnSpacing = 12 };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.Children.Add(ModernUi.SmallBadge(badge, foreground, ModernUi.Surface));
        var text = ModernUi.Text(line, 13, foreground: ModernUi.TextSecondary, maxLines: 3);
        Grid.SetColumn(text, 1);
        row.Children.Add(text);
        return ModernUi.Card(row, new Thickness(10), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static Border BuildFileCard(string path)
    {
        var row = new Grid { ColumnSpacing = 12 };
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.ColumnDefinitions.Add(new ColumnDefinition());
        row.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        row.Children.Add(ModernUi.IconTile("\uE8A5", 36, ModernUi.AccentSoft, ModernUi.Accent, 16));
        var info = new FileInfo(path);
        var text = new StackPanel
        {
            Spacing = 2,
            Children =
            {
                ModernUi.Text(info.Name, 14, FontWeights.SemiBold, maxLines: 1),
                ModernUi.Text($"{info.DirectoryName} · {info.Length / 1024d:0.#} KB", 12, foreground: ModernUi.TextSecondary, maxLines: 1)
            }
        };
        Grid.SetColumn(text, 1);
        row.Children.Add(text);
        var open = ModernUi.IconButton("\uE838", "打开所在位置", async () => await Windows.System.Launcher.LaunchFolderPathAsync(info.DirectoryName!));
        Grid.SetColumn(open, 2);
        row.Children.Add(open);
        return ModernUi.Card(row, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static Border BuildSimpleTableCard(string title, IReadOnlyList<IReadOnlyList<string>> rows)
    {
        var grid = new Grid { RowSpacing = 0 };
        var columnCount = Math.Min(6, rows.Max(row => row.Count));
        for (var column = 0; column < columnCount; column++)
        {
            grid.ColumnDefinitions.Add(new ColumnDefinition());
        }

        for (var rowIndex = 0; rowIndex < rows.Count; rowIndex++)
        {
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            for (var column = 0; column < columnCount; column++)
            {
                var cell = new Border
                {
                    Padding = new Thickness(8, 6, 8, 6),
                    BorderBrush = ModernUi.Stroke,
                    BorderThickness = new Thickness(0, 0, 1, 1),
                    Background = rowIndex == 0 ? ModernUi.SurfaceAlt : ModernUi.Surface,
                    Child = ModernUi.Text(rows[rowIndex].ElementAtOrDefault(column) ?? string.Empty, 12, rowIndex == 0 ? FontWeights.SemiBold : FontWeights.Normal, maxLines: 2)
                };
                Grid.SetRow(cell, rowIndex);
                Grid.SetColumn(cell, column);
                grid.Children.Add(cell);
            }
        }

        return ModernUi.Card(new StackPanel
        {
            Spacing = 10,
            Children =
            {
                ModernUi.Text(title, 13, FontWeights.SemiBold, ModernUi.TextSecondary),
                grid
            }
        }, new Thickness(12), radius: 8, background: ModernUi.SurfaceAlt);
    }

    private static IReadOnlyList<string> ParseMarkdownCells(string line)
    {
        var trimmed = line.Trim().Trim('|');
        return trimmed.Split('|', StringSplitOptions.TrimEntries).ToList();
    }

    private static string ResultGroupTitle(IToolModule module)
    {
        return module.Metadata.Category switch
        {
            ToolCategory.Calculator => "计算摘要",
            ToolCategory.System => "系统摘要",
            ToolCategory.Life => "生活工具结果",
            ToolCategory.Security => "安全校验结果",
            _ => "结果摘要"
        };
    }
}
