<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException;
use App\Http\Controllers\CourseController;
use App\Http\Controllers\ProgressController;
use Illuminate\Support\Facades\Log;

use App\Models\Course;
use App\Models\Chapter;

class AIController extends Controller
{
    // ====== PARÁMETROS CONFIGURABLES ======

        // Límite de caracteres que puede enviar el usuario
        private int $maxUserMessageLength = 500;

        // Límite máximo de caracteres en la respuesta AI
        private int $maxAiResponseLength = 800;

        // Modelo Ollama a usar
        private string $model = 'llama3.2';

        // Temperatura para generación (aleatoriedad)
        private float $temperature = 0.4;

        // Tiempo máximo de tokens (igual que maxAiResponseLength pero en tokens, ajustar si hace falta)
        private int $maxTokens = 800;

        // Ruta o comando para el servidor Ollama
        private string $ollamaServer = 'http://localhost:11434';

        // Opcional: activar streaming de respuesta (true/false)
        private bool $stream = false;

        // Voz del lector de mensajes (ElevenLabs)
        private string $voiceId = 'pNInz6obpgDQGcFmaJgB';

    // ======================================


    // Función para comprobar conexión con el servidor Ollama
    public function ping() {
        $url = rtrim($this->ollamaServer, '/') . '/'; // base URL

        try {
            $response = Http::get($url);

            if ($response->successful()) {
                return response()->json([
                    'status' => 'success',
                    'message' => 'Ollama server reachable',
                    'content' => $response->body(),
                ]);
            } else {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Ollama server not reachable',
                    'http_status' => $response->status(),
                ], 503);
            }
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to connect to Ollama server',
                'error' => $e->getMessage(),
            ], 503);
        }
    }

    // Función para preguntar a Ollama
    public function askAI(Request $request, Course $course, Chapter $chapter) {

        $pingData = $this->ping()->getData();

        if (!isset($pingData->status) || $pingData->status !== 'success') {
            return response()->json(['error' => 'Ollama is not reachable'], 503);
        }

        // Comprobar si el usuario tiene acceso al curso

        $status = (new CourseController())->userCourse_status($course->id);
        if (!in_array($status, ['In Progress', 'Redoing'])) {
            return response()->json(['error' => 'No tienes acceso a este curso'], 403);
        }

        // Comprobar si el usuario tiene acceso al capitulo

        $currentChapterId = (new ProgressController())->current_chapter($course->id);
        // Si intenta acceder a un capítulo posterior al que ha desbloqueado
        if ($chapter->id > $currentChapterId) {
            return response()->json(['error' => 'Este capítulo aún no está desbloqueado'], 403);
        }

        // Validar entrada
        try {
            $request->validate([
                'question' => 'required|string|max:' . $this->maxUserMessageLength,
            ]);
        } catch (ValidationException $e) {
            return response()->json([
                'error' => 'Validation error',
                'messages' => $e->errors()
            ], 422);
        }

        // Obtener datos confiables del servidor
        $courseTitle    = $course->title;
        $chapterTitle   = $chapter->title;
        $chapterContent = $chapter->content;

        // Obtener nombre del usuario autenticado
        $student = Auth::user();
        $studentName = $student?->name ?? 'Student';

        // Query
        $question = $request->input('question');

        $prompt = "
            You are an assistant for an online course platform called DailyStudy. You help students with questions about the course they are taking.

            The student's name is {$studentName}.
            They are taking the course: {$courseTitle}.
            Current chapter: {$chapterTitle}.

            Content of the current chapter:
            {$chapterContent}

            Student's question:
            --------------------------------------------------------
            {$question}
            --------------------------------------------------------

            Please respond in a friendly, educational tone. Use examples if helpful.
            Always address the student by name, and respond entirely in the same language the question is written in, including the greeting and closing.

            Limit your response to a maximum of {$this->maxAiResponseLength} characters.
        ";

        // Construir payload para la petición HTTP a Ollama
        $payload = [
            'model' => $this->model,
            'prompt' => $prompt,
            'temperature' => $this->temperature,
            'max_tokens' => $this->maxTokens,
            'stream' => $this->stream,
        ];

        // Verificar si la conexión fue abortada
        if (connection_aborted()) {
            Log::info("Request aborted before calling Ollama.");
            return response()->json(['error' => 'Client aborted the request.'], 499);
        }


        try {
            $response = Http::timeout(300) // en segundos (300s -> 5min)
               ->post($this->ollamaServer . '/api/generate', $payload);
               
            if (!$response->successful()) {
                return response()->json(['error' => 'Error from Ollama server'], 500);
            }

            $output = $response->json();

            $answerRaw = $output['response'] ?? null;

            if (!$answerRaw) {
                return response()->json(['error' => 'No response from Ollama'], 500);
            }

            $answer = mb_substr(trim($answerRaw), 0, $this->maxAiResponseLength);

            return response()->json(['answer' => $answer]);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to connect to Ollama server', 'message' => $e->getMessage()], 500);
        }
    }

    public function messageRead(Request $request)
    {
        $text = $request->input('text');

        if (!$text) {
            return response()->json(['error' => 'Text is required'], 400);
        }

        $apiKey = config('services.elevenlabs.key');

        try {
            $response = Http::withHeaders([
                'xi-api-key' => $apiKey,
                'Content-Type' => 'application/json',
            ])->post("https://api.elevenlabs.io/v1/text-to-speech/{$this->voiceId}", [
                'text' => $text,
                'model_id' => 'eleven_monolingual_v1',
                'voice_settings' => [
                    'stability' => 0.5,
                    'similarity_boost' => 0.75
                ]
            ]);

            if (!$response->ok()) {
                // Log completa para ver el error
                Log::error('TTS API error: ' . $response->body());
                return response()->json(['error' => 'TTS API error', 'details' => $response->body()], 500);
            }

            return response($response->body(), 200)
                ->header('Content-Type', 'audio/mpeg');
        } catch (\Exception $e) {
            Log::error('TTS Error: ' . $e->getMessage());
            return response()->json(['error' => 'Internal server error'], 500);
        }
    }
}
