using System.Text.Json.Nodes;
using Nalu.Web.Models;

namespace Nalu.Web.Services;

public class SuggestionBuilder
{
    private static readonly Dictionary<string, string> GreetingMap = new(StringComparer.OrdinalIgnoreCase)
    {
        { "bom dia", "Bom dia!" },
        { "boa tarde", "Boa tarde!" },
        { "boa noite", "Boa noite!" },
        { "olá", "Olá!" },
        { "ola", "Olá!" },
        { "oi", "Oi!" },
        { "eae", "Oi!" },
        { "e aí", "Oi!" },
        { "fala", "Oi!" },
        { "opa", "Oi!" }
    };

    public string? Build(
        ValidatorDefinition validator,
        ExtractionRequest request,
        string? extractedValue,
        bool obtained,
        bool certain,
        bool wasInvalidated = false,
        bool wasCorrected = false,
        string? originalValue = null,
        string? suggestionKeyOverride = null)
    {
        var templateKey = suggestionKeyOverride
            ?? SelectTemplateKey(request.UserInput, obtained, certain, wasInvalidated, wasCorrected);

        var template = GetTemplate(validator, templateKey, request.Language);
        if (string.IsNullOrWhiteSpace(template)) return null;

        return ExpandPlaceholders(template, extractedValue, request.UserInput, originalValue);
    }

    private static string? GetTemplate(ValidatorDefinition validator, string key, string language)
    {
        // Try language-specific first
        if (validator.LocalizedSuggestions.TryGetValue(language, out var localized)
            && localized.TryGetValue(key, out var localizedText))
            return localizedText;

        // Fall back to flat suggestions
        return validator.Suggestions.TryGetValue(key, out var flat) ? flat : null;
    }

    private static string SelectTemplateKey(
        string userInput, bool obtained, bool certain, bool wasInvalidated, bool wasCorrected)
    {
        if (!obtained)
        {
            if (wasInvalidated) return "when_invalid";
            return IsGreeting(userInput) ? "when_null_greeting" : "when_null_evasive";
        }

        if (!certain)
        {
            if (wasCorrected) return "when_corrected";
            return "when_uncertain";
        }

        return "when_certain";
    }

    private static string ExpandPlaceholders(
        string template, string? extractedValue, string userInput, string? originalValue)
    {
        var greeting = DetectGreetingResponse(userInput);

        var result = template
            .Replace("{{extracted_value}}", extractedValue ?? "")
            .Replace("{{greeting_response}}", greeting)
            .Replace("{{original}}", originalValue ?? "");

        // JSON field expansion — for enriched values like CEP address
        if (extractedValue?.TrimStart().StartsWith('{') == true)
        {
            try
            {
                var obj = JsonNode.Parse(extractedValue)?.AsObject();
                if (obj != null)
                {
                    foreach (var prop in obj)
                        result = result.Replace($"{{{{{prop.Key}}}}}", prop.Value?.GetValue<string>() ?? "");
                }
            }
            catch { /* non-JSON, skip */ }
        }

        return result;
    }

    private static bool IsGreeting(string userInput)
    {
        var normalized = userInput.Trim().ToLowerInvariant().TrimEnd('.', '!', '?', ',');
        return GreetingMap.Keys.Any(g =>
            normalized == g
            || normalized.StartsWith(g + " ", StringComparison.Ordinal)
            || normalized.StartsWith(g + ",", StringComparison.Ordinal)
            || normalized.StartsWith(g + "!", StringComparison.Ordinal));
    }

    private static string DetectGreetingResponse(string userInput)
    {
        var normalized = userInput.Trim().ToLowerInvariant();
        foreach (var (key, response) in GreetingMap)
        {
            if (normalized.StartsWith(key, StringComparison.Ordinal))
                return response;
        }
        return "";
    }
}
