<?php

declare(strict_types=1);

namespace App\Services;

use GuzzleHttp\Client;
use Illuminate\Database\Capsule\Manager as DB;

class GroqLimitException extends \Exception {}

class GroqService
{
    private Client $http;
    private string $apiKey;
    private int $dailyLimit;
    private const MODEL = 'llama-3.3-70b-versatile';

    public function __construct()
    {
        $this->apiKey     = $_ENV['GROQ_API_KEY'] ?? '';
        $this->dailyLimit = (int)($_ENV['GROQ_DAILY_LIMIT'] ?? 100);
        $this->http       = new Client(['timeout' => 30]);
    }

    public function call(string $prompt, int $maxTokens = 500, float $temperature = 0.7): string
    {
        if (!$this->apiKey) {
            throw new GroqLimitException('Clé Groq non configurée');
        }

        // Vérifier limite quotidienne
        $today = date('Y-m-d');
        $count = DB::table('logs_audit')
            ->where('action', 'groq_call')
            ->whereDate('created_at', $today)
            ->count();

        if ($count >= $this->dailyLimit) {
            throw new GroqLimitException('Limite quotidienne Groq atteinte (' . $this->dailyLimit . ' appels/jour)');
        }

        try {
            $response = $this->http->post('https://api.groq.com/openai/v1/chat/completions', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->apiKey,
                    'Content-Type'  => 'application/json',
                ],
                'json' => [
                    'model'       => self::MODEL,
                    'messages'    => [['role' => 'user', 'content' => $prompt]],
                    'max_tokens'  => $maxTokens,
                    'temperature' => $temperature,
                ],
            ]);

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

            // Logger l'appel
            DB::table('logs_audit')->insert([
                'action'    => 'groq_call',
                'details'   => json_encode(['tokens' => $maxTokens, 'prompt_chars' => strlen($prompt)]),
                'created_at'=> date('Y-m-d H:i:s'),
            ]);

            return $content;
        } catch (GroqLimitException $e) {
            throw $e;
        } catch (\Exception $e) {
            error_log('[GroqService] ' . $e->getMessage());
            throw new \Exception('Erreur API Groq: ' . $e->getMessage());
        }
    }

    public function resumeDashboard(array $kpis, array $alertes): string
    {
        $alertesStr = implode(', ', array_column($alertes, 'message'));
        $prompt = "Voici les KPIs du jour pour MyKollectOr : " . json_encode($kpis) .
                  ". Alertes : " . $alertesStr .
                  ". Génère un résumé de 3 phrases maximum en français, priorisé par urgence. Sois concis et pratique.";

        try {
            return $this->call($prompt, 200, 0.5);
        } catch (\Exception $e) {
            return 'IA indisponible — ' . $e->getMessage();
        }
    }

    public function genererEmailTemplate(string $contexte): string
    {
        $prompt = "Génère un email de relance en français pour MyKollectOr (médailles sportives gravées). Contexte : {$contexte}. Ton : chaleureux, sportif. 3-4 phrases maximum.";
        return $this->call($prompt, 300, 0.7);
    }

    public function genererPostSocial(string $reseau, string $sujet): string
    {
        $prompt = "Génère un post {$reseau} court et inspirant (max 150 mots) pour MyKollectOr® (médailles sportives gravées). Sujet : {$sujet}. Ton : authentique, sportif, motivant. Inclure #MyKollectOr.";
        return $this->call($prompt, 250, 0.8);
    }

    public function suggestionsSeo(string $contenu, string $url): string
    {
        $prompt = "Voici le contenu de la page {$url} : {$contenu}. Suggère une balise title et une meta description optimisées SEO en français, chacune sous 160 caractères. Réponds au format JSON : {title, description}.";
        return $this->call($prompt, 200, 0.3);
    }

    public function decomposerTache(string $titreTache): array
    {
        $prompt = "Tu es un assistant de productivité pour MyKollectOr, une plateforme de médailles sportives. Décompose cette tâche en 3-5 sous-tâches concrètes et actionnables. Réponds UNIQUEMENT en JSON valide, sans markdown : [{\"titre\":\"...\",\"description\":\"...\"}]. Tâche : {$titreTache}";
        $raw = $this->call($prompt, 500, 0.5);
        $decoded = json_decode($raw, true);
        return is_array($decoded) ? $decoded : [];
    }

    public function resumeSemaine(array $entries): string
    {
        $text = implode("\n", array_map(fn($e) => $e['date'] . ': ' . $e['contenu'], $entries));
        $prompt = "Voici les entrées de journal de la semaine pour Julien, fondateur de MyKollectOr : {$text}. Génère un résumé bienveillant en 3-4 phrases : ce qui a avancé, ce qui bloque, encouragement pour la semaine à venir.";
        return $this->call($prompt, 300, 0.6);
    }

    public function assistantChat(string $message, array $history, array $context): string
    {
        $systemPrompt = "Tu es l'assistant personnel de Julien Carpentier, fondateur de MyKollectOr®, une plateforme de médailles sportives gravées. Tu connais son projet en détail. Tu l'aides à prioriser, organiser et avancer. Sois concis, pratique et bienveillant. Parle en français. Contexte actuel : " . json_encode($context);

        $messages = [['role' => 'system', 'content' => $systemPrompt]];
        foreach (array_slice($history, -10) as $h) {
            $messages[] = ['role' => $h['role'], 'content' => $h['message']];
        }
        $messages[] = ['role' => 'user', 'content' => $message];

        try {
            $response = $this->http->post('https://api.groq.com/openai/v1/chat/completions', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->apiKey,
                    'Content-Type'  => 'application/json',
                ],
                'json' => [
                    'model'      => self::MODEL,
                    'messages'   => $messages,
                    'max_tokens' => 500,
                    'temperature'=> 0.7,
                ],
            ]);

            $data = json_decode((string)$response->getBody(), true);

            DB::table('logs_audit')->insert([
                'action'    => 'groq_call',
                'details'   => json_encode(['type' => 'assistant']),
                'created_at'=> date('Y-m-d H:i:s'),
            ]);

            return $data['choices'][0]['message']['content'] ?? '';
        } catch (\Exception $e) {
            return 'Je suis temporairement indisponible. Réessayez dans quelques instants.';
        }
    }

    public function getUsageToday(): array
    {
        $count = DB::table('logs_audit')
            ->where('action', 'groq_call')
            ->whereDate('created_at', date('Y-m-d'))
            ->count();

        return [
            'utilises'  => $count,
            'limite'    => $this->dailyLimit,
            'restants'  => max(0, $this->dailyLimit - $count),
            'disponible'=> $count < $this->dailyLimit,
        ];
    }
}
