<?php

namespace App\Services;

use App\Models\Examen;
use App\Models\Pregunta;
use App\Models\ReglaAreaProceso;
use App\Models\PreguntaAsignada;
use Illuminate\Support\Facades\DB;

class ExamenService
{
    /**
     * Generar preguntas según reglas
     */
    public function generarPreguntasExamen(Examen $examen): array
    {
        if ($examen->preguntasAsignadas()->exists()) {
            return [
                'success' => false,
                'message' => 'El examen ya tiene preguntas'
            ];
        }

        $reglas = ReglaAreaProceso::where('area_proceso_id', $examen->area_proceso_id)
            ->orderBy('orden')
            ->get();

        if ($reglas->isEmpty()) {
            return [
                'success' => false,
                'message' => 'No hay reglas configuradas'
            ];
        }

        DB::beginTransaction();

        try {
            $orden = 1;

            foreach ($reglas as $regla) {
                $preguntas = Pregunta::where('curso_id', $regla->curso_id)
                    ->where('activo', 1)
                    ->when($regla->nivel_dificultad, fn ($q) =>
                        $q->where('nivel_dificultad', $regla->nivel_dificultad)
                    )
                    ->inRandomOrder()
                    ->limit($regla->cantidad_preguntas)
                    ->get();

                if ($preguntas->count() < $regla->cantidad_preguntas) {
                    throw new \Exception("Preguntas insuficientes para curso {$regla->curso_id}");
                }

                foreach ($preguntas as $pregunta) {
                    PreguntaAsignada::create([
                        'examen_id'    => $examen->id,
                        'pregunta_id'  => $pregunta->id,
                        'orden'        => $orden++,
                        'puntaje_base' => $regla->ponderacion,
                        'estado'       => 'pendiente',
                    ]);
                }
            }

            DB::commit();

            return ['success' => true];

        } catch (\Throwable $e) {
            DB::rollBack();
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }


public function obtenerPreguntasExamen(Examen $examen): array
{
    // Traemos preguntas con curso
    $preguntas = $examen->preguntasAsignadas()
        ->with('pregunta.curso')
        ->get()
        ->sortBy('orden');

    // Traemos datos del área-proceso directamente desde la DB
    $areaProceso = \DB::table('area_proceso')
        ->join('procesos', 'area_proceso.proceso_id', '=', 'procesos.id')
        ->join('areas', 'area_proceso.area_id', '=', 'areas.id')
        ->where('area_proceso.id', $examen->area_proceso_id)
        ->select(
            'procesos.nombre as proceso_nombre',
            'procesos.duracion as proceso_duracion',
            'procesos.intentos_maximos as proceso_intentos_maximos',
            'areas.nombre as area_nombre'
        )
        ->first();

    return $preguntas->map(fn($pa) => [
        'id'             => $pa->id,
        'orden'          => $pa->orden,
        'enunciado'      => $pa->pregunta->enunciado,
        'extra'          => $pa->pregunta->enunciado_adicional,
        'opciones'       => $this->mezclarOpciones($pa->pregunta->opciones),
        'imagenes'       => $pa->pregunta->imagenes,
        'estado'         => $pa->estado,
        'respuesta'      => $pa->pregunta->respuesta_correcta,
        'curso'          => $pa->pregunta->curso->nombre ?? null,
        'proceso'        => $areaProceso->proceso_nombre ?? null,
        'duracion'       => $areaProceso->proceso_duracion ?? null,
        'intentos_maximos'=> $areaProceso->proceso_intentos_maximos ?? null,
        'area'           => $areaProceso->area_nombre ?? null
    ])->values()->toArray();
}




public function guardarRespuesta(PreguntaAsignada $pa, ?string $respuesta): array
{
    if ($pa->estado === 'respondida') {
        return ['success' => false, 'message' => 'Ya respondida'];
    }

    // 🔹 Si está en blanco
    if (empty($respuesta)) {

        $pa->update([
            'respuesta_usuario' => null,
            'es_correcta'       => 2, // 2 = blanco
            'puntaje_obtenido'  => 0,
            'estado'            => 'respondida',
            'respondida_at'     => now()
        ]);

        return [
            'success'  => true,
            'correcta' => 2,
            'puntaje'  => 0
        ];
    }

    // 🔹 Si respondió algo
    $esCorrecta = $respuesta === $pa->pregunta->respuesta_correcta;

    $pa->update([
        'respuesta_usuario' => $respuesta,
        'es_correcta'       => $esCorrecta ? 1 : 0,
        'puntaje_obtenido'  => $esCorrecta ? $pa->puntaje_base : 0,
        'estado'            => 'respondida',
        'respondida_at'     => now()
    ]);

    return [
        'success'  => true,
        'correcta' => $esCorrecta ? 1 : 0,
        'puntaje'  => $pa->puntaje_obtenido
    ];
}



    private function mezclarOpciones(?array $opciones): array
    {
        if (!$opciones) return [];

        $keys = array_keys($opciones);
        shuffle($keys);

        return array_map(fn ($k) => [
            'key' => $k,
            'texto' => $opciones[$k]
        ], $keys);
    }
}
