using Microsoft.Web.WebView2.Core;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;

namespace ReFoneFactureOS;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += async (_, _) => await StartAsync();
    }

    private async Task StartAsync()
    {
        try
        {
            await Browser.EnsureCoreWebView2Async();
            string? indexPath = ResolveIndexPath();

            if (indexPath is null)
            {
                Browser.NavigateToString(BuildErrorPage("Impossible de trouver WEB/index.html a cote du projet FactureOS."));
                return;
            }

            Browser.CoreWebView2.Settings.IsStatusBarEnabled = false;
            Browser.CoreWebView2.WebMessageReceived += HandleWebMessageReceived;
            Browser.Source = new Uri(indexPath);
        }
        catch (Exception ex)
        {
            Browser.NavigateToString(BuildErrorPage(ex.Message));
        }
    }

    private static string? ResolveIndexPath()
    {
        string current = AppContext.BaseDirectory;

        for (int level = 0; level < 8; level++)
        {
            string candidate = Path.Combine(current, "WEB", "index.html");
            if (File.Exists(candidate))
            {
                return new Uri(candidate).AbsoluteUri;
            }

            DirectoryInfo? parent = Directory.GetParent(current);
            if (parent is null)
            {
                break;
            }

            current = parent.FullName;
        }

        return null;
    }

    private static void HandleWebMessageReceived(object? sender, CoreWebView2WebMessageReceivedEventArgs eventArgs)
    {
        try
        {
            using JsonDocument document = JsonDocument.Parse(eventArgs.WebMessageAsJson);
            JsonElement root = document.RootElement;
            if (!root.TryGetProperty("type", out JsonElement typeElement) ||
                typeElement.GetString() != "refone-download" ||
                !root.TryGetProperty("filename", out JsonElement filenameElement) ||
                !root.TryGetProperty("dataUrl", out JsonElement dataUrlElement))
            {
                return;
            }

            string filename = SanitizeFilename(filenameElement.GetString() ?? "factureos.pdf");
            string dataUrl = dataUrlElement.GetString() ?? "";
            int commaIndex = dataUrl.IndexOf(',');
            if (commaIndex < 0)
            {
                return;
            }

            byte[] bytes = Convert.FromBase64String(dataUrl[(commaIndex + 1)..]);
            string downloadsPath = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
                "Downloads");
            Directory.CreateDirectory(downloadsPath);

            string destinationPath = UniqueFilePath(downloadsPath, filename);
            File.WriteAllBytes(destinationPath, bytes);

            try
            {
                Process.Start("explorer.exe", $"/select,\"{destinationPath}\"");
            }
            catch
            {
            }
        }
        catch
        {
        }
    }

    private static string SanitizeFilename(string rawValue)
    {
        string filename = string.Join("-", rawValue.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).Trim();
        return string.IsNullOrWhiteSpace(filename) ? "factureos.pdf" : filename;
    }

    private static string UniqueFilePath(string directory, string filename)
    {
        string path = Path.Combine(directory, filename);
        if (!File.Exists(path))
        {
            return path;
        }

        string name = Path.GetFileNameWithoutExtension(filename);
        string extension = Path.GetExtension(filename);
        for (int index = 2; index <= 999; index++)
        {
            string candidate = Path.Combine(directory, $"{name}-{index}{extension}");
            if (!File.Exists(candidate))
            {
                return candidate;
            }
        }

        return Path.Combine(directory, $"factureos-{DateTimeOffset.Now.ToUnixTimeSeconds()}.pdf");
    }

    private static string BuildErrorPage(string message)
    {
        return $"""
        <!DOCTYPE html>
        <html lang="fr">
        <head>
          <meta charset="utf-8">
          <title>ReFone FactureOS</title>
          <style>
            body {{
              margin: 0;
              min-height: 100vh;
              display: grid;
              place-items: center;
              background: radial-gradient(circle at top left, rgba(61,124,255,.22), transparent 35%), #070b16;
              color: white;
              font-family: "Segoe UI", sans-serif;
            }}
            article {{
              width: min(560px, calc(100vw - 48px));
              padding: 28px;
              border-radius: 28px;
              background: rgba(255,255,255,.06);
              border: 1px solid rgba(255,255,255,.08);
              box-shadow: 0 24px 60px rgba(0,0,0,.28);
            }}
            h1 {{ margin: 0 0 10px; font-size: 32px; }}
            p {{ margin: 0; line-height: 1.65; color: rgba(255,255,255,.74); }}
          </style>
        </head>
        <body>
          <article>
            <h1>FactureOS introuvable</h1>
            <p>{System.Net.WebUtility.HtmlEncode(message)}</p>
          </article>
        </body>
        </html>
        """;
    }
}
