<?php

namespace App\Http\Controllers;

use App\Models\Alumno;
use App\Models\Docente;
use App\Models\Evaluacion;
use App\Models\EvaluacionSubmission;
use App\Models\Respuesta;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class EvaluacionResponderController extends Controller
{
    public function misEvaluaciones()
    {
        $user = Auth::user();

        $docente = Docente::whereHas('docentes', fn($q) => $q->where('id', $user->id))->first();
        $alumno  = Alumno::whereHas('alumnos',  fn($q) => $q->where('id', $user->id))->first();

        $evaluaciones = collect();
        $respondidas  = [];

        if ($docente) {
            $grupos     = $docente->grupos()->get();
            $plantelIds = $grupos->pluck('plantel')->unique()->filter()->values();
            $nivelIds   = $grupos->pluck('nivel')->unique()->filter()->values();

            $evaluaciones = Evaluacion::whereHas('tipo', fn($q) => $q->where('slug', 'docente'))
                ->where('status', 'activa')
                ->where(fn($q) => $q
                    ->whereHas('planteles', fn($p) => $p->whereIn('plantels.id', $plantelIds))
                    ->orWhereDoesntHave('planteles')
                )
                ->where(fn($q) => $q
                    ->whereHas('niveles', fn($n) => $n->whereIn('nivels.id', $nivelIds))
                    ->orWhereDoesntHave('niveles')
                )
                ->where(fn($q) => $q->whereNull('fecha_inicio')->orWhereDate('fecha_inicio', '<=', now()))
                ->where(fn($q) => $q->whereNull('fecha_fin')->orWhereDate('fecha_fin', '>=', now()))
                ->withCount('preguntas')
                ->get();

        } elseif ($alumno) {
            $gruposIds  = $alumno->grupos()->pluck('grupos.id');
            $plantelIds = \App\Models\Grupo::whereIn('id', $gruposIds)->pluck('plantel')->unique()->filter()->values();
            $nivelIds   = \App\Models\Grupo::whereIn('id', $gruposIds)->pluck('nivel')->unique()->filter()->values();

            $evaluaciones = Evaluacion::whereHas('tipo', fn($q) => $q->where('slug', 'alumno'))
                ->where('status', 'activa')
                ->where(fn($q) => $q
                    ->whereHas('planteles', fn($p) => $p->whereIn('plantels.id', $plantelIds))
                    ->orWhereDoesntHave('planteles')
                )
                ->where(fn($q) => $q
                    ->whereHas('niveles', fn($n) => $n->whereIn('nivels.id', $nivelIds))
                    ->orWhereDoesntHave('niveles')
                )
                ->where(fn($q) => $q->whereNull('fecha_inicio')->orWhereDate('fecha_inicio', '<=', now()))
                ->where(fn($q) => $q->whereNull('fecha_fin')->orWhereDate('fecha_fin', '>=', now()))
                ->withCount('preguntas')
                ->get();
        }

        if ($evaluaciones->isNotEmpty()) {
            $respondidas = EvaluacionSubmission::where('user_id', $user->id)
                ->whereIn('evaluacion_id', $evaluaciones->pluck('id'))
                ->pluck('evaluacion_id')
                ->toArray();
        }

        return view('evaluacion.mis_evaluaciones', compact('evaluaciones', 'respondidas', 'docente', 'alumno'));
    }

    public function show(Evaluacion $evaluacion)
    {
        abort_if($evaluacion->status !== 'activa', 403, 'Esta evaluación no está activa.');

        if ($evaluacion->fecha_inicio && \Carbon\Carbon::parse($evaluacion->fecha_inicio)->isFuture()) {
            abort(403, 'Esta evaluación aún no ha comenzado.');
        }
        if ($evaluacion->fecha_fin && \Carbon\Carbon::parse($evaluacion->fecha_fin)->startOfDay()->isPast()) {
            abort(403, 'Esta evaluación ya cerró.');
        }

        $yaRespondida = EvaluacionSubmission::where('evaluacion_id', $evaluacion->id)
            ->where('user_id', Auth::id())
            ->exists();

        $preguntas = $evaluacion->preguntas()->with(['tipo', 'opciones'])->get();
        $tipoSlug  = $evaluacion->tipo->slug;

        // Para tipo 'alumno': obtener docentes del alumno para preguntas es_docente
        $docentesParaEvaluar = collect();
        if ($tipoSlug === 'alumno' && $preguntas->where('es_docente', true)->count() > 0) {
            $alumno = Alumno::whereHas('alumnos', fn($q) => $q->where('id', Auth::id()))->first();
            if ($alumno) {
                // Ciclo más alto del alumno = semestre actual
                $cicloActual = DB::table('alumno_grupo')
                    ->join('grupos', 'grupos.id', '=', 'alumno_grupo.grupo_id')
                    ->where('alumno_grupo.alumno_id', $alumno->id)
                    ->max('grupos.ciclo');

                if ($cicloActual) {
                    // Grupos del alumno en ese ciclo
                    $gruposIds = DB::table('alumno_grupo')
                        ->join('grupos', 'grupos.id', '=', 'alumno_grupo.grupo_id')
                        ->where('alumno_grupo.alumno_id', $alumno->id)
                        ->where('grupos.ciclo', $cicloActual)
                        ->pluck('alumno_grupo.grupo_id')
                        ->toArray();

                    // Docentes asignados a esos grupos cuya materia tenga el mismo ciclo que el grupo
                    $docenteIds = DB::table('docente_grupo')
                        ->join('materials', 'materials.id', '=', 'docente_grupo.materia_id')
                        ->whereIn('docente_grupo.grupo_id', $gruposIds)
                        ->where('materials.ciclo', $cicloActual)
                        ->distinct()
                        ->pluck('docente_grupo.docente_id')
                        ->toArray();

                    $docentesParaEvaluar = Docente::whereIn('id', $docenteIds)
                        ->with('docentes')
                        ->get()
                        ->values();
                }
            }
        }

        return view('evaluacion.responder', compact(
            'evaluacion', 'preguntas', 'docentesParaEvaluar', 'tipoSlug', 'yaRespondida'
        ));
    }

    public function store(Request $request, Evaluacion $evaluacion)
    {
        abort_if($evaluacion->status !== 'activa', 403);

        if (EvaluacionSubmission::where('evaluacion_id', $evaluacion->id)
            ->where('user_id', Auth::id())->exists()) {
            return back()->with('error', 'Ya respondiste esta evaluación.');
        }

        DB::transaction(function () use ($request, $evaluacion) {
            $submission = EvaluacionSubmission::create([
                'evaluacion_id' => $evaluacion->id,
                'user_id'       => Auth::id(),
            ]);

            foreach ($evaluacion->preguntas()->with('tipo')->get() as $pregunta) {
                $tipoSlug         = $pregunta->tipo->slug;
                $esOpcionMultiple = $tipoSlug === 'opcion_multiple';

                if ($pregunta->es_docente) {
                    $valores = $request->input("resp.{$pregunta->id}", []);
                    foreach ($valores as $docenteId => $valor) {
                        if (!filled($valor)) continue;
                        Respuesta::create([
                            'submission_id' => $submission->id,
                            'pregunta_id'   => $pregunta->id,
                            'docente_id'    => $docenteId,
                            'valor'         => $esOpcionMultiple ? null : $valor,
                            'opcion_id'     => $esOpcionMultiple ? $valor : null,
                        ]);
                    }
                } else {
                    $valor = $request->input("resp.{$pregunta->id}");
                    if (!filled($valor)) continue;
                    Respuesta::create([
                        'submission_id' => $submission->id,
                        'pregunta_id'   => $pregunta->id,
                        'docente_id'    => null,
                        'valor'         => $esOpcionMultiple ? null : $valor,
                        'opcion_id'     => $esOpcionMultiple ? $valor : null,
                    ]);
                }
            }
        });

        return redirect()->route('evaluacion.mis_evaluaciones')
            ->with('info', '¡Evaluación enviada correctamente! Gracias por tu participación.');
    }
}
