<?php

namespace Apps\Immo\Helper;

use Core\Core\Response;

class MistralApi {

    private $apiKey;
    private $apiUrl = "https://api.mistral.ai/v1/chat/completions";

    /**
     * Constructeur de la classe MistralApi.
     *
     * @param string $apiKey Ta clé API Mistral.
     */
    public function __construct(string $apiKey) {
        $this->apiKey = $apiKey;
    }

    /**
     * Méthode générique pour appeler l'API Mistral.
     *
     * @param array $messages Tableau de messages au format ["role" => "user", "content" => "..."]
     * @param string $model Modèle à utiliser (ex: "mistral-tiny")
     * @param float $temperature Paramètre de température pour la génération
     * @return array Réponse de l'API
     */
    public function callApi(array $messages, string $model = "mistral-tiny", float $temperature = 0.2): array {
        $headers = [
            "Authorization: Bearer {$this->apiKey}",
            "Content-Type: application/json",
        ];

        $data = [
            "model" => $model,
            "messages" => $messages,
            "temperature" => $temperature,
        ];

        $ch = curl_init($this->apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if (curl_errno($ch)) {
            throw new \Exception("Erreur cURL : " . curl_error($ch));
        }

        curl_close($ch);

        if ($httpCode !== 200) {
            throw new \Exception("Erreur API : Code {$httpCode} - " . $response);
        }

        return json_decode($response, true);
    }

    
    public function GetJson($response){
        
          $content = $response['choices'][0]['message']['content'];
            
            $debut = strpos($content, '{');
            $fin = strrpos($content, '}');

            if ($debut !== false && $fin !== false) {
                $jsonString = substr($content, $debut, $fin - $debut + 1);

                $result = json_decode($jsonString, true);

                if (json_last_error() === JSON_ERROR_NONE) {
                   // print_r($content);
                } else {
                    echo "JSON invalide";
                }
            }
            
        return $result;    
            
    }
    
    /**
     * Vérifie si un texte contient les informations obligatoires (type de bien, surface, équipements, localisation).
     *
     * @param string $userText Texte saisi par l'utilisateur
     * @return array Résultat de l'analyse
     */
    public function estimate(string $userText): string {
        $messages = [
            [
                "role" => "user",
                "content" => "
                Voici un texte saisi par un utilisateur : '{$userText}'.
                Vérifie si les informations suivantes sont présentes :
                - Type de bien (ex: maison, appartement, terrain)
                - Surface habitable (en m²)
                - Surface du terrain (en m², si applicable)
                - Équipements (ex: piscine, garage, cuisine équipée)
                - Localisation (ville, quartier, code postal)
 **Retourne UNIQUEMENT un objet JSON valide** (sans texte supplémentaire, sans balises Markdown, sans explications) avec la structure suivante  :
                {
                    \"type_de_bien\": \"valeur ou null\",
                    \"surface_habitable\": \"valeur ou null\",
                     \"surface_terrain\": \"valeur ou null\",
                    \"equipements\": [\"valeur1\", \"valeur2\"] ou [],
                    \"localisation\": \"valeur ou null\",
                    \"manquants\": [\"type_de_bien\", \"surface\", \"surface_terrain\", ...] // liste des champs manquants
                }
                "
            ]
        ];

        $response = $this->callApi($messages);
        $result = $this->GetJson($response);

        $missing = count($result['manquants']) > 0;

        //Il manque des informations
        if ($missing) {

            return Response::Error($result['manquants']);
        } else {

            $result = $this->estimateValueViaPrompt($result);

            return Response::Success($result["estimation"]);
        }
    }

    /**
     * Estime la valeur d'un bien via un prompt envoyé à l'API Mistral.
     */
    public function estimateValueViaPrompt(array $propertyInfo): array {
        $type = $propertyInfo['type_de_bien'] ?? 'inconnu';
        $surfaceHabitable = $propertyInfo['surface_habitable'] ?? 'inconnu';
        $surfaceTerrain = $propertyInfo['surface_terrain'] ?? 'inconnu';
        $localisation = $propertyInfo['localisation'] ?? 'inconnu';
        $equipements = implode(", ", $propertyInfo['equipements'] ?? []);

        $messages = [
    [
        "role" => "user",
        "content" => "
                Voici les informations d'un bien immobilier :
                - Type de bien : {$type}
                - Surface habitable : {$surfaceHabitable} m²
                - Surface du terrain : {$surfaceTerrain} m²
                - Localisation : {$localisation}
                - Équipements : {$equipements}

                Fais une estimation approximative de la valeur de ce bien en euros, en tenant compte des prix du marché dans cette localisation et des équipements.
                 **Retourne UNIQUEMENT un objet JSON valide** (sans texte supplémentaire, sans balises Markdown, sans explications) avec la structure suivante :
                {
                    \"prix_estime\": \"valeur en euros\",
                    \"explication\": \"explication de l'estimation\",
                    \"recapitulatif\": {
                        \"type_de_bien\": \"{$type}\",
                        \"surface\": \"{$surface} m²\",
                        \"localisation\": \"{$localisation}\",
                        \"equipements\": [\"{$equipements}\"]
                    }
                }
                "
    ]
        ];

        try {
            $response = $this->callApi($messages);
            $result = $this->GetJson($response);
            
           
            return [
                "success" => true,
                "estimation" => $result,
                "message" => "Estimation générée avec succès.",
            ];
        } catch (Exception $e) {
            return [
                "success" => false,
                "error_code" => 2,
                "error_message" => "Erreur lors de l'appel à l'API pour l'estimation : " . $e->getMessage(),
                "estimation" => null,
            ];
        }
    }

    /*     * *
     * Vérify que l('utilisateur à saisie les bonnee données utile
     */

    public function verifySearchProperty(string $userText) {

        $messages = [
            [
                "role" => "user",
                "content" => "
                Voici un texte saisi par un utilisateur : '{$userText}'.
                Vérifie si les informations suivantes sont présentes :
                - Type de bien (ex: maison, appartement, terrain)
                - Surface habitable (en m²)
                - Localisation (ville, quartier, code postal)

                Retourne un objet JSON structuré comme suit :
                {
                    \"type_de_bien\": \"valeur ou null\",
                    \"surface_habitable\": \"valeur ou null\",
                    \"localisation\": \"valeur ou null\",
                    \"manquants\": [\"type_de_bien\", \"surface\",  ...] // liste des champs manquants
                }
                "
            ]
        ];

        $response = $this->callApi($messages);

        $content = $response['choices'][0]['message']['content'];
        $result = json_decode($content, true);

        $missing = $result['manquants'] ?? [];
        $success = empty($missing);

        //Il manque des informations
        if (!$success || !is_array($result)) {

            return Response::Error($missing);
        } else {

            return Response::Success($result);
        }
    }
}
