<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Concurso;
use App\Models\ConcursoParticipante;
use App\Models\ConcursoRespuesta;
use Illuminate\Http\Request;

class ConcursoParticipanteController extends Controller
{
    // ── INDEX ─────────────────────────────────────────────────────────
    public function index(Concurso $concurso)
    {
        $concurso->load('preguntas');
        $participantes = $concurso->participantesConNota();

        return view('admin.concursos.participantes.index', compact('concurso', 'participantes'));
    }

    // ── CREATE ────────────────────────────────────────────────────────
    public function create(Concurso $concurso)
    {
        $concurso->load('preguntas');
        return view('admin.concursos.participantes.form', compact('concurso'));
    }

    // ── STORE ─────────────────────────────────────────────────────────
    public function store(Request $request, Concurso $concurso)
    {
        $data = $request->validate([
            'apellidos'   => 'required|string|max:150',
            'nombres'     => 'required|string|max:150',
            'nivel'       => 'nullable|string|max:50',
            'grado'       => 'nullable|string|max:20',
            'seccion'     => 'nullable|string|max:10',
            'genero'      => 'nullable|in:M,F',
            'tiempo'      => 'nullable|date_format:H:i:s,H:i',
            'observacion' => 'nullable|string|max:500',
            'respuesta'   => 'nullable|array',
            'respuesta.*' => 'nullable|string|max:100',
        ]);

        $data['concurso_id'] = $concurso->id;
        // Normalizar tiempo
        if (!empty($data['tiempo']) && strlen($data['tiempo']) === 5) {
            $data['tiempo'] = $data['tiempo'] . ':00';
        }

        $participante = ConcursoParticipante::create($data);

        // Guardar respuestas
        $this->guardarRespuestas($participante, $request->input('respuesta', []), $concurso->num_preguntas);

        return redirect()->route('admin.concursos.participantes.index', $concurso)
            ->with('success', 'Participante agregado correctamente.');
    }

    // ── EDIT ──────────────────────────────────────────────────────────
    public function edit(Concurso $concurso, ConcursoParticipante $participante)
    {
        $concurso->load('preguntas');
        $participante->load('respuestas');
        $respuestasIndexed = $participante->respuestas->keyBy('pregunta_numero');

        return view('admin.concursos.participantes.form', compact('concurso', 'participante', 'respuestasIndexed'));
    }

    // ── UPDATE ────────────────────────────────────────────────────────
    public function update(Request $request, Concurso $concurso, ConcursoParticipante $participante)
    {
        $data = $request->validate([
            'apellidos'   => 'required|string|max:150',
            'nombres'     => 'required|string|max:150',
            'nivel'       => 'nullable|string|max:50',
            'grado'       => 'nullable|string|max:20',
            'seccion'     => 'nullable|string|max:10',
            'genero'      => 'nullable|in:M,F',
            'tiempo'      => 'nullable|date_format:H:i:s,H:i',
            'observacion' => 'nullable|string|max:500',
            'respuesta'   => 'nullable|array',
            'respuesta.*' => 'nullable|string|max:100',
        ]);

        if (!empty($data['tiempo']) && strlen($data['tiempo']) === 5) {
            $data['tiempo'] = $data['tiempo'] . ':00';
        }

        $participante->update($data);

        // Actualizar respuestas
        $participante->respuestas()->delete();
        $this->guardarRespuestas($participante, $request->input('respuesta', []), $concurso->num_preguntas);

        return redirect()->route('admin.concursos.participantes.index', $concurso)
            ->with('success', 'Participante actualizado correctamente.');
    }

    // ── DESTROY ───────────────────────────────────────────────────────
    public function destroy(Concurso $concurso, ConcursoParticipante $participante)
    {
        $participante->delete();
        return redirect()->route('admin.concursos.participantes.index', $concurso)
            ->with('success', 'Participante eliminado.');
    }

    // ── HELPER ────────────────────────────────────────────────────────
    private function guardarRespuestas(ConcursoParticipante $participante, array $respuestas, int $numPreguntas): void
    {
        for ($i = 1; $i <= $numPreguntas; $i++) {
            $valor = $respuestas[$i] ?? null;
            ConcursoRespuesta::create([
                'participante_id'  => $participante->id,
                'pregunta_numero'  => $i,
                'respuesta_alumno' => ($valor !== null && trim($valor) !== '') ? trim($valor) : null,
            ]);
        }
    }

    // ══════════════════════════════════════════════════════════════════════
    //  CARGA MASIVA
    // ══════════════════════════════════════════════════════════════════════

    /** Descarga la plantilla Excel para importación masiva */
    public function plantillaExcel(Concurso $concurso)
    {
        $concurso->load('preguntas');

        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('Participantes');

        // ── Cabeceras ──
        $headers = ['apellidos', 'nombres', 'nivel', 'grado', 'seccion', 'genero', 'tiempo', 'observacion'];
        for ($i = 1; $i <= $concurso->num_preguntas; $i++) {
            $headers[] = 'P' . $i;
        }

        $col = 1;
        foreach ($headers as $h) {
            $cell = $sheet->getCellByColumnAndRow($col, 1);
            $cell->setValue($h);
            $sheet->getColumnDimensionByColumn($col)->setAutoSize(true);

            // Estilo de cabecera
            $cellRef = $cell->getCoordinate();
            $sheet->getStyle($cellRef)->applyFromArray([
                'font'      => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill'      => ['fillType' => 'solid', 'startColor' => ['rgb' => '1A237E']],
                'alignment' => ['horizontal' => 'center'],
            ]);
            $col++;
        }

        // ── Fila de ejemplo ──
        $ejemplo = ['GARCIA GARCIA', 'Juan Carlos', 'Secundaria', '2°', 'A', 'M', '01:15', ''];
        for ($i = 1; $i <= $concurso->num_preguntas; $i++) {
            $ejemplo[] = '';
        }
        $colE = 1;
        foreach ($ejemplo as $val) {
            $sheet->getCellByColumnAndRow($colE, 2)->setValue($val);
            $colE++;
        }

        // Freeze header row
        $sheet->freezePane('A2');

        $writer   = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $filename = 'plantilla_participantes_' . $concurso->sigla . '_' . $concurso->anio . '.xlsx';

        return response()->streamDownload(function () use ($writer) {
            $writer->save('php://output');
        }, $filename, [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        ]);
    }

    /** Parsea el Excel y devuelve JSON con preview + detección de duplicados */
    public function previewMasivo(Request $request, Concurso $concurso)
    {
        $request->validate(['archivo' => 'required|file|mimes:xlsx,xls,csv|max:5120']);

        $concurso->load('preguntas');
        $path = $request->file('archivo')->getRealPath();

        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
        $sheet  = $spreadsheet->getActiveSheet();
        $rows   = $sheet->toArray(null, true, true, false);
        $header = array_map('strtolower', array_map('trim', $rows[0] ?? []));

        $numPreg = $concurso->num_preguntas;
        $filas   = [];
        $errores  = 0;

        // Participantes existentes para detección de duplicados
        $existentes = ConcursoParticipante::where('concurso_id', $concurso->id)
            ->get()
            ->keyBy(fn($p) => strtoupper(trim($p->apellidos)) . '|' . strtoupper(trim($p->nombres)));

        for ($r = 1; $r < count($rows); $r++) {
            $row  = $rows[$r];
            $fila = [];

            foreach ($header as $i => $col) {
                $fila[$col] = trim((string)($row[$i] ?? ''));
            }

            // Saltar filas completamente vacías
            if (empty($fila['apellidos']) && empty($fila['nombres'])) continue;

            if (empty($fila['apellidos']) || empty($fila['nombres'])) {
                $errores++;
                $fila['_error'] = 'Apellidos o nombres vacíos';
            }

            // Respuestas P1..Pn
            $respuestas = [];
            for ($i = 1; $i <= $numPreg; $i++) {
                $k = 'p' . $i;
                $respuestas[$i] = isset($fila[$k]) ? trim($fila[$k]) : '';
                unset($fila[$k]);
            }
            $fila['_respuestas'] = $respuestas;

            // Normalizar tiempo al formato 24h desde el preview
            if (!empty($fila['tiempo'])) {
                $t    = trim((string)$fila['tiempo']);
                $dt12 = \DateTime::createFromFormat('g:i:s A', $t)
                     ?: \DateTime::createFromFormat('g:i A',   $t)
                     ?: \DateTime::createFromFormat('h:i:s A', $t)
                     ?: \DateTime::createFromFormat('h:i A',   $t);
                if ($dt12) {
                    $fila['tiempo'] = $dt12->format('H:i:s');
                } else {
                    $dt24 = \DateTime::createFromFormat('H:i:s', $t)
                         ?: \DateTime::createFromFormat('H:i',   $t)
                         ?: \DateTime::createFromFormat('G:i:s', $t)
                         ?: \DateTime::createFromFormat('G:i',   $t);
                    $fila['tiempo'] = $dt24 ? $dt24->format('H:i:s') : '';
                }
            }

            // Detectar duplicado
            $key = strtoupper(trim($fila['apellidos'])) . '|' . strtoupper(trim($fila['nombres']));
            if ($existentes->has($key)) {
                $fila['_duplicado']       = true;
                $fila['_participante_id'] = $existentes[$key]->id;
                $fila['_accion']          = 'actualizar';
            } else {
                $fila['_duplicado'] = false;
                $fila['_accion']    = 'agregar';
            }

            $filas[] = $fila;
        }

        return response()->json([
            'filas'   => $filas,
            'errores' => $errores,
            'total'   => count($filas),
            'columnas_respuesta' => $numPreg,
        ]);
    }

    /** Guarda los participantes masivamente según acciones seleccionadas */
    public function guardarMasivo(Request $request, Concurso $concurso)
    {
        // Siempre responder JSON aunque haya error
        try {
            $filas = $request->input('filas', []);

            if (empty($filas) || !is_array($filas)) {
                return response()->json(['ok' => false, 'message' => 'No se recibieron datos.'], 422);
            }

            $concurso->load('preguntas');
            $agregados    = 0;
            $actualizados = 0;
            $omitidos     = 0;

            foreach ($filas as $fila) {
                $accion = $fila['accion'] ?? 'agregar';

                if ($accion === 'omitir') {
                    $omitidos++;
                    continue;
                }

                $apellidos = strtoupper(trim($fila['apellidos'] ?? ''));
                $nombres   = trim($fila['nombres'] ?? '');

                if (!$apellidos || !$nombres) continue;

                // Respuestas: las claves vienen como strings desde JSON ("1","2"...)
                // convertimos a int para guardarRespuestas()
                $respuestasRaw = $fila['respuestas'] ?? [];
                $respuestas    = [];
                foreach ($respuestasRaw as $k => $v) {
                    $respuestas[(int)$k] = $v;
                }

                // Normalizar tiempo: soporta "01:15", "01:15:00", "11:42 AM", "11:42:00 AM"
                $tiempo = null;
                if (!empty($fila['tiempo'])) {
                    $t = trim((string)$fila['tiempo']);
                    // Intentar parsear formato 12h (AM/PM)
                    $dt12 = \DateTime::createFromFormat('g:i:s A', $t)
                         ?: \DateTime::createFromFormat('g:i A',   $t)
                         ?: \DateTime::createFromFormat('h:i:s A', $t)
                         ?: \DateTime::createFromFormat('h:i A',   $t);
                    if ($dt12) {
                        $tiempo = $dt12->format('H:i:s');
                    } else {
                        // Formato 24h: "HH:MM" o "HH:MM:SS"
                        $dt24 = \DateTime::createFromFormat('H:i:s', $t)
                             ?: \DateTime::createFromFormat('H:i',   $t)
                             ?: \DateTime::createFromFormat('G:i:s', $t)
                             ?: \DateTime::createFromFormat('G:i',   $t);
                        $tiempo = $dt24 ? $dt24->format('H:i:s') : null;
                    }
                }

                // Normalizar género
                $genero = null;
                if (!empty($fila['genero'])) {
                    $g = strtoupper(trim($fila['genero']));
                    if (in_array($g, ['M', 'F'])) $genero = $g;
                }

                $datos = [
                    'concurso_id' => $concurso->id,
                    'apellidos'   => $apellidos,
                    'nombres'     => $nombres,
                    'nivel'       => !empty($fila['nivel'])       ? trim($fila['nivel'])       : null,
                    'grado'       => !empty($fila['grado'])       ? trim($fila['grado'])       : null,
                    'seccion'     => !empty($fila['seccion'])     ? strtoupper(trim($fila['seccion'])) : null,
                    'genero'      => $genero,
                    'tiempo'      => $tiempo,
                    'observacion' => !empty($fila['observacion']) ? trim($fila['observacion']) : null,
                ];

                if ($accion === 'agregar') {
                    $participante = ConcursoParticipante::create($datos);
                    $this->guardarRespuestas($participante, $respuestas, $concurso->num_preguntas);
                    $agregados++;

                } elseif ($accion === 'actualizar') {
                    $pid = $fila['participante_id'] ?? null;
                    if ($pid) {
                        $participante = ConcursoParticipante::find((int)$pid);
                        if ($participante) {
                            $participante->update($datos);
                            $participante->respuestas()->delete();
                            $this->guardarRespuestas($participante, $respuestas, $concurso->num_preguntas);
                            $actualizados++;
                        }
                    } else {
                        // No tiene ID => agregar como nuevo
                        $participante = ConcursoParticipante::create($datos);
                        $this->guardarRespuestas($participante, $respuestas, $concurso->num_preguntas);
                        $agregados++;
                    }
                }
            }

            return response()->json([
                'ok'           => true,
                'agregados'    => $agregados,
                'actualizados' => $actualizados,
                'omitidos'     => $omitidos,
            ]);

        } catch (\Throwable $e) {
            return response()->json([
                'ok'      => false,
                'message' => $e->getMessage(),
                'file'    => basename($e->getFile()) . ':' . $e->getLine(),
            ], 500);
        }
    }
}
