<?php

namespace App\Services;

use App\Models\Recipe;
use OpenAI\Laravel\Facades\OpenAI;
use GuzzleHttp\Client as HttpClient;
use GuzzleHttp\Promise\Utils;

class RecipeService
{
    private ?string $language = null;

    public $produitsWarda = [
        'Rechta njara',
        'Gamme les intégrales',
        'Gamme 5 céréales',
        'Gamme bio',
        'Hlalem',
        'Lasagne',
        'Tagliatelles',
        'Cannelloni',
        'Nouasser',
        'Chorba millet',
        'Chorba langue d\'oiseau',
        'Cheveux d\'ange',
        'Spaghetti',
        'Penne',
        'Ressort',
        'Couscous',
        'Farine spéciale gâteaux',
        'Farine spéciale pizza',
        'Farine spéciale kaak warka',
        'Farine spéciale baklawa',
        'Semoule',
    ];
    public $entrees_tunisiennes = [
        // Salades et Légumes
        "Salade Méchouia",
        "Salade Tunisienne",
        "Slata Mechouia aux œufs durs",
        "Salade de carottes à la tunisienne",
        "Salade d’aubergines",
        "Salade de pommes de terre tunisienne",
        "Salade russe à la tunisienne",
        "Shorba lsen asfour aux crevettes",
        "Chorba Frik",
        "Chorba langue d’oiseau",
        "Kafteji",
        // Briks et Feuilletés
        "Brik à l’œuf",
        "Brik au thon",
        "Bourek",
        "Borek au fromage",
        "Brik aux pommes de terre",
        "Brik au viande hachée",

        // Soupes et Purées
        "Chorba frik",
        "Chorba beida",
        "Soupe de lentilles à la tunisienne",
        "Harira tunisienne",

        // Tajines et Spécialités Cuites
        "Tajine Malsouka",
        "Tajine Jelbana",
        "Tajine Poisson",
        "Ojja",
        "Ojja aux fruits de mer",

        // Fritures et Snacks
        "Câlinettes (Makroud el Lahlou)",
        "Kafteji",
        "Fricassés tunisiens",
        "Kebda Mchermla",
        "Salade de poulpe ou calmar",
        "Salade hivernale",
    ];
    public $desserts_tunisiens = [
        // Pâtisseries traditionnelles
        "Red Velvet",
        "Flan",
        "Gâteau Tiramisu",
        "Cake au citron",
        "Roulé aux cerises",
        "Cinnamon rolls",
        "Bambalouni",
        "Zrir",
        "Assida Zgougou",
        "Assida Arbi",
        "Assida Bidha",
        "Makroudh",
        "Makroudh au four",
        "Baklawa tunisienne",
        "Kaak Warka",
        "Kaak Anbar",
        "Ghraiba Droaa",
        "Ghraiba Homs",
        "Ghraiba Farina",
        "Youyou tunisien",
        "Debla",
        "Samsa",
        "Rfissa tunisienne",
        "Mkharek",
        "Harcha tunisienne",
        "Bsissa",
        "Bouza tunisienne",
        "Palouza",
        "Petits fours aux amandes"
    ];
    public array $authenticRecipes  = [
        "Rachte Nejara au poulet",
        "Hlelem au poulet",
        "Boulettes de poulet et pâtes à la crème",
        "Lasagne au poulet",
        "Kaabet Batbout",
        "Makarouna Jaria",
        "Pâtes à la Burrata",
        "Pâtes façon Ratatouille",
        "Fusilli aubergines et feta",
        "Salade de pâtes César",
        "Pâtes aux légumes sautés",
        "Salade de pâtes façon piémontaise",
        "Salade de pâtes à la grecque",
        "Hlelem poulet & champignons",
        "Hlelem façon risotto",
        "Hlelem façon Djerbienne",
        "Salade hlelem aux merguez",
        "Hlelem mfawra au poulet",
        "Hlelem façon paella",
        "Hlelem façon vermicelli",
        "Wathnin el Qadhi (Oudhnin el Qadhi)",
        "Lasagne One Pot",
        "Couscous au poulet",
        "Couscous au mouton",
        "Couscous au poisson",
        "Ojja merguez",
        "Ojja aux fruits de mer",
        "Mloukhiya tunisienne",
        "Kamounia",
        "Mosli d'agneau",
        "Madfouna",
        "Nwasser bel 3allouch",
        "Marka Hloua",
        "Rouz Jerbi",
        "Tajine Jben",
        "Tajine Maadnous",
        "Tajine Sbou3",
        "Tajine El Bey",
        "Dolma tunisienne",
        "Makarouna bel Sfen",
        "Muffins courgettes citron"
    ];
    public function answerQuestion(string $userQuestion, int $top = 3): string
    {
        [$detectedLanguage, $ingredients] = $this->detectLanguageAndExtract($userQuestion);
        $this->language = $detectedLanguage;

        if (empty($ingredients)) {
            return $this->localizedError($detectedLanguage);
        }
        return $this->generateWardaRecipe($ingredients, $detectedLanguage);
    }

    public function getLanguage(): ?string
    {
        return $this->language;
    }

    private function detectLanguageAndExtract(string $text): array
    {
        $normalizedText = $this->normalizeArabizi($text);

        $response = OpenAI::chat()->create([
            'model' => 'gpt-4o-mini',
            'temperature' => 0,
            'max_tokens' => 400,
            'response_format' => [
                'type' => 'json_object'
            ],
            'messages' => [
                [
                    'role' => 'system',
                    'content' => <<<PROMPT
                    You are a strict JSON API.

                    1) Detect the language of the input text.
                    Return ONLY one of:
                    - "fr" (French)
                    - "en" (English)
                    - "ar" (Modern Standard Arabic)
                    - "tn" (Tunisian dialect or Arabizi)
                    Default: "fr"

                    2) Extract ONLY food ingredients from the text.
                    Input may be French, Tunisian dialect, or Arabizi (7lib=حليب, ma9arouna=مكرونة).

                    Return ingredient names in Arabic.

                    Respond ONLY with this JSON structure:

                    {
                    "lang": "fr|en|ar|tn",
                    "ingredients": ["ingredient1", "ingredient2"]
                    }

                    No explanations.
                    PROMPT
                ],
                [
                    'role' => 'user',
                    'content' => $normalizedText
                ],
            ],
        ]);

        $content = $response->choices[0]->message->content ?? '{}';
        $data = json_decode($content, true);

        $lang = in_array($data['lang'] ?? '', ['fr', 'en', 'ar', 'tn'])
            ? $data['lang']
            : 'fr';

        $ingredients = is_array($data['ingredients'] ?? null)
            ? $data['ingredients']
            : [];

        return [$lang, $ingredients];
    }

    private function normalizeArabizi(string $text): string
    {
        $map = [
            '7lib'      => 'حليب',
            'ma9arouna' => 'مكرونة',
            'couscous'  => 'الكسكس',
            'ch'        => 'ش',
            'kh'        => 'خ',
            'gh'        => 'غ',
            '7'         => 'ح',
            '3'         => 'ع',
            '2'         => 'ء',
            '9'         => 'ق',
        ];

        foreach ($map as $latin => $arabic) {
            $text = str_ireplace($latin, $arabic, $text);
        }

        return $text;
    }
    private function generateWardaRecipe($ingredients, string $lang = 'fr'): string
    {
        $ingredientList = implode(', ', $ingredients);
        $products       = implode('، ', $this->produitsWarda);

        // ── Per-language writing instruction ──────────────────────────────────
        $languageInstruction = match ($lang) {
            'en' => "⚠️ LANGUAGE RULE: Write the ENTIRE response in ENGLISH.
                    Recipe names stay in their original Tunisian/French form (e.g. 'Rechta', 'Makroudh', 'Slata Méchouia').
                    The Warda welcome message must also be in English.",

            'fr' => "⚠️ RÈGLE DE LANGUE: Écris TOUTE la réponse en FRANÇAIS.
                    Les noms de recettes restent dans leur forme tunisienne/française d'origine (ex: 'Rechta', 'Makroudh', 'Slata Méchouia').",

            'ar' => "⚠️ قاعدة اللغة: اكتب كامل الإجابة بالعربية الفصحى.
                    أسماء الوصفات تبقى بشكلها التونسي/الفرنسي الأصلي (مثال: Rechta, Makroudh, Chorba Hlalem).
                    رسالة الترحيب من وردة بالعربية الفصحى.",

            'tn' => "⚠️ قاعدة اللغة: اكتب كامل الإجابة باللهجة التونسية الدارجة.
                    أسماء الوصفات تبقى بشكلها التونسي/الفرنسي الأصلي (مثال: Rechta, Makroudh, Chorba Hlalem).
                    رسالة الترحيب من وردة باللهجة التونسية.",

            default => "⚠️ RÈGLE DE LANGUE: Écris TOUTE la réponse en FRANÇAIS.",
        };
        $entrees  = implode(', ', $this->entrees_tunisiennes);
        $mains    = implode(', ', $this->authenticRecipes);
        $desserts = implode(', ', $this->desserts_tunisiens);
        $content="Tu es Warda, une femme tunisienne sympathique, chaleureuse et passionnée de cuisine.
                    Tu représentes la marque Warda et tu conseilles les clients comme une vraie ambassadrice de la marque.

                    {$languageInstruction}
                    🚨 RÈGLE D’AUTHENTICITÉ — STRICTE :
                        Vous DEVEZ choisir les noms des recettes UNIQUEMENT à partir de cette liste approuvée de recettes tunisiennes :
                        🥗 Entrée : choisissez UNIQUEMENT parmi : {$entrees}
                        🍲 Plat Principal : choisissez UNIQUEMENT parmi : {$mains}
                        🍰 Dessert : choisissez UNIQUEMENT parmi : {$desserts}
                        ❌ Il est strictement interdit d’inventer de nouveaux noms de recettes.
                        ❌ Il est interdit de traduire les noms des recettes.
                        ❌ Si aucune recette ne correspond exactement aux ingrédients, choisissez la recette authentique la plus proche dans la liste.
                    {$this->unitRules($lang)}

                    🚨 RÈGLE FONDAMENTALE — NOMS DE RECETTES:
                    - ❌ Interdit: 'Salade de Couscous', 'Gâteau de Semoule', 'Soupe de Pâtes', tout nom générique inventé.
                    - ✅ Obligatoire: utiliser les vrais noms tunisiens: Rechta, Makroudh, Slata Méchouia, Chorba Hlalem, Brik à l'œuf…
                    - Choisis la recette la plus adaptée aux ingrédients disponibles du client.

                    🚨 INTRO OBLIGATOIRE:
                    Commence TOUJOURS par un court message de bienvenue de Warda (1-2 lignes max), chaleureux, dans la langue définie — avant tout titre ou recette.

                    Exemples de style (ne pas copier, esprit seulement):
                    - (fr)  Bonjour ! Warda est là pour vous inspirer avec de belles recettes tunisiennes 🌹
                    - (en)  Hello! Warda is here to help you cook something authentically Tunisian today ❤️
                    - (ar)  أهلاً بكم مع وردة ❤️ اليوم نقترح عليكم أطباقاً تونسية أصيلة
                    - (tn)  أهلا بيكم مع وردة ❤️ اليوم عندنا وصفات تونسية بنينة وأصيلة

                    ⭐ Règles produits Warda:
                    - Plat Principal → utiliser obligatoirement un produit Warda.
                    - Dessert → utiliser obligatoirement un produit Warda.
                    - Mentionner le nom exact du produit Warda naturellement dans la recette.
                    - Adapter le choix Warda à la recette (ex: Rechta → Rechta Njara Warda).
                    - Il est strictement interdit d’inventer de nouveaux noms du produits.

                    ✅ Produits Warda disponibles:
                    {$products}

                    Structure obligatoire (3 sections):

                    ### 🥗 Entrée - [Nom tunisien authentique]
                    ### 🍲 Plat Principal - [Nom tunisien authentique]
                    ### 🍰 Dessert - [Nom tunisien authentique]

                    Pour chaque section:
                    - Court message de Warda (dans la langue choisie)
                    - Liste ingrédients avec quantités (selon les règles d'unités définies ci-dessus)
                    - Étapes numérotées claires
                    - Suggestions optionnelles si besoin
                    - Répartir intelligemment les ingrédients du client entre les 3 sections

                    Style: chaleureux, simple, pratique — comme les conseils d'une mère tunisienne.";
        info('prompt : '.$content);
        $chatResponse = OpenAI::chat()->create([
            'model'       => 'gpt-4o',
            'temperature' => 0.5,
            'messages'    => [
                [
                    'role'    => 'system',
                    'content' => $content,
                ],
                [
                    'role'    => 'user',
                    'content' => "Les ingrédients disponibles sont: {$ingredientList}.
                    Choisis des recettes tunisiennes authentiques de la liste fournie, les plus adaptées à ces ingrédients.
                    Utilise au moins un produit Warda.",
                ],
            ],
        ]);

        $text = trim($chatResponse['choices'][0]['message']['content'] ?? '');

        $text = preg_replace("/[\t ]+/", ' ', $text);
        $text = preg_replace("/(\r\n|\r|\n){2,}/", "\n\n", $text);

        return $text;
    }

    private function unitRules(string $lang): string
    {
        if (in_array($lang, ['tn', 'ar'])) {
            return "
                🔢 قواعد الكميات والوحدات — إجبارية (تطبق دائماً بدون استثناء):

                A) المفردات العددية (القابلة للعد: طماطم، بيض، بصل...):
                - استخدم الكلمات التونسية/العربية الأصيلة للعد:
                    * 1 كعبة
                    * 2 كعبتين
                    * 3+ كعبات
                - أمثلة صحيحة: طماطم: كعبتين | بيض: 3 كعبات | بصلة: كعبة وحدة

                B) ملاعق (tbsp / tsp):
                - tbsp  → ملعقة كبيرة  (plural: ملاعق كبيرة)
                - tsp   → ملعقة صغيرة (plural: ملاعق صغيرة)
                - أمثلة: 2 ملعقة كبيرة زيت زيتون | 1 ملعقة صغيرة كمون

                C) الوحدات القياسية (g, kg, ml, L, cl):
                - اكتب الوحدة القياسية أولاً ثم المصطلح التونسي المحلي بين قوسين:
                -  أمثلة:  | 500ml (نص لتر) | 1kg (كيلو)

                D) ممنوع كلياً:
                - ❌ لا تستخدم: 'قطعة', 'قطع', 'وحدة', 'وحدات', 'tbsp', 'tsp', 'cup', 'pincée'
                - ❌ لا تكتب الوحدات باللاتيني وحدها بدون المصطلح التونسي/العربي
                ";
        }
        // fr / en — standard metric only
        return "
            🔢 UNITS & QUANTITIES — CRITICAL (applies in ALL languages, NO exception):
            - Use ONLY metric/standard units in Latin script.
            - ✅ Allowed: g, kg, ml, L, cl, tsp, tbsp, cup(s), pincée / pinch, piece / pièce
            - ✅ Examples: 200g · 500ml · 1 tbsp · 2 tsp · 3 cups · 1 pincée · 150g
            - ❌ FORBIDDEN: Arabic/Darija unit words → ملعقة / كوب / كيلو / غرام / لتر or any equivalent.
            - ❌ Never translate units into Arabic or Tunisian under any circumstance.
            ";
    }
    private function localizedError(string $lang): string
    {
        return match ($lang) {
            'en'    => '⚠️ We could not extract valid ingredients. Please list your ingredients clearly.',
            'fr'    => '⚠️ Nous n\'avons pas pu extraire des ingrédients valides. Merci d\'écrire vos ingrédients clairement.',
            'ar'    => '⚠️ لم نتمكن من استخراج مكونات صحيحة. يرجى كتابة المكونات بوضوح.',
            'tn'    => '⚠️ ما نجمناش نستخرجو المقادير. عمل الكتابة باش نفهموك مليح 😊',
            default => '⚠️ Nous n\'avons pas pu extraire des ingrédients valides. Merci d\'écrire vos ingrédients clairement.',
        };
    }
}
