<?php

namespace App\Http\Controllers;

use App\Models\Evaluaciones;
use App\Models\Evaluation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;

class EvaluacionesController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */

    private $disk = "public";

    public function index($id)
    {
        $evaluaciones = Evaluaciones::leftJoin('estados', 'estados.id', '=', 'evaluaciones.estado_id')
            ->leftJoin('t_g_parametros as tipo_evaluacion', 'tipo_evaluacion.nu_id_parametro', '=', 'evaluaciones.tipo_evaluacion_id')
            ->where('evaluaciones.grupo_de_evaluaciones_id', $id)
            ->whereNull('evaluaciones.deleted_at')
            ->select(
                'evaluaciones.*',
                'estados.nombre as estado_nombre',
                'tipo_evaluacion.tx_item_description as tipo_evaluacion_nombre'
            )
            ->get();

        return response()->json($evaluaciones);
    }

    public function getEvaluacionById($id)
    {
        // Buscar la evaluación por su ID
        $evaluacion = Evaluaciones::select(
            'id',
            'nombre',
            'tipo_evaluacion_id',
            'fecha_y_hora_programo',
            'observaciones',
            'estado_id',
            'domain_id',
            'created_at as fecha_creacion',
            'porcentaje_asignado',
            'grupo_de_evaluaciones_id',
            'modalidad',
            'contenido',
            'texto_enrriquesido'
        )
            ->where('id', $id)
            ->first();

        // Verificar si se encontró la evaluación
        if (!$evaluacion) {
            return response()->json(['message' => 'Evaluación no encontrada'], 404);
        }

        // Devolver los datos de la evaluación
        return response()->json($evaluacion);
    }

    /**
     * ✅ MODIFICADO: Actualizar evaluación con validación de porcentaje
     * 
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function updateEvaluacionById(Request $request, $id)
    {
        try {
            Log::info("🔄 Actualizando evaluación ID: {$id}");

            $validator = Validator::make($request->all(), [
                'nombre' => 'required|string|max:255',
                'tipo_evaluacion_id' => 'nullable|exists:t_g_parametros,nu_id_parametro',
                'porcentaje_evaluacion' => 'nullable|numeric',
                'porcentaje_asignado' => 'required|numeric|min:0|max:100', // ✅ Ahora required
                'fecha_y_hora_programo' => 'required|date',
                'observaciones' => 'nullable|string',
                'estado_id' => 'required|integer|in:1,2,3',
                'domain_id' => 'required|integer',
                'grupo_de_evaluaciones_id' => 'nullable|integer',
                'modalidad' => 'required|in:0,1',
                'recursos' => 'nullable|array',
                'recursos.*' => 'file|max:10240',
                'texto_enrriquesido' => 'nullable|string'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'errors' => $validator->errors()
                ], 422);
            }

            $validatedData = $validator->validated();

            // Buscar evaluación
            $evaluacion = Evaluaciones::find($id);

            if (!$evaluacion) {
                return response()->json([
                    'success' => false,
                    'message' => 'Evaluación no encontrada'
                ], 404);
            }

            // ✅ VALIDACIÓN CRÍTICA: Verificar porcentaje si cambió
            $porcentajeNuevo = (float) $validatedData['porcentaje_asignado'];
            $porcentajeAnterior = (float) $evaluacion->porcentaje_asignado;

            // Solo validar si el porcentaje cambió
            if ($porcentajeNuevo != $porcentajeAnterior) {
                Log::info("📊 Validando cambio de porcentaje: {$porcentajeAnterior}% → {$porcentajeNuevo}%");

                $grupoId = $evaluacion->grupo_de_evaluaciones_id;

                // Obtener porcentaje usado SIN incluir esta evaluación
                $porcentajeUsado = DB::table('evaluaciones')
                    ->where('grupo_de_evaluaciones_id', $grupoId)
                    ->where('id', '!=', $id) // ← Excluir evaluación actual
                    ->whereNull('deleted_at')
                    ->sum('porcentaje_asignado');

                $porcentajeDisponible = 100 - $porcentajeUsado;

                Log::info("📊 Porcentaje usado (sin esta evaluación): {$porcentajeUsado}%, disponible: {$porcentajeDisponible}%");

                // ✅ VALIDAR: No exceder el 100%
                if ($porcentajeNuevo > $porcentajeDisponible) {
                    Log::warning("⚠️ Porcentaje excedido en actualización");

                    return response()->json([
                        'success' => false,
                        'message' => "El porcentaje asignado excede el límite permitido",
                        'error' => "Porcentaje disponible: {$porcentajeDisponible}%",
                        'detalles' => [
                            'porcentaje_usado' => (float) $porcentajeUsado,
                            'porcentaje_disponible' => (float) $porcentajeDisponible,
                            'porcentaje_intentado' => $porcentajeNuevo,
                            'porcentaje_anterior' => $porcentajeAnterior
                        ]
                    ], 422);
                }
            }

            // ✅ Validación OK - Actualizar
            DB::beginTransaction();

            $evaluacion->update($validatedData);
            Log::info("✅ Evaluación actualizada - Nuevo porcentaje: {$porcentajeNuevo}%");

            // Manejar archivos
            $fileUrls = [];
            if ($request->hasFile('recursos')) {
                foreach ($request->file('recursos') as $file) {
                    $fileName = time() . '_' . uniqid() . '_' . $file->getClientOriginalName();
                    $path = $file->storeAs('uploads/evaluaciones', $fileName, 'public');
                    $fileUrl = Storage::url($path);
                    $fileUrls[] = $fileUrl;
                }

                if (!empty($fileUrls)) {
                    $evaluacion->contenido = json_encode($fileUrls);
                    $evaluacion->save();
                }
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Evaluación actualizada exitosamente',
                'data' => $evaluacion
            ], 200);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("❌ Error actualizando evaluación: " . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error al actualizar la evaluación',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * ✅ CORREGIDO: Obtener TODAS las evaluaciones del grupo (sin filtrar por alumno)
     * Para el selector de evaluaciones en el reporte de asistencia
     * 
     * @param int $grupoId ID del Indicador
     * @return \Illuminate\Http\JsonResponse
     */
    public function getEvaluacionesDelGrupo($grupoId)
    {
        try {
            Log::info("📋 Obteniendo evaluaciones del grupo: {$grupoId}");

            $evaluaciones = DB::table('evaluaciones as e')
                ->leftJoin('estados as es', 'e.estado_id', '=', 'es.id')
                ->leftJoin('t_g_parametros as tipo', 'tipo.nu_id_parametro', '=', 'e.tipo_evaluacion_id')
                ->where('e.grupo_de_evaluaciones_id', $grupoId)
                ->whereNull('e.deleted_at')
                ->select(
                    'e.id',
                    'e.nombre',
                    'e.fecha_y_hora_programo',
                    'e.porcentaje_asignado',
                    'es.nombre as estado_nombre',
                    'tipo.tx_item_description as tipo_evaluacion_nombre'
                )
                ->orderBy('e.fecha_y_hora_programo', 'asc')
                ->get();

            Log::info("✅ Evaluaciones encontradas: " . $evaluaciones->count());

            return response()->json($evaluaciones, 200);
        } catch (\Exception $e) {
            Log::error("❌ Error obteniendo evaluaciones: " . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error al obtener evaluaciones',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * ✅ CORREGIDO: Obtener asistencias con LEFT JOIN
     * Trae TODOS los alumnos del curso, tengan o no registro
     * 
     * @param int $evaluacionId
     * @param int $cursoId
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAsistenciasPorEvaluacion($evaluacionId, $cursoId)
    {
        try {
            Log::info("📊 Obteniendo asistencias - Evaluación: {$evaluacionId}, Curso: {$cursoId}");

            // Verificar que la evaluación existe
            $evaluacion = DB::table('evaluaciones')->where('id', $evaluacionId)->first();

            if (!$evaluacion) {
                Log::warning("⚠️ Evaluación no encontrada: {$evaluacionId}");
                return response()->json([
                    'success' => false,
                    'message' => 'Evaluación no encontrada'
                ], 404);
            }

            // Obtener TODOS los alumnos del curso con LEFT JOIN
            $asistencias = DB::table('curso_alumno as ca')
                ->join('alumnos as a', 'ca.alumno_id', '=', 'a.id')
                ->leftJoin('evaluaciones_alumno as ea', function ($join) use ($evaluacionId) {
                    $join->on('ea.alumno_id', '=', 'a.id')
                        ->where('ea.evaluacion_id', '=', $evaluacionId);
                })
                ->where('ca.curso_id', $cursoId)
                ->where('ca.estado_id', 2) // Solo alumnos EN PROCESO
                ->whereNull('a.deleted_at')
                ->select(
                    'a.id as alumno_id',
                    'a.nombres',
                    'a.apellidos',
                    'a.dni',
                    'a.codigo',
                    DB::raw('COALESCE(ea.asistencia, 0) as asistencia'),
                    DB::raw('COALESCE(ea.nota, 0) as nota'),
                    'ea.id as evaluacion_alumno_id'
                )
                ->orderBy('a.apellidos')
                ->orderBy('a.nombres')
                ->get();

            Log::info("✅ Total alumnos en curso: " . $asistencias->count());
            Log::info("✅ Alumnos con asistencia registrada: " . $asistencias->where('evaluacion_alumno_id', '!=', null)->count());

            return response()->json($asistencias, 200);
        } catch (\Exception $e) {
            Log::error("❌ Error obteniendo asistencias: " . $e->getMessage());
            Log::error("Stack trace: " . $e->getTraceAsString());

            return response()->json([
                'success' => false,
                'message' => 'Error al obtener asistencias',
                'error' => $e->getMessage()
            ], 500);
        }
    }



    /**
     * ✅ MODIFICADO: Crear evaluación con validación de porcentaje total
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        try {
            Log::info('🚀 Datos recibidos en store:', $request->all());

            // Validación básica
            $validator = Validator::make($request->all(), [
                'nombre' => 'required|string|max:255',
                'tipo_evaluacion_id' => 'nullable|exists:t_g_parametros,nu_id_parametro',
                'porcentaje_evaluacion' => 'nullable|numeric',
                'porcentaje_asignado' => 'required|numeric|min:0|max:100', // ✅ Ahora required
                'fecha_y_hora_programo' => 'required|date',
                'observaciones' => 'nullable|string',
                'texto_enrriquesido' => 'nullable|string',
                'estado_id' => 'required|integer',
                'domain_id' => 'required|integer',
                'grupo_de_evaluaciones_id' => 'required|integer',
                'modalidad' => 'required|in:0,1',
                'recursos' => 'nullable|array',
                'recursos.*' => 'file|max:10240'
            ]);

            if ($validator->fails()) {
                Log::error('❌ Error de validación:', $validator->errors()->toArray());
                return response()->json([
                    'success' => false,
                    'message' => 'Error de validación',
                    'errors' => $validator->errors()
                ], 422);
            }

            $validatedData = $validator->validated();

            // ✅ VALIDACIÓN CRÍTICA: Verificar suma de porcentajes
            $grupoId = $validatedData['grupo_de_evaluaciones_id'];
            $porcentajeNuevo = (float) $validatedData['porcentaje_asignado'];

            // Obtener porcentaje ya usado en el grupo
            $porcentajeUsado = DB::table('evaluaciones')
                ->where('grupo_de_evaluaciones_id', $grupoId)
                ->whereNull('deleted_at')
                ->sum('porcentaje_asignado');

            $porcentajeDisponible = 100 - $porcentajeUsado;

            Log::info("📊 Validación de porcentaje - Usado: {$porcentajeUsado}%, Nuevo: {$porcentajeNuevo}%, Disponible: {$porcentajeDisponible}%");

            // ✅ VALIDAR: No exceder el 100%
            if ($porcentajeNuevo > $porcentajeDisponible) {
                Log::warning("⚠️ Porcentaje excedido - Intentó asignar {$porcentajeNuevo}% pero solo hay {$porcentajeDisponible}% disponible");

                return response()->json([
                    'success' => false,
                    'message' => "El porcentaje asignado excede el límite permitido",
                    'error' => "Porcentaje disponible: {$porcentajeDisponible}%",
                    'detalles' => [
                        'porcentaje_usado' => (float) $porcentajeUsado,
                        'porcentaje_disponible' => (float) $porcentajeDisponible,
                        'porcentaje_intentado' => $porcentajeNuevo
                    ]
                ], 422);
            }

            // ✅ Validación OK - Continuar con la creación
            Log::info("✅ Validación de porcentaje exitosa");

            // Formatear la fecha
            $validatedData['fecha_y_hora_programo'] = Carbon::parse($validatedData['fecha_y_hora_programo'])
                ->format('Y-m-d H:i:s');

            $evaluacionData = collect($validatedData)->except('recursos')->toArray();

            DB::beginTransaction();

            // Crear la evaluación
            $evaluacion = Evaluaciones::create($evaluacionData);
            Log::info("✅ Evaluación creada con ID: {$evaluacion->id}");

            $fileUrls = [];

            // Procesar archivos
            if ($request->hasFile('recursos')) {
                $files = $request->file('recursos');

                if (!is_array($files)) {
                    $files = [$files];
                }

                foreach ($files as $file) {
                    if ($file && $file->isValid()) {
                        $fileName = time() . '_' . uniqid() . '_' . $file->getClientOriginalName();
                        $path = $file->storeAs('uploads/evaluaciones', $fileName, 'public');
                        $fileUrl = Storage::url($path);
                        $fileUrls[] = $fileUrl;

                        Log::info("📄 Archivo guardado: {$fileName}");
                    }
                }

                if (!empty($fileUrls)) {
                    $evaluacion->contenido = json_encode($fileUrls);
                    $evaluacion->save();
                    Log::info('📁 URLs de archivos guardadas:', $fileUrls);
                }
            }

            // Poblar evaluaciones_alumno
            $alumnosCreados = $this->poblarEvaluacionesAlumno($evaluacion->id, $evaluacion->grupo_de_evaluaciones_id);

            if ($alumnosCreados === false) {
                DB::rollBack();
                Log::error("❌ Error al poblar evaluaciones_alumno");

                return response()->json([
                    'success' => false,
                    'message' => 'Error al crear registros de alumnos'
                ], 500);
            }

            DB::commit();
            $evaluacion->refresh();

            Log::info("🎉 Evaluación creada exitosamente con {$alumnosCreados} alumnos");

            return response()->json([
                'success' => true,
                'message' => 'Evaluación creada exitosamente',
                'data' => [
                    'evaluacion' => $evaluacion,
                    'fileUrls' => $fileUrls,
                    'totalFiles' => count($fileUrls),
                    'alumnosCreados' => $alumnosCreados,
                    'porcentaje_usado_total' => (float) ($porcentajeUsado + $porcentajeNuevo),
                    'porcentaje_disponible' => (float) ($porcentajeDisponible - $porcentajeNuevo)
                ]
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('❌ Error al crear evaluación:', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Error interno del servidor',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Poblar automáticamente la tabla evaluaciones_alumno
     * al crear una nueva evaluación
     */
    private function poblarEvaluacionesAlumno($evaluacionId, $grupoId)
    {
        try {
            Log::info("🔧 Poblando evaluaciones_alumno para evaluación {$evaluacionId}");

            // Obtener curso_id
            $cursoId = DB::table('grupo_de_evaluaciones')
                ->where('id', $grupoId)
                ->value('curso_id');

            if (!$cursoId) {
                Log::error("❌ No se encontró el grupo {$grupoId}");
                return false;
            }

            Log::info("📚 Grupo encontrado - Curso ID: {$cursoId}");

            // ✅ CRÍTICO: INNER JOIN con alumnos para filtrar huérfanos
            $alumnos = DB::table('curso_alumno')
                ->join('alumnos', 'alumnos.id', '=', 'curso_alumno.alumno_id')
                ->where('curso_alumno.curso_id', $cursoId)
                ->where('curso_alumno.estado_id', 2)
                ->where('alumnos.estadoAlumno', '!=', 'RETIRADO')
                ->select('curso_alumno.alumno_id')
                ->distinct()
                ->pluck('curso_alumno.alumno_id');

            $totalAlumnos = $alumnos->count();
            Log::info("👥 Alumnos VÁLIDOS encontrados: {$totalAlumnos}");

            // ✅ LOG: Ver IDs que se van a insertar
            Log::info("📋 IDs de alumnos: " . $alumnos->take(10)->implode(', ') . '...');

            if ($totalAlumnos === 0) {
                Log::warning("⚠️ No hay alumnos válidos");
                return 0;
            }

            // Preparar datos
            $datos = [];
            $now = Carbon::now(); // ✅ USAR CARBON

            foreach ($alumnos as $alumnoId) {
                $datos[] = [
                    'evaluacion_id' => $evaluacionId,
                    'alumno_id' => $alumnoId,
                    'nota' => 0,
                    'asistencia' => 0,
                    'created_at' => $now,
                    'updated_at' => $now
                ];
            }

            // Insertar
            DB::table('evaluaciones_alumno')->insert($datos);

            Log::info("✅ {$totalAlumnos} registros insertados");
            return $totalAlumnos;
        } catch (\Exception $e) {
            Log::error("❌ Error: " . $e->getMessage());
            return false;
        }
    }


    /**
     * Método auxiliar para manejar la subida de archivos
     */
    private function handleFileUploads(Request $request, $evaluacionId)
    {
        $fileUrls = [];

        if ($request->hasFile('recursos')) {
            foreach ($request->file('recursos') as $file) {
                if ($file->isValid()) {
                    $fileName = $evaluacionId . '_' . time() . '_' . $file->getClientOriginalName();
                    $path = $file->storeAs('uploads/evaluaciones', $fileName, 'public');
                    $fileUrls[] = Storage::url($path);
                }
            }
        }

        return $fileUrls;
    }


    /**
     * Método para debugging - eliminar en producción
     */
    public function debug(Request $request)
    {
        return response()->json([
            'all_data' => $request->all(),
            'files' => $request->hasFile('recursos') ? 'Sí tiene archivos' : 'No tiene archivos',
            'file_count' => $request->hasFile('recursos') ? count($request->file('recursos')) : 0,
            'headers' => $request->headers->all(),
            'content_type' => $request->header('Content-Type')
        ]);
    }

    /**
     * ✅ NUEVO: Obtiene el porcentaje total usado en un Indicador
     * Endpoint: GET /api/evaluaciones/grupo/{grupoId}/porcentaje
     * 
     * @param int $grupoId ID del Indicador
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPorcentajeTotalGrupo($grupoId)
    {
        try {
            Log::info("📊 Calculando porcentaje total del grupo: {$grupoId}");

            // Verificar que el grupo existe
            $grupo = DB::table('grupo_de_evaluaciones')
                ->where('id', $grupoId)
                ->first();

            if (!$grupo) {
                return response()->json([
                    'success' => false,
                    'message' => 'Indicador no encontrado'
                ], 404);
            }

            // Sumar todos los porcentajes asignados del grupo
            $porcentajeUsado = DB::table('evaluaciones')
                ->where('grupo_de_evaluaciones_id', $grupoId)
                ->whereNull('deleted_at')
                ->sum('porcentaje_asignado');

            // Calcular porcentaje disponible
            $porcentajeDisponible = 100 - $porcentajeUsado;

            Log::info("✅ Porcentaje usado: {$porcentajeUsado}%, disponible: {$porcentajeDisponible}%");

            return response()->json([
                'success' => true,
                'porcentaje_usado' => (float) $porcentajeUsado,
                'porcentaje_disponible' => (float) $porcentajeDisponible,
                'grupo_id' => $grupoId
            ], 200);
        } catch (\Exception $e) {
            Log::error("❌ Error al calcular porcentaje del grupo: " . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error al obtener el porcentaje del grupo',
                'error' => $e->getMessage()
            ], 500);
        }
    }
    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Evaluaciones  $Evaluaciones
     * @return \Illuminate\Http\Response
     */
    public function show(Evaluaciones $Evaluaciones)
    {
        return response()->json($Evaluaciones);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Evaluaciones  $Evaluaciones
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Evaluaciones $Evaluaciones)
    {
        $validatedData = $this->validate($request, [
            'nombre' => 'required|string|max:255',
            'tipo_evaluacion_id' => 'nullable|exists:t_g_parametros,nu_id_parametro',
            'fecha_y_hora_programo' => 'required|date',
            'observaciones' => 'nullable|string',
            'estado_id' => 'required',
            'porcentaje_asignado' => 'nullable|numeric',
            'domain_id' => 'required|integer',
            'grupo_de_evaluaciones_id' => 'required|integer',
            'modalidad' => 'required|in:0,1'
        ]);

        $Evaluaciones->update($validatedData);
        return response()->json($Evaluaciones);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Evaluaciones  $Evaluaciones
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $grupo = Evaluaciones::withTrashed()->findOrFail($id);
        $grupo->forceDelete();

        return response()->json(['message' => 'Curso eliminado exitosamente'], 201);
    }

    public function getNotasPorAlumnoYGrupo($alumnoId, $grupoId)
    {
        try {
            // Modifica la consulta para incluir el nombre del estado
            $notas = DB::table('evaluaciones_alumno as ea')
                ->join('evaluaciones as e', 'ea.evaluacion_id', '=', 'e.id')
                ->leftJoin('estados as es', 'e.estado_id', '=', 'es.id') // Hacemos el JOIN con la tabla estados
                ->where('ea.alumno_id', $alumnoId)
                ->where('e.grupo_de_evaluaciones_id', $grupoId)
                ->select(
                    'ea.id as evaluacion_alumno_id', // ID de la tabla evaluaciones_alumno
                    'ea.nota',
                    'e.id as evaluacion_id',
                    'e.nombre',
                    'e.porcentaje_asignado',
                    'e.porcentaje_evaluacion',
                    'e.fecha_y_hora_programo',
                    'e.fecha_y_hora_realizo',
                    'e.observaciones',
                    'e.modalidad',
                    'e.contenido',
                    'ea.asistencia',
                    'es.nombre as estado_nombre', // Traemos el nombre del estado desde la tabla estados
                    'e.tipo_evaluacion_id'
                )
                ->get();

            return response()->json([
                'success' => true,
                'notas' => $notas
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener las notas del alumno: ' . $e->getMessage()
            ], 500);
        }
    }

    public function getPromedioPorAlumnoYGrupo($alumnoId, $grupoId)
    {
        try {
            $resultados = DB::table('evaluaciones_alumno as ea')
                ->join('evaluaciones as e', 'ea.evaluacion_id', '=', 'e.id')
                ->where('ea.alumno_id', $alumnoId)
                ->where('e.grupo_de_evaluaciones_id', $grupoId)
                ->select(
                    'ea.alumno_id',
                    'ea.nota',
                    'e.porcentaje_asignado'
                )
                ->get();

            return response()->json([
                'success' => true,
                'message' => 'Notas obtenidas correctamente log',
                'data' => $resultados
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener las notas y porcentajes: ' . $e->getMessage()
            ], 500);
        }
    }

    public function getEvaluacionesPorGrupo($grupoId, $alumnoId)
    {
        try {
            $evaluaciones = DB::table('evaluaciones_alumno as ea')
                ->join('evaluaciones as e', 'ea.evaluacion_id', '=', 'e.id')
                ->where('e.grupo_de_evaluaciones_id', $grupoId)
                ->where('ea.alumno_id', $alumnoId)
                ->select(
                    'ea.nota',
                    'e.nombre',
                    'e.porcentaje_asignado',
                    DB::raw('(ea.nota * e.porcentaje_asignado / 100) as nota_porcentual')  // Aquí calculamos la nota porcentual
                )
                ->get();

            return response()->json([
                'success' => true,
                'evaluaciones' => $evaluaciones,
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener las evaluaciones: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Actualizar el estado de "Aplicar en Cálculo" de una evaluación
     */
    public function updateAplicarEnCalculo(Request $request, $evaluacionId)
    {

        try {
            // Validación para Lumen
            $validator = Validator::make($request->all(), [
                'aplicar_en_calculo' => 'required|boolean'
            ]);

            if ($validator->fails()) {
                Log::warning('🟡 VALIDATION FAILED - updateAplicarEnCalculo', [
                    'evaluacion_id' => $evaluacionId,
                    'validation_errors' => $validator->errors(),
                    'request_data' => $request->all()
                ]);

                return response()->json([
                    'success' => false,
                    'message' => 'Datos de validación incorrectos',
                    'errors' => $validator->errors()
                ], 422);
            }

            $evaluacion = Evaluaciones::find($evaluacionId);

            if (!$evaluacion) {
                return response()->json([
                    'success' => false,
                    'message' => 'Evaluación no encontrada'
                ], 404);
            }

            $evaluacion->aplicar_en_calculo = $request->input('aplicar_en_calculo');
            $evaluacion->save();

            $response = [
                'success' => true,
                'message' => 'Estado de aplicación en cálculo actualizado correctamente',
                'data' => [
                    'evaluacion_id' => $evaluacionId,
                    'aplicar_en_calculo' => $evaluacion->aplicar_en_calculo
                ]
            ];

            return response()->json($response, 200);
        } catch (\Exception $e) {
            $errorResponse = [
                'success' => false,
                'message' => 'Error al actualizar el estado: ' . $e->getMessage()
            ];
            return response()->json($errorResponse, 500);
        }
    }

    public function subirRecursos(Request $request, $evaluacion_id)
    {
        // dd($request, $evaluacion_id);

        $this->validate($request, [
            'recursos' => 'required|array',
            'recursos.*' => 'file|mimes:jpg,png,pdf,mp4|max:10240' // Aceptar solo imágenes, PDFs y videos
        ]);

        $evaluacionId = $evaluacion_id;

        // Crear un array para guardar las rutas de los archivos
        $rutas = [];

        // Subir cada archivo y guardar su ruta
        foreach ($request->file('recursos') as $file) {
            // Generar un nombre único para cada archivo
            $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();  // Usar UUID para un nombre único

            // Guardar el archivo en la carpeta 'uploads' dentro de 'public' con el nombre único
            $path = $file->storeAs('uploads', $filename, $this->disk);  // Guardar en public/uploads

            // Agregar la ruta del archivo al array
            $rutas[] = $path;
        }

        // Convertir el array de rutas a formato JSON
        $evaluacion = Evaluaciones::find($evaluacionId);
        $evaluacionesJson = json_encode($rutas);

        if ($evaluacion) {
            // Actualizar el campo 'contenido' de la evaluación con las nuevas rutas
            $evaluacion->contenido = $evaluacionesJson;  // Guardar las rutas en el campo 'contenido'
            $evaluacion->save();

            return response()->json(['message' => 'Archivos subidos correctamente.']);
        } else {
            return response()->json(['error' => 'Evaluación no encontrada.'], 404);
        }
    }

    /**
     * Obtiene las notas y porcentajes asignados de un alumno en un grupo específico
     * 
     * @param int $alumnoId ID del alumno
     * @param int $grupoId ID del Indicador
     * @return \Illuminate\Http\JsonResponse
     */
    public function getNotasYPorcentajesPorAlumnoYGrupo($alumnoId, $grupoId)
    {
        try {
            $resultados = DB::table('evaluaciones_alumno as ea')
                ->join('evaluaciones as e', 'ea.evaluacion_id', '=', 'e.id')
                ->where('ea.alumno_id', $alumnoId)
                ->where('e.grupo_de_evaluaciones_id', $grupoId)
                ->select(
                    'ea.alumno_id',
                    'ea.nota',
                    'e.porcentaje_asignado'
                )
                ->get();

            return response()->json([
                'success' => true,
                'data' => $resultados
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error al obtener las notas y porcentajes: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * ✅ Exportar notas con configuración personalizable de dimensiones
     * GET /api/exportar-notas-curso/{cursoId}
     */
    public function exportarNotasCurso($cursoId)
    {
        try {
            // ========== ⚙️ CONFIGURACIÓN DE DIMENSIONES (EDITABLE) ==========

            $config = [
                // 📏 ANCHOS DE COLUMNAS (en unidades Excel)
                'anchos' => [
                    'numero' => 16,                      // Columna N°
                    'apellidos_nombres' => 30,          // Columna APELLIDOS Y NOMBRES
                    'indicadores' => 40,                 // Cada columna de indicador (1, 2, 3...)
                    'promedio' => 20,                   // Columna Promedio
                    'evaluacion_recuperacion' => 15,   // Columna Evaluación de Recuperación
                    'nota_final' => 10                  // Columna Nota Final
                ],

                // 📐 ALTURAS DE FILAS (en puntos)
                'alturas' => [
                    'header_fila_1' => 60,  // Fila 1 del header (títulos principales)
                    'header_fila_2' => 25,  // Fila 2 del header (números de indicadores)
                    'datos' => 15           // Filas de datos de alumnos (opcional)
                ]
            ];

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

            Log::info("📊 Exportando notas del curso: {$cursoId}");

            // ========== 1️⃣ OBTENER DATOS ==========

            $curso = DB::table('cursos')
                ->where('id', $cursoId)
                ->first();

            if (!$curso) {
                return response()->json([
                    'success' => false,
                    'message' => 'Curso no encontrado'
                ], 404);
            }

            $alumnos = DB::table('curso_alumno as ca')
                ->join('alumnos as a', 'ca.alumno_id', '=', 'a.id')
                ->where('ca.curso_id', $cursoId)
                ->where('ca.estado_id', 2)
                ->whereNull('a.deleted_at')
                ->select(
                    'a.id',
                    'a.codigo',
                    'a.nombres',
                    'a.apellidos',
                    DB::raw("CONCAT(a.apellidos, ' ', a.nombres) as nombre_completo"),
                    'ca.id as curso_alumno_id'
                )
                ->orderBy('a.apellidos')
                ->orderBy('a.nombres')
                ->get();

            if ($alumnos->isEmpty()) {
                return response()->json([
                    'success' => false,
                    'message' => 'No hay alumnos en este curso'
                ], 404);
            }

            $recuperacionData = DB::table('curso_alumno')
                ->whereIn('alumno_id', $alumnos->pluck('id'))
                ->where('curso_id', $cursoId)
                ->select(
                    'alumno_id',
                    'nota_recuperacion',
                    'sistema_recuperacion',
                    'criterio_nota_final'
                )
                ->get()
                ->keyBy('alumno_id');

            $indicadores = DB::table('grupo_de_evaluaciones')
                ->where('curso_id', $cursoId)
                ->whereNull('deleted_at')
                ->select('id', 'nombre_del_grupo')
                ->orderBy('id')
                ->get();

            $evaluacionesPorIndicador = [];

            foreach ($indicadores as $indicador) {
                $evaluaciones = DB::table('evaluaciones')
                    ->where('grupo_de_evaluaciones_id', $indicador->id)
                    ->whereNull('deleted_at')
                    ->select('id', 'nombre', 'porcentaje_asignado')
                    ->orderBy('fecha_y_hora_programo')
                    ->get();

                $evaluacionesPorIndicador[$indicador->id] = $evaluaciones;
            }

            $alumnoIds = $alumnos->pluck('id')->toArray();
            $evaluacionIds = collect($evaluacionesPorIndicador)
                ->flatten()
                ->pluck('id')
                ->toArray();

            $notas = DB::table('evaluaciones_alumno as ea')
                ->join('evaluaciones as e', 'ea.evaluacion_id', '=', 'e.id')
                ->whereIn('ea.alumno_id', $alumnoIds)
                ->whereIn('ea.evaluacion_id', $evaluacionIds)
                ->select(
                    'ea.alumno_id',
                    'ea.evaluacion_id',
                    'ea.nota',
                    'e.grupo_de_evaluaciones_id',
                    'e.porcentaje_asignado'
                )
                ->get()
                ->groupBy('alumno_id');

            $promediosPorAlumno = [];

            foreach ($alumnos as $alumno) {
                $notasAlumno = $notas->get($alumno->id, collect());

                $promediosIndicadores = [];
                $sumaPromedios = 0;
                $cantIndicadores = 0;

                foreach ($indicadores as $indicador) {
                    $notasIndicador = $notasAlumno->where('grupo_de_evaluaciones_id', $indicador->id);

                    if ($notasIndicador->isEmpty()) {
                        $promediosIndicadores[$indicador->id] = 0;
                    } else {
                        $promedio = $notasIndicador->sum(function ($nota) {
                            return ($nota->nota * $nota->porcentaje_asignado) / 100;
                        });

                        $promediosIndicadores[$indicador->id] = round($promedio, 2);
                        $sumaPromedios += $promedio;
                        $cantIndicadores++;
                    }
                }

                $promedioGeneral = $cantIndicadores > 0
                    ? round($sumaPromedios / $cantIndicadores, 2)
                    : 0;

                $datosRecup = $recuperacionData->get($alumno->id);
                $notaRecuperacion = $datosRecup && isset($datosRecup->nota_recuperacion)
                    ? (float) $datosRecup->nota_recuperacion
                    : 0;
                $sistema = $datosRecup && isset($datosRecup->sistema_recuperacion)
                    ? $datosRecup->sistema_recuperacion
                    : null;
                $criterio = $datosRecup && isset($datosRecup->criterio_nota_final)
                    ? $datosRecup->criterio_nota_final
                    : null;

                $notaFinal = 0;

                if ($notaRecuperacion > 0 && $sistema) {
                    if ($criterio === 'nota_mas_alta') {
                        $notaFinal = max($promedioGeneral, $notaRecuperacion);
                    } else {
                        $notaFinal = $notaRecuperacion;
                    }
                } else {
                    $notaFinal = $promedioGeneral;
                }

                $promediosPorAlumno[$alumno->id] = [
                    'indicadores' => $promediosIndicadores,
                    'promedio_general' => $promedioGeneral,
                    'nota_recuperacion' => $notaRecuperacion,
                    'nota_final' => round($notaFinal, 2)
                ];
            }

            Log::info("✅ Datos obtenidos - Alumnos: {$alumnos->count()}, Indicadores: {$indicadores->count()}");

            // ========== 2️⃣ CREAR EXCEL ==========

            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();

            // ========== CALCULAR COLUMNAS ==========
            $colIndex = 1;

            $colNumero = $colIndex++;
            $colNombres = $colIndex++;

            $columnasIndicadores = [];

            foreach ($indicadores as $indicador) {
                $columnasIndicadores[$indicador->id] = $colIndex;
                $colIndex++;
            }

            $colPromedio = $colIndex++;
            $colRecuperacion = $colIndex++;
            $colNotaFinal = $colIndex++;

            $totalColumnas = $colIndex - 1;
            $ultimaColumna = $this->getColumnLetter($totalColumnas);
            $primeraColumnaIndicador = $this->getColumnLetter(3);
            $ultimaColumnaIndicador = $this->getColumnLetter(2 + count($indicadores));

            // ========== FILA 1-2: HEADERS ==========

            $sheet->setCellValue('A1', 'Nº de Orden');
            $sheet->mergeCells('A1:A2');

            $sheet->setCellValue('B1', "APELLIDOS Y NOMBRES\n(En orden alfabético)");
            $sheet->mergeCells('B1:B2');

            $sheet->setCellValue('C1', 'INDICADORES DE LOGRO');
            $sheet->mergeCells('C1:' . $ultimaColumnaIndicador . '1');

            $numeroIndicador = 1;
            foreach ($indicadores as $indicador) {
                $colLetra = $this->getColumnLetter($columnasIndicadores[$indicador->id]);
                $sheet->setCellValue($colLetra . '2', $numeroIndicador);
                $numeroIndicador++;
            }

            $colLetraPromedio = $this->getColumnLetter($colPromedio);
            $sheet->setCellValue($colLetraPromedio . '1', 'Promedio');
            $sheet->mergeCells($colLetraPromedio . '1:' . $colLetraPromedio . '2');

            $colLetraRecup = $this->getColumnLetter($colRecuperacion);
            $sheet->setCellValue($colLetraRecup . '1', "Evaluación de\nRecuperación");
            $sheet->mergeCells($colLetraRecup . '1:' . $colLetraRecup . '2');

            $colLetraFinal = $this->getColumnLetter($colNotaFinal);
            $sheet->setCellValue($colLetraFinal . '1', 'Nota Final');
            $sheet->mergeCells($colLetraFinal . '1:' . $colLetraFinal . '2');

            // ========== ESTILOS DEL HEADER ==========

            $headerRange = 'A1:' . $ultimaColumna . '2';

            $sheet->getStyle($headerRange)->applyFromArray([
                'font' => [
                    'bold' => true,
                    'size' => 9
                ],
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical' => Alignment::VERTICAL_CENTER,
                    'wrapText' => true
                ],
                'borders' => [
                    'allBorders' => [
                        'borderStyle' => Border::BORDER_THIN,
                        'color' => ['rgb' => '000000']
                    ]
                ]
            ]);

            $sheet->getStyle($headerRange)->getFill()
                ->setFillType(Fill::FILL_SOLID)
                ->getStartColor()->setRGB('F2F2F2');

            // ✅ APLICAR ALTURAS CONFIGURABLES
            $sheet->getRowDimension(1)->setRowHeight($config['alturas']['header_fila_1']);
            $sheet->getRowDimension(2)->setRowHeight($config['alturas']['header_fila_2']);

            // ========== DATOS DE ALUMNOS ==========
            $row = 3;
            $numero = 1;

            foreach ($alumnos as $alumno) {
                $datosAlumno = $promediosPorAlumno[$alumno->id];

                $sheet->setCellValue('A' . $row, str_pad($numero, 2, '0', STR_PAD_LEFT));
                $sheet->setCellValue('B' . $row, $alumno->nombre_completo);

                foreach ($indicadores as $indicador) {
                    $colLetra = $this->getColumnLetter($columnasIndicadores[$indicador->id]);
                    $promedio = $datosAlumno['indicadores'][$indicador->id];
                    $sheet->setCellValue($colLetra . $row, $promedio > 0 ? $promedio : '');
                }

                $sheet->setCellValue($colLetraPromedio . $row, $datosAlumno['promedio_general']);
                $sheet->setCellValue($colLetraRecup . $row, $datosAlumno['nota_recuperacion'] > 0 ? $datosAlumno['nota_recuperacion'] : '');
                $sheet->setCellValue($colLetraFinal . $row, $datosAlumno['nota_final']);

                // ✅ APLICAR ALTURA CONFIGURABLE A FILAS DE DATOS (opcional)
                if (isset($config['alturas']['datos'])) {
                    $sheet->getRowDimension($row)->setRowHeight($config['alturas']['datos']);
                }

                $row++;
                $numero++;
            }

            // ========== ✅ APLICAR ANCHOS CONFIGURABLES ==========

            $sheet->getColumnDimension('A')->setWidth($config['anchos']['numero']);
            $sheet->getColumnDimension('B')->setWidth($config['anchos']['apellidos_nombres']);

            // Indicadores
            foreach ($indicadores as $indicador) {
                $colLetra = $this->getColumnLetter($columnasIndicadores[$indicador->id]);
                $sheet->getColumnDimension($colLetra)->setWidth($config['anchos']['indicadores']);
            }

            $sheet->getColumnDimension($colLetraPromedio)->setWidth($config['anchos']['promedio']);
            $sheet->getColumnDimension($colLetraRecup)->setWidth($config['anchos']['evaluacion_recuperacion']);
            $sheet->getColumnDimension($colLetraFinal)->setWidth($config['anchos']['nota_final']);

            // ========== BORDES Y ALINEACIONES ==========

            $dataRange = 'A1:' . $ultimaColumna . ($row - 1);

            $sheet->getStyle($dataRange)->applyFromArray([
                'borders' => [
                    'allBorders' => [
                        'borderStyle' => Border::BORDER_THIN,
                        'color' => ['rgb' => '000000']
                    ]
                ]
            ]);

            $sheet->getStyle('A3:A' . ($row - 1))->getAlignment()
                ->setHorizontal(Alignment::HORIZONTAL_CENTER)
                ->setVertical(Alignment::VERTICAL_CENTER);

            $sheet->getStyle('B3:B' . ($row - 1))->getAlignment()
                ->setHorizontal(Alignment::HORIZONTAL_LEFT)
                ->setVertical(Alignment::VERTICAL_CENTER);

            $sheet->getStyle('C3:' . $ultimaColumna . ($row - 1))->getAlignment()
                ->setHorizontal(Alignment::HORIZONTAL_CENTER)
                ->setVertical(Alignment::VERTICAL_CENTER);

            // ========== GENERAR ARCHIVO ==========
            $writer = new Xlsx($spreadsheet);
            $fileName = 'Notas_' . preg_replace('/[^A-Za-z0-9_\-]/', '_', $curso->codigo ?? $curso->nombre) .
                '_' . Carbon::now()->format('Ymd_His') . '.xlsx';

            $tempFile = tempnam(sys_get_temp_dir(), $fileName);
            $writer->save($tempFile);

            Log::info("✅ Excel generado: {$fileName}");

            return response()->download($tempFile, $fileName)->deleteFileAfterSend(true);
        } catch (\Exception $e) {
            Log::error("❌ Error exportando notas: " . $e->getMessage());
            Log::error("Stack trace: " . $e->getTraceAsString());

            return response()->json([
                'success' => false,
                'message' => 'Error al exportar notas',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * ✅ Aplicar color a celda según nota
     */
    private function aplicarColorNota($sheet, $cell, $nota)
    {
        $notaFloat = (float) $nota;

        if ($notaFloat >= 14) {
            $sheet->getStyle($cell)->getFont()->getColor()->setRGB('006100');
        } elseif ($notaFloat >= 11) {
            $sheet->getStyle($cell)->getFont()->getColor()->setRGB('9C6500');
        } else {
            $sheet->getStyle($cell)->getFont()->getColor()->setRGB('9C0006');
        }
    }

    /**
     * ✅ Convertir índice numérico a letra de columna Excel
     */
    private function getColumnLetter($columnIndex)
    {
        $letter = '';
        while ($columnIndex > 0) {
            $temp = ($columnIndex - 1) % 26;
            $letter = chr($temp + 65) . $letter;
            $columnIndex = ($columnIndex - $temp - 1) / 26;
        }
        return $letter;
    }
}
