using Meezi.Core.Utilities;

namespace Meezi.API.Services;

/// <summary>
/// Parses a free-text Persian (or mixed) query into structured discover filter hints.
/// The results are merged into <see cref="DiscoverFilterParams"/> before matching,
/// so the AI text box silently pre-populates filters without the user having to pick chips.
/// </summary>
public static class DiscoverNlpParser
{
    public record NlpHints(
        IReadOnlyList<string> Themes,
        IReadOnlyList<string> Vibes,
        IReadOnlyList<string> Occasions,
        IReadOnlyList<string> SpaceFeatures,
        string? NoiseLevel,
        string? PriceTier,
        string? Size);

    public static NlpHints Parse(string rawQuery)
    {
        if (string.IsNullOrWhiteSpace(rawQuery))
            return new NlpHints([], [], [], [], null, null, null);

        // Normalize: lower-case + Arabic glyph unification
        var q = PersianSearchNormalizer.Normalize(rawQuery.ToLowerInvariant());

        var themes        = new HashSet<string>();
        var vibes         = new HashSet<string>();
        var occasions     = new HashSet<string>();
        var spaceFeatures = new HashSet<string>();
        string? noise     = null;
        string? price     = null;
        string? size      = null;

        // ── Themes ──────────────────────────────────────────────────────────
        if (Any(q, "کتاب", "کتابخانه", "book cafe", "book"))
            themes.Add("book_cafe");

        if (Any(q, "قهوه تخصصی", "رست", "اسپشلتی", "specialty", "singl origin", "سینگل اوریجین"))
            themes.Add("specialty_coffee");

        if (Any(q, "چایی", "چای", "tea house", "tea"))
            themes.Add("tea_house");

        if (Any(q, "گالری", "هنر", "نقاشی", "art gallery", "art"))
            themes.Add("art_gallery");

        if (Any(q, "ورزشی", "sport", "بازی", "game"))
            themes.Add("sport_cafe");

        if (Any(q, "گیمینگ", "gaming", "گیم"))
            themes.Add("gaming_cafe");

        if (Any(q, "سنتی", "قدیمی", "ایرانی", "اصیل", "persian", "ایران"))
            themes.Add("persian_traditional");

        if (Any(q, "رترو", "vintage", "کلاسیک"))
            themes.Add("vintage");

        if (Any(q, "مدرن", "شیک", "مینیمال", "modern", "minimal"))
            themes.Add("modern");

        if (Any(q, "صبحانه", "برانچ", "brunch"))
            themes.Add("brunch");

        if (Any(q, "شب", "دیروقت", "late night", "شبانه"))
            themes.Add("late_night");

        if (Any(q, "گیاه", "طبیعت", "سبز", "plants", "گلخانه"))
            themes.Add("plants_heavy");

        if (Any(q, "اینستا", "دکور", "عکس", "فتوگنیک", "insta"))
            themes.Add("instagrammable");

        if (Any(q, "کافه رستوران", "رستوران", "رستو"))
            themes.Add("brunch");

        // ── Vibes ────────────────────────────────────────────────────────────
        if (Any(q, "ارام", "ساکت", "بی سر و صدا", "آروم", "quiet"))
        {
            vibes.Add("quiet");
            noise ??= "quiet";
        }

        if (Any(q, "رمانتیک", "عاشقانه", "دوتایی", "romantic"))
            vibes.Add("romantic");

        if (Any(q, "دنج", "صمیمی", "گرم", "cozy", "کوزی"))
            vibes.Add("cozy");

        if (Any(q, "هنری", "خلاق", "artistic"))
            vibes.Add("artistic");

        if (Any(q, "شلوغ", "شاد", "پر انرژی", "lively"))
        {
            vibes.Add("lively");
            noise ??= "lively";
        }

        if (Any(q, "درس", "مطالعه", "کار", "لپتاپ", "study"))
            vibes.Add("study_friendly");

        if (Any(q, "لوکس", "لاکچری", "لوکژری", "luxury"))
            vibes.Add("luxury");

        if (Any(q, "ترند", "مد", "تازه", "trendy"))
            vibes.Add("trendy");

        // ── Occasions ────────────────────────────────────────────────────────
        if (Any(q, "قرار", "دیت", "دوتایی", "date"))
            occasions.Add("date");

        if (Any(q, "خانواده", "بچه", "کودک", "family"))
            occasions.Add("family");

        if (Any(q, "دوستانه", "دوستا", "جمعی", "friends", "گروهی"))
            occasions.Add("friends");

        if (Any(q, "مطالعه", "درس خوندن", "کار کردن", "study", "لپتاپ"))
            occasions.Add("study_work");

        if (Any(q, "جلسه", "بیزنس", "کاری", "business meeting", "میتینگ"))
            occasions.Add("business_meeting");

        if (Any(q, "صبحانه", "breakfast"))
            occasions.Add("breakfast");

        if (Any(q, "برانچ", "brunch"))
            occasions.Add("brunch");

        if (Any(q, "تولد", "جشن", "celebration", "مهمونی"))
            occasions.Add("celebration");

        if (Any(q, "تنها", "solo", "تک نفره", "یه نفره"))
            occasions.Add("solo");

        if (Any(q, "بعد شام", "after dinner", "شام"))
            occasions.Add("after_dinner");

        if (Any(q, "گروه بزرگ", "خیلی ها", "group", "گروه زیاد"))
            occasions.Add("group_large");

        if (Any(q, "آشنایی", "دوست پیدا", "finding someone"))
            occasions.Add("finding_someone");

        if (Any(q, "سریع", "quick", "یه قهوه سریع"))
            occasions.Add("quick_coffee");

        // ── Space Features ───────────────────────────────────────────────────
        if (Any(q, "وایفای", "وای فای", "wifi", "اینترنت"))
            spaceFeatures.Add("wifi");

        if (Any(q, "پارکینگ", "parking"))
            spaceFeatures.Add("parking");

        if (Any(q, "فضای باز", "بیرون", "خارج از ساختمان", "outdoor"))
            spaceFeatures.Add("outdoor");

        if (Any(q, "تراس", "terrace"))
            spaceFeatures.Add("terrace");

        if (Any(q, "روفتاپ", "روف تاپ", "بام", "rooftop", "پشت بام"))
            spaceFeatures.Add("rooftop");

        if (Any(q, "باغ", "گاردن", "garden"))
            spaceFeatures.Add("garden");

        if (Any(q, "سگ", "گربه", "حیوان خانگی", "pet", "پت فرندلی"))
            spaceFeatures.Add("pet_friendly");

        if (Any(q, "کودک", "بچه دار", "kids friendly", "بازی بچه"))
            spaceFeatures.Add("kids_friendly");

        if (Any(q, "موسیقی زنده", "live music", "کنسرت کوچک"))
            spaceFeatures.Add("live_music");

        if (Any(q, "اتاق خصوصی", "خصوصی", "private room"))
            spaceFeatures.Add("private_room");

        if (Any(q, "قلیان", "hookah", "نارگیله"))
            spaceFeatures.Add("hookah");

        if (Any(q, "بازی رومیزی", "بازی فکری", "board game"))
            spaceFeatures.Add("board_games");

        if (Any(q, "بدون دود", "سیگار ممنوع", "non smoking", "no smoking", "دود نه"))
            spaceFeatures.Add("no_smoking");

        if (Any(q, "نمازخانه", "نماز", "prayer"))
            spaceFeatures.Add("prayer_room");

        if (Any(q, "بیرون بر", "تیک اوی", "takeaway", "تیک اوت"))
            spaceFeatures.Add("takeaway");

        if (Any(q, "ویلچر", "معلول", "دسترسی", "wheelchair"))
            spaceFeatures.Add("wheelchair");

        // ── Price ────────────────────────────────────────────────────────────
        if (Any(q, "ارزون", "ارزان", "مقرون به صرفه", "budget", "اقتصادی", "کم هزینه"))
            price = "budget";
        else if (Any(q, "لوکس", "گرون", "لاکچری", "premium", "پریمیوم", "گران قیمت"))
            price = "premium";

        // ── Size ─────────────────────────────────────────────────────────────
        if (Any(q, "کوچیک", "کوچک", "tiny", "کوچولو", "مینی"))
            size = "tiny";
        else if (Any(q, "دنج", "cozy", "صمیمی") && size is null)
            size = "cozy";
        else if (Any(q, "بزرگ", "وسیع", "large", "spacious", "گنجایش بالا"))
            size = "large";

        return new NlpHints(
            [.. themes],
            [.. vibes],
            [.. occasions],
            [.. spaceFeatures],
            noise,
            price,
            size);
    }

    // ── helpers ──────────────────────────────────────────────────────────────

    private static bool Any(string q, params string[] terms) =>
        terms.Any(q.Contains);
}
