using System.Text;
using System.Text.RegularExpressions;
using GerbilManagerWebAPI.Ai;
using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.SaleAd;
using Microsoft.Extensions.Options;

namespace GerbilManagerWebAPI.Inbox
{
    /// <summary>
    /// INBOX-2: AI reply DRAFT for an incoming inquiry (human-in-the-loop — the
    /// breeder edits and sends herself, NEVER auto-send; send is INBOX-3).
    ///
    /// PRIVACY / data minimization (INBOX-architecture.md §privacy): the prompt
    /// carries ONLY the inquiry's own text (signatures/quoted history stripped),
    /// the sender's display name for the greeting, a short German context, and
    /// optionally the current ForSale animals (name + Farbschlag). NOT the
    /// contact DB, NOT other requests, NOT any addresses.
    /// </summary>
    public sealed class DraftReplyService(HttpClient http, IOptions<AiOptions> options)
    {
        private readonly OpenAiChatClient _client = new(http, options);

        public sealed record ForSaleAnimal(string Name, string? Farbschlag);

        public Task<AiCallResult> DraftAsync(
            Request request, IReadOnlyList<ForSaleAnimal> forSale, CancellationToken ct = default)
            => _client.CompleteAsync(BuildSystemPrompt(), BuildUserPrompt(request, forSale), ct);

        internal static string BuildSystemPrompt() => """
            Du hilfst einer Hobby-Rennmaus-Züchterin („Zucht der kleinen Chaoten“), eine
            freundliche deutsche Antwort auf eine Anfrage zu ENTWERFEN. Sie liest den
            Entwurf, passt ihn an und versendet selbst.

            Regeln:
            - Ton: warm, persönlich, hilfsbereit — wie eine erfahrene Hobby-Züchterin,
              nicht wie ein Unternehmen. Anrede per „du“, Gruß mit dem Namen der
              anfragenden Person, falls bekannt.
            - KEINE Fakten erfinden: Verfügbarkeit, Tiere und Eigenschaften NUR aus den
              mitgelieferten Daten. Ist keine Abgabetier-Liste mitgeliefert oder passt
              nichts, verweise freundlich darauf, dass sie aktuelle Infos persönlich gibt.
            - Keine Preise/Schutzgebühren nennen und keine Adressen oder sonstige
              persönliche Daten — solche Details klärt sie selbst im Gespräch.
            - Gib NUR den Antworttext aus (ohne Betreff, ohne Erklärungen) und beende
              mit einem herzlichen Gruß ohne Namens-Signatur.
            """;

        internal static string BuildUserPrompt(Request request, IReadOnlyList<ForSaleAnimal> forSale)
        {
            var sb = new StringBuilder();
            sb.AppendLine("Entwirf eine Antwort auf folgende Anfrage:");
            sb.AppendLine();
            if (!string.IsNullOrWhiteSpace(request.FromName))
                sb.AppendLine($"Von: {request.FromName}");
            if (!string.IsNullOrWhiteSpace(request.Subject))
                sb.AppendLine($"Betreff: {request.Subject}");
            sb.AppendLine();
            sb.AppendLine("Anfrage-Text:");
            sb.AppendLine(StripQuotedText(request.BodyText ?? ""));
            if (forSale.Count > 0)
            {
                sb.AppendLine();
                sb.AppendLine("Aktuell abzugebende Tiere (einzige zulässige Quelle für Verfügbarkeits-Aussagen):");
                foreach (var a in forSale)
                {
                    sb.AppendLine(string.IsNullOrWhiteSpace(a.Farbschlag)
                        ? $"- {a.Name}"
                        : $"- {a.Name} ({a.Farbschlag})");
                }
            }
            return sb.ToString();
        }

        // ── Signatur-/Zitat-Stripping (best effort, bewusst konservativ) ────

        private static readonly Regex QuoteIntro = new(
            @"^Am .+ schrieb .+:\s*$", RegexOptions.Compiled);

        private static readonly Regex OutlookHeader = new(
            @"^(Von|Gesendet|An|Betreff):\s", RegexOptions.Compiled);

        /// <summary>
        /// Drops quoted history ('&gt;'-lines, the German Gmail "Am … schrieb …:"
        /// intro, Outlook-style forwarded headers) and everything below a signature
        /// delimiter ("-- "). Keeps the sender's own words untouched.
        /// </summary>
        internal static string StripQuotedText(string body)
        {
            var lines = body.Replace("\r\n", "\n").Split('\n');
            var kept = new List<string>();
            foreach (var line in lines)
            {
                var trimmed = line.TrimEnd();
                if (trimmed == "--" || trimmed == "-- ")
                    break; // signature delimiter: everything below is signature
                if (QuoteIntro.IsMatch(trimmed))
                    break; // quoted history follows
                if (trimmed.StartsWith('>'))
                    continue;
                if (OutlookHeader.IsMatch(trimmed))
                    continue;
                kept.Add(line);
            }
            // collapse the whitespace the stripping may have left behind
            return string.Join("\n", kept).Trim();
        }
    }
}
