using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Web.WebView2.Core;
using Windows.ApplicationModel.DataTransfer;
using Windows.System;
using YMhut.Box.Core.Settings;
using YMhut.Box.Core.Tools;

namespace YMhut.Box.WinUI.Services;

public sealed class ToolResultWebBridge(
    IToolResultExperienceCatalog experienceCatalog,
    ISettingsService settingsService,
    IToolLinkNavigationService linkNavigationService)
{
    private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
    {
        WriteIndented = false
    };

    static ToolResultWebBridge()
    {
        JsonOptions.Converters.Add(new JsonStringEnumConverter());
    }

    public ToolResultWebPayload CreatePayload(
        IToolModule module,
        ToolResultDocument document,
        long durationMs,
        bool cached = false,
        string source = "tool-run")
    {
        var experience = experienceCatalog.GetRequired(module.Id);
        return new ToolResultWebPayload(
            module.Id,
            ToolText.Name(module),
            document,
            experience.ExperienceId,
            settingsService.Current.Theme,
            settingsService.Current.Language,
            new ToolResultPrivacyPolicy(ToolResultPrivacySanitizer.DefaultRedactedHostHints),
            new ToolResultRuntimeMetadata(
                durationMs,
                DateTimeOffset.Now,
                cached,
                source,
                new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    ["category"] = module.Metadata.Category.ToString(),
                    ["offline"] = module.Metadata.OfflineCapable.ToString(),
                    ["icon"] = module.Metadata.IconGlyph
                }),
            experience);
    }

    public string Serialize(ToolResultWebPayload payload)
        => JsonSerializer.Serialize(payload, JsonOptions);

    public async Task HandleMessageAsync(CoreWebView2WebMessageReceivedEventArgs args)
    {
        using var message = JsonDocument.Parse(args.WebMessageAsJson);
        var root = message.RootElement;
        var action = root.TryGetProperty("action", out var actionElement) ? actionElement.GetString() : string.Empty;
        var value = root.TryGetProperty("value", out var valueElement) ? valueElement.GetString() : string.Empty;

        switch (action)
        {
            case "copy":
                CopyText(ToolResultPrivacySanitizer.Redact(value, settingsService.Current.Language));
                ToastService.Show(AppLocalizer.T("已复制", "Copied"), ToastKind.Success);
                break;
            case "openFile":
                if (!string.IsNullOrWhiteSpace(value))
                {
                    await Launcher.LaunchFileAsync(await Windows.Storage.StorageFile.GetFileFromPathAsync(value));
                }
                break;
            case "openFolder":
                if (!string.IsNullOrWhiteSpace(value))
                {
                    var folder = Directory.Exists(value) ? value : Path.GetDirectoryName(value);
                    if (!string.IsNullOrWhiteSpace(folder))
                    {
                        await Launcher.LaunchFolderPathAsync(folder);
                    }
                }
                break;
            case "openLink":
                await linkNavigationService.OpenAsync(value);
                break;
            case "openSystemBrowser":
                await linkNavigationService.OpenAsync(value, ToolLinkTarget.SystemBrowser);
                break;
        }
    }

    private static void CopyText(string text)
    {
        var data = new DataPackage();
        data.SetText(text);
        Clipboard.SetContent(data);
    }
}
