<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Curso;
use App\Models\Periodo;
use App\Models\MatriculaCurso;
use App\Models\LogroCurso;
use App\Models\CursoDocente;
use Illuminate\Support\Facades\Auth;
use App\Models\NotaSubcomponente;
use App\Models\NotaLogro;
use App\Models\NotaFinal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Models\Instituto;
use App\Services\MoodleService;
use Illuminate\Http\JsonResponse;


class NotaCursoController extends Controller
{
    public function index($curso_id)
{
    $docente_id = Auth::user()->docente->id ?? null;

    // Verifica si el curso pertenece al docente autenticado
    $asignado = CursoDocente::where('curso_id', $curso_id)
        ->where('docente_id', $docente_id)
        ->exists();

    if (!$asignado) {
        abort(403, 'No tienes permiso para acceder a este curso.');
    }

    // Obtener curso y periodo activo
    $curso = Curso::findOrFail($curso_id);
    $periodoActivo = Periodo::where('activo', 1)->firstOrFail();

    // Obtener estudiantes matriculados en este curso y periodo
    $matriculados = MatriculaCurso::with(['matricula.postulante'])
        ->where('curso_id', $curso_id)
        ->whereHas('matricula', function ($query) use ($periodoActivo) {
            $query->where('periodo_id', $periodoActivo->id);
        })
        ->get();

    // Obtener logros y subcomponentes del curso
    $logros = LogroCurso::with('subcomponentes')
        ->where('curso_id', $curso_id)
        ->get();

    // Determinar si hay logros y/o subcomponentes
    $tieneLogros = $logros->isNotEmpty();
    $tieneSubcomponentes = $logros->flatMap->subcomponentes->isNotEmpty();

    // Obtener IDs de estudiantes
    $estudianteIds = $matriculados->pluck('matricula.postulante.id_postulante')->toArray();

    // Cargar notas existentes
    $notasSub = NotaSubcomponente::whereIn('estudiante_id', $estudianteIds)->get()->groupBy(function ($item) {
        return $item->estudiante_id . '_' . $item->subcomponente_id;
    });

    $notasLogros = NotaLogro::whereIn('estudiante_id', $estudianteIds)
        ->where('curso_id', $curso_id)
        ->get()->groupBy(function ($item) {
            return $item->estudiante_id . '_' . $item->logro_curso_id;
        });

    $notasFinales = NotaFinal::whereIn('estudiante_id', $estudianteIds)
        ->where('curso_id', $curso_id)
        ->get()->keyBy('estudiante_id');

    return view('docentes.notas.index', compact(
        'curso',
        'matriculados',
        'logros',
        'tieneLogros',
        'tieneSubcomponentes',
        'notasSub',
        'notasLogros',
        'notasFinales'
    ));
}

public function store(Request $request, $curso_id)
{
    DB::beginTransaction();

    try {

        /*
        |--------------------------------------------------------------------------
        | 1. Obtener todos los MatriculaCurso necesarios de una sola vez
        |--------------------------------------------------------------------------
        */
        $ids = collect([
            array_keys($request->input('notas', [])),
            array_keys($request->input('logro_total', [])),
            array_keys($request->input('logros_directos', [])),
            array_keys($request->input('nota_final', [])),
        ])->flatten()->unique()->filter();

        $matriculas = MatriculaCurso::with('matricula.postulante')
            ->whereIn('id', $ids)
            ->get()
            ->keyBy('id');

        /*
        |--------------------------------------------------------------------------
        | 2. Guardar NOTAS DE SUBCOMPONENTES
        |--------------------------------------------------------------------------
        */
        foreach ($request->input('notas', []) as $matriculaCursoId => $subNotas) {

            if (!isset($matriculas[$matriculaCursoId])) continue;

            $estudianteId = $matriculas[$matriculaCursoId]
                ->matricula->postulante->id_postulante;

            foreach ($subNotas as $subcomponenteId => $nota) {

                if ($nota === null || $nota === '') continue;

                NotaSubcomponente::updateOrCreate(
                    [
                        'estudiante_id'    => $estudianteId,
                        'subcomponente_id' => $subcomponenteId,
                    ],
                    [
                        'nota' => $nota,
                    ]
                );
            }
        }

        /*
        |--------------------------------------------------------------------------
        | 3. Guardar LOGROS CALCULADOS DESDE SUBCOMPONENTES
        |--------------------------------------------------------------------------
        */
        foreach ($request->input('logro_total', []) as $matriculaCursoId => $logrosTotales) {

            if (!isset($matriculas[$matriculaCursoId])) continue;

            $estudianteId = $matriculas[$matriculaCursoId]
                ->matricula->postulante->id_postulante;

            foreach ($logrosTotales as $logroId => $nota) {

                if ($nota === null || $nota === '') continue;

                NotaLogro::updateOrCreate(
                    [
                        'estudiante_id'   => $estudianteId,
                        'curso_id'        => $curso_id,
                        'logro_curso_id'  => $logroId,
                    ],
                    [
                        'nota' => $nota,
                    ]
                );
            }
        }

        /*
        |--------------------------------------------------------------------------
        | 4. Guardar LOGROS DIRECTOS (SIN SUBCOMPONENTES)
        |--------------------------------------------------------------------------
        */
        foreach ($request->input('logros_directos', []) as $matriculaCursoId => $logrosNotas) {

            if (!isset($matriculas[$matriculaCursoId])) continue;

            $estudianteId = $matriculas[$matriculaCursoId]
                ->matricula->postulante->id_postulante;

            foreach ($logrosNotas as $logroId => $nota) {

                if ($nota === null || $nota === '') continue;

                NotaLogro::updateOrCreate(
                    [
                        'estudiante_id'   => $estudianteId,
                        'curso_id'        => $curso_id,
                        'logro_curso_id'  => $logroId,
                    ],
                    [
                        'nota' => $nota,
                    ]
                );
            }
        }

        /*
        |--------------------------------------------------------------------------
        | 5. Guardar NOTA FINAL
        |--------------------------------------------------------------------------
        */
        foreach ($request->input('nota_final', []) as $matriculaCursoId => $notaFinal) {

            if (!isset($matriculas[$matriculaCursoId])) continue;
            if ($notaFinal === null || $notaFinal === '') continue;

            $estudianteId = $matriculas[$matriculaCursoId]
                ->matricula->postulante->id_postulante;

            NotaFinal::updateOrCreate(
                [
                    'estudiante_id' => $estudianteId,
                    'curso_id'      => $curso_id,
                ],
                [
                    'promedio' => $notaFinal,
                    'usuario'  => auth()->user()->name ?? 'sistema',
                ]
            );
        }

        DB::commit();

        return response()->json([
            'success' => true,
            'message' => 'Notas registradas correctamente.'
        ]);

    } catch (\Exception $e) {

        DB::rollBack();

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


public function generarReporte($curso_id)
{

    $docente_id = Auth::user()->docente->id ?? null;

    // Verifica si el curso pertenece al docente autenticado
    $asignado = CursoDocente::where('curso_id', $curso_id)
        ->where('docente_id', $docente_id)
        ->exists();

    if (!$asignado) {
        abort(403, 'No tienes permiso para acceder a este curso.');
    }
    // Obtener las notas y los datos relacionados con la matrícula
    $datos_notas = DB::table('matriculas as m')
        ->join('periodos as pe', 'pe.id', '=', 'm.periodo_id')
        ->join('planes_estudio as pl', 'pl.id', '=', 'm.plan_estudio_id')
        ->join('semestres as s', 's.id', '=', 'm.semestre_id')
        ->join('matricula_cursos as mc', 'm.id', '=', 'mc.matricula_id')
        ->join('cursos as c', 'mc.curso_id', '=', 'c.id')
        ->leftJoin('cursos_docentes as cd', 'cd.curso_id', '=', 'c.id')
        ->leftJoin('docentes as d', 'd.id', '=', 'cd.docente_id')
        ->join('logros_curso as lc', 'lc.curso_id', '=', 'c.id')
        ->join('postulantes as p', 'm.postulante_id', '=', 'p.id_postulante')
        ->leftJoin('notas_logros as nl', function($join) {
            $join->on('nl.estudiante_id', '=', 'p.id_postulante')
                 ->on('nl.curso_id', '=', 'c.id')
                 ->on('nl.logro_curso_id', '=', 'lc.id');
        })
        ->where('c.id', $curso_id)
        ->where('pe.activo', 1)
        ->select([
            'p.id_postulante as estudiante_id',
            DB::raw("CONCAT(p.apellidos, ' ', p.nombres) as estudiante_nombre"),
            'p.dni',
            'lc.nombre as logro_nombre',
            'nl.nota',
            'c.nombre as curso_nombre',
            'pl.nombre as carrera',
            's.nombre as semestre',
            'pe.nombre as periodo',
            DB::raw("CONCAT(d.apellido, ' ', d.nombre) as docente")
        ])
        ->orderBy('estudiante_nombre')
        ->get();

    if ($datos_notas->isEmpty()) {
        return back()->with('error', 'No se encontraron notas para este curso.');
    }

    // Procesar las notas y agrupación por estudiante
    $estudiantes = $this->formatearEstudiantes($datos_notas);
    $logros = $this->extraerLogros($datos_notas);

    // Calcular el promedio para cada estudiante
    foreach ($estudiantes as $key => $estudiante) {
        $notas = array_filter($estudiante['logros'], function ($logro) {
            return $logro !== 'N/A'; // Solo tomamos las notas válidas
        });
        $promedio = count($notas) > 0 ? array_sum($notas) / count($notas) : 0;
        $estudiantes[$key]['promedio'] = $promedio; // Añadimos el promedio al estudiante
    }

    // Obtener la información del instituto (solo lo necesario)
    $instituto_db = Instituto::first(); // Obtener datos del instituto

    $instituto = [
        'nombre' => $instituto_db->nombre ?? 'No disponible',
        'codigo_modular' => $instituto_db->codigo_modular ?? 'No disponible',
        'dre' => $instituto_db->dre ?? 'No disponible',
        'departamento' => $instituto_db->departamento ?? 'No disponible',
        'provincia' => $instituto_db->provincia ?? 'No disponible',
        'distrito' => $instituto_db->distrito ?? 'No disponible',
        'direccion' => $instituto_db->direccion ?? '',
        'telefono' => $instituto_db->telefono ?? '',
        'logo' => $instituto_db->logo, // Asumo que aquí tienes la ruta del logo
    ];

    // Recoger los datos específicos del curso
    $curso_info = [
        'carrera' => $datos_notas[0]->carrera ?? 'No disponible',
        'semestre' => $datos_notas[0]->semestre ?? 'No disponible',
        'periodo' => $datos_notas[0]->periodo ?? 'No disponible',
        'docente' => $datos_notas[0]->docente ?? 'No disponible',
        'curso' => $datos_notas[0]->curso_nombre ?? 'No disponible',
    ];

    // Obtener logo del instituto (base64 si es necesario)
    $logoPath = storage_path('app/public/' . $instituto['logo']);
    if (file_exists($logoPath)) {
        $imagenBase64 = base64_encode(file_get_contents($logoPath));
    } else {
        $imagenBase64 = null;
    }

    // Generar PDF con tamaño A3 y orientación landscape
    $pdf = Pdf::loadView('reportes.reporte-notas', compact('estudiantes', 'logros', 'instituto', 'curso_info', 'imagenBase64'))
    ->setPaper('a3', 'portrait');

    return $pdf->stream('reporte-notas.pdf');
}

public function generarRanking($curso_id)
{
    $docente_id = Auth::user()->docente->id ?? null;

    // Verifica si el curso pertenece al docente autenticado
    $asignado = CursoDocente::where('curso_id', $curso_id)
        ->where('docente_id', $docente_id)
        ->exists();

    if (!$asignado) {
        abort(403, 'No tienes permiso para acceder a este curso.');
    }

    // Mismo bloque de obtención de datos...
    $datos_notas = DB::table('matriculas as m')
        ->join('periodos as pe', 'pe.id', '=', 'm.periodo_id')
        ->join('planes_estudio as pl', 'pl.id', '=', 'm.plan_estudio_id')
        ->join('semestres as s', 's.id', '=', 'm.semestre_id')
        ->join('matricula_cursos as mc', 'm.id', '=', 'mc.matricula_id')
        ->join('cursos as c', 'mc.curso_id', '=', 'c.id')
        ->leftJoin('cursos_docentes as cd', 'cd.curso_id', '=', 'c.id')
        ->leftJoin('docentes as d', 'd.id', '=', 'cd.docente_id')
        ->join('logros_curso as lc', 'lc.curso_id', '=', 'c.id')
        ->join('postulantes as p', 'm.postulante_id', '=', 'p.id_postulante')
        ->leftJoin('notas_logros as nl', function($join) {
            $join->on('nl.estudiante_id', '=', 'p.id_postulante')
                ->on('nl.curso_id', '=', 'c.id')
                ->on('nl.logro_curso_id', '=', 'lc.id');
        })
        ->where('c.id', $curso_id)
        ->where('pe.activo', 1)
        ->select([
            'p.id_postulante as estudiante_id',
            DB::raw("CONCAT(p.apellidos, ' ', p.nombres) as estudiante_nombre"),
            'p.dni',
            'lc.nombre as logro_nombre',
            'nl.nota',
            'c.nombre as curso_nombre',
            'pl.nombre as carrera',
            's.nombre as semestre',
            'pe.nombre as periodo',
            DB::raw("CONCAT(d.apellido, ' ', d.nombre) as docente")
        ])
        ->get();

    if ($datos_notas->isEmpty()) {
        return back()->with('error', 'No se encontraron notas para este curso.');
    }

    $estudiantes = $this->formatearEstudiantes($datos_notas);
    $logros = $this->extraerLogros($datos_notas);

    // Calcular y agregar promedio
    foreach ($estudiantes as $key => $estudiante) {
        $notas = array_filter($estudiante['logros'], fn($n) => $n !== 'N/A');
        $promedio = count($notas) > 0 ? array_sum($notas) / count($notas) : 0;
        $estudiantes[$key]['promedio'] = round($promedio, 2);
    }

    // 👉 Ordenar por promedio descendente (ranking)
    usort($estudiantes, function ($a, $b) {
        return ($b['promedio'] ?? 0) <=> ($a['promedio'] ?? 0);
    });

    // Información del instituto
    $instituto_db = Instituto::first();
    $instituto = [
        'nombre' => $instituto_db->nombre ?? 'No disponible',
        'codigo_modular' => $instituto_db->codigo_modular ?? 'No disponible',
        'dre' => $instituto_db->dre ?? 'No disponible',
        'departamento' => $instituto_db->departamento ?? 'No disponible',
        'provincia' => $instituto_db->provincia ?? 'No disponible',
        'distrito' => $instituto_db->distrito ?? 'No disponible',
        'direccion' => $instituto_db->direccion ?? '',
        'telefono' => $instituto_db->telefono ?? '',
        'logo' => $instituto_db->logo,
    ];

    $curso_info = [
        'carrera' => $datos_notas[0]->carrera ?? 'No disponible',
        'semestre' => $datos_notas[0]->semestre ?? 'No disponible',
        'periodo' => $datos_notas[0]->periodo ?? 'No disponible',
        'docente' => $datos_notas[0]->docente ?? 'No disponible',
        'curso' => $datos_notas[0]->curso_nombre ?? 'No disponible',
    ];

    $logoPath = storage_path('app/public/' . $instituto['logo']);
    $imagenBase64 = file_exists($logoPath) ? base64_encode(file_get_contents($logoPath)) : null;

    // 👉 Cambia la vista a otra (ej. reporte-ranking)
    $pdf = Pdf::loadView('reportes.reporte-ranking', compact('estudiantes', 'logros', 'instituto', 'curso_info', 'imagenBase64'))
              ->setPaper('a3', 'portrait');

    return $pdf->stream('reporte-ranking.pdf');
}

public function generarNomina($curso_id)
{
    $docente_id = Auth::user()->docente->id ?? null;

    $asignado = CursoDocente::where('curso_id', $curso_id)
        ->where('docente_id', $docente_id)
        ->exists();

    if (!$asignado) {
        abort(403, 'No tienes permiso para acceder a este curso.');
    }

    $matriculados = DB::table('matriculas as m')
        ->join('matricula_cursos as mc', 'm.id', '=', 'mc.matricula_id')
        ->join('postulantes as p', 'm.postulante_id', '=', 'p.id_postulante')
        ->join('cursos as c', 'mc.curso_id', '=', 'c.id')
        ->join('semestres as s', 'm.semestre_id', '=', 's.id')
        ->join('periodos as pe', 'm.periodo_id', '=', 'pe.id')
        ->join('planes_estudio as pl', 'm.plan_estudio_id', '=', 'pl.id')
        ->leftJoin('cursos_docentes as cd', 'cd.curso_id', '=', 'c.id')
        ->leftJoin('docentes as d', 'cd.docente_id', '=', 'd.id')
        ->where('c.id', $curso_id)
        ->where('pe.activo', 1)
        ->select([
            'p.dni',
            DB::raw("CONCAT(p.apellidos, ' ', p.nombres) as nombre_estudiante"),
            'pl.nombre as carrera',
            'pe.nombre as periodo',
            's.nombre as semestre',
            'c.nombre as curso_nombre',
            DB::raw("CONCAT(d.apellido, ' ', d.nombre) as docente")
        ])
        ->distinct()
        ->orderBy('nombre_estudiante')
        ->get();

    if ($matriculados->isEmpty()) {
        return back()->with('error', 'No hay estudiantes matriculados en este curso.');
    }

    $instituto = Instituto::first();
    $logoPath = storage_path('app/public/' . $instituto?->logo);
    $imagenBase64 = $instituto && file_exists($logoPath) ? base64_encode(file_get_contents($logoPath)) : null;

    $curso_info = [
        'curso' => $matriculados[0]->curso_nombre,
        'carrera' => $matriculados[0]->carrera,
        'semestre' => $matriculados[0]->semestre,
        'periodo' => $matriculados[0]->periodo,
        'docente' => $matriculados[0]->docente,
    ];

    $pdf = Pdf::loadView('reportes.reporte-nomina', compact('matriculados', 'instituto', 'curso_info', 'imagenBase64'))
        ->setPaper('a3', 'portrait');

    return $pdf->stream('reporte-nomina.pdf');
}


private function formatearEstudiantes($datos_notas)
{
    $estudiantes = [];

    // Recorrer los datos de las notas y organizarlos por estudiante
    foreach ($datos_notas as $nota) {
        $estudiantes[$nota->estudiante_id]['nombre'] = $nota->estudiante_nombre;
        $estudiantes[$nota->estudiante_id]['dni'] = $nota->dni;

        // Crear un array para almacenar los logros y sus respectivas notas
        $estudiantes[$nota->estudiante_id]['logros'][$nota->logro_nombre] = $nota->nota;
    }

    return $estudiantes;
}
private function extraerLogros($datos_notas)
{
    $logros = [];

    // Recorrer los datos de las notas y extraer los logros únicos
    foreach ($datos_notas as $nota) {
        if (!in_array($nota->logro_nombre, $logros)) {
            $logros[] = $nota->logro_nombre;
        }
    }

    return $logros;
}

public function actaFinal($id)
{
    $cursoId = $id;

    $curso = Curso::with(['modulo', 'semestre', 'planesEstudio', 'docentes'])->findOrFail($cursoId);


    // 2. Datos del instituto
    $instituto = Instituto::first();
    
    $logoPath = public_path('storage/' . $instituto->logo);



    // 3. Estudiantes del curso
    $estudiantes = DB::select("
        SELECT 
            mc.id AS matricula_curso_id,
            CONCAT(p.apellidos, ' ', p.nombres) AS nombre,
            p.dni
        FROM matriculas m
        JOIN matricula_cursos mc ON m.id = mc.matricula_id
        JOIN cursos c ON mc.curso_id = c.id
        JOIN postulantes p ON m.postulante_id = p.id_postulante
        JOIN periodos pe ON pe.id = m.periodo_id
        WHERE c.id = ? AND pe.activo = 1
        ORDER BY nombre ASC
    ", [$cursoId]);

    // 4. Sesiones
    $sesiones = DB::table('sesiones')
        ->where('curso_id', $cursoId)
        ->orderBy('fecha')
        ->get();

    // 5. Asistencias
    $asistencias = DB::table('asistencias')
        ->whereIn('matricula_curso_id', collect($estudiantes)->pluck('matricula_curso_id'))
        ->get()
        ->groupBy('matricula_curso_id')
        ->map(function ($items) {
            return $items->keyBy('sesion_id');
        });

    // 6. Logros del curso
    $logros = DB::table('logros_curso')
        ->where('curso_id', $cursoId)
        ->get();

    // 7. Notas por logro
    $notas_logros = DB::select("
        SELECT 
            p.id_postulante AS id_estudiante,
            CONCAT(p.apellidos, ' ', p.nombres) AS nombre_estudiante,
            p.dni,
            lc.nombre AS nombre_logro,
            nl.nota AS nota_logro
        FROM matriculas m
        JOIN matricula_cursos mc ON m.id = mc.matricula_id
        JOIN cursos c ON mc.curso_id = c.id
        JOIN postulantes p ON m.postulante_id = p.id_postulante
        JOIN periodos pe ON pe.id = m.periodo_id
        JOIN logros_curso lc ON lc.curso_id = c.id
        LEFT JOIN notas_logros nl ON nl.estudiante_id = p.id_postulante AND nl.curso_id = c.id AND nl.logro_curso_id = lc.id
        WHERE c.id = ? AND pe.activo = 1
        ORDER BY nombre_estudiante ASC
    ", [$cursoId]);

    // Obtener el periodo activo del curso (si existe al menos una matrícula activa)
    $periodo = DB::table('matriculas as m')
    ->join('matricula_cursos as mc', 'm.id', '=', 'mc.matricula_id')
    ->join('periodos as p', 'p.id', '=', 'm.periodo_id')
    ->where('mc.curso_id', $cursoId)
    ->where('p.activo', 1)
    ->select('p.id', 'p.nombre')
    ->first();


    // Agrupación: estudiantes con notas por logro
    $lista_estudiantes = [];
    $lista_logros = [];

    foreach ($notas_logros as $fila) {
        $id = $fila->id_estudiante;
        $logro = $fila->nombre_logro;
        $nota = is_numeric($fila->nota_logro) ? round($fila->nota_logro) : 'N/A';

        if (!in_array($logro, $lista_logros)) {
            $lista_logros[] = $logro;
        }

        if (!isset($lista_estudiantes[$id])) {
            $lista_estudiantes[$id] = [
                'nombre' => $fila->nombre_estudiante,
                'dni' => $fila->dni,
                'logros' => [],
            ];
        }

        $lista_estudiantes[$id]['logros'][$logro] = $nota;
    }

    // Renderizar PDF
    $pdf = Pdf::loadView('reportes.acta_final', [
        'instituto' => $instituto,
        'logoPath' => $logoPath,
        'curso' => $curso,
        'estudiantes' => $estudiantes,
        'sesiones' => $sesiones,
        'asistencias' => $asistencias,
        'logros' => $logros,
        'periodo' => $periodo,
        'lista_estudiantes' => $lista_estudiantes,
        'lista_logros' => $lista_logros,
    ])->setPaper('a3', 'landscape');

    return $pdf->stream('acta_final_curso_' . $cursoId . '.pdf');
}
public function evaluacionesMoodle(int $cursoId): JsonResponse
{
    $curso = Curso::findOrFail($cursoId);

    if (!$curso->moodle_course_id) {
        return response()->json([
            'success' => false,
            'message' => 'El curso no está vinculado a Moodle'
        ]);
    }

    $moodle = app(\App\Services\MoodleService::class);
    $resp   = $moodle->obtenerEvaluacionesCurso($curso->moodle_course_id);

    if (isset($resp['exception'])) {
        return response()->json([
            'success' => false,
            'message' => $resp['message'] ?? 'Error Moodle'
        ]);
    }

    $evaluaciones = [];

    foreach ($resp['usergrades'] ?? [] as $user) {
        foreach ($user['gradeitems'] ?? [] as $item) {

            // SOLO actividades reales
            if ($item['itemtype'] !== 'mod') {
                continue;
            }

            $evaluaciones[$item['id']] = [
                'itemid' => $item['id'],
                'nombre' => $item['itemname'],
                'tipo'   => $item['itemmodule'],
                'max'    => $item['grademax'],
            ];
        }
    }

    return response()->json([
        'success'      => true,
        'evaluaciones' => array_values($evaluaciones)
    ]);
}



    /**
     * ================================
     * NOTAS DE UNA EVALUACIÓN MOODLE
     * ================================
     */
    public function notasEvaluacionMoodle(
        int $cursoId,
        int $itemId,
        MoodleService $moodle
    ): JsonResponse {

        // 1️⃣ Curso Laravel
        $curso = Curso::findOrFail($cursoId);

        if (!$curso->moodle_course_id) {
            return response()->json([
                'success' => false,
                'message' => 'El curso no está vinculado a Moodle'
            ]);
        }

        // 2️⃣ Llamada a Moodle
        $resp = $moodle->obtenerNotasEvaluacion(
            $curso->moodle_course_id,
            $itemId
        );

        if (isset($resp['exception'])) {
            return response()->json([
                'success' => false,
                'message' => $resp['message'] ?? 'Error al consultar Moodle'
            ]);
        }

        // 3️⃣ Procesar notas
        $usuarios = $resp['usergrades'] ?? [];
        $notas = [];

        foreach ($usuarios as $u) {

            if (!isset($u['gradeitems'][0])) {
                continue;
            }

            $item = $u['gradeitems'][0];

            $notas[] = [
                'userid'     => $u['userid'],
                'estudiante' => $u['userfullname'],
                'nota'       => $item['graderaw'] ?? null,
                'texto'      => $item['gradeformatted'] ?? '-',
                'max'        => $item['grademax'] ?? null,
            ];
        }

        return response()->json([
            'success' => true,
            'notas'   => $notas
        ]);
    }
public function estructuraLogrosCurso(int $cursoId): array
{
    $logros = LogroCurso::with('subcomponentes')
        ->where('curso_id', $cursoId)
        ->get();

    return $logros->map(function ($logro) {
        return [
            'id' => $logro->id,
            'nombre' => $logro->nombre,
            'subcomponentes' => $logro->subcomponentes->map(function ($sub) {
                return [
                    'id' => $sub->id,
                    'nombre' => $sub->nombre
                ];
            })->values()
        ];
    })->values()->toArray();
}
public function datosModalNotasMoodle(int $cursoId,int $itemId,MoodleService $moodle): JsonResponse 
{

    $curso = Curso::findOrFail($cursoId);

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

    // 🔹 1. Notas Moodle
    $resp = $moodle->obtenerNotasEvaluacion(
        $curso->moodle_course_id,
        $itemId
    );

    if (isset($resp['exception'])) {
        return response()->json([
            'success' => false,
            'message' => $resp['message'] ?? 'Error Moodle'
        ]);
    }

    // 🔹 2. Logros + subcomponentes (REUTILIZADO)
    $logros = $this->estructuraLogrosCurso($cursoId);

    // 🔹 3. Estudiantes + notas Moodle
    $estudiantes = [];

    foreach ($resp['usergrades'] ?? [] as $u) {

        if (!isset($u['gradeitems'][0])) continue;

        $item = $u['gradeitems'][0];

        $estudiantes[] = [
            'userid'     => $u['userid'],
            'estudiante' => $u['userfullname'],
            'nota'       => $item['graderaw'] ?? null,
            'logros'     => $logros
        ];
    }

    return response()->json([
        'success'     => true,
        'estudiantes' => $estudiantes,
        'logros'      => $logros
    ]);
}
public function importarNotasMoodle(
    Request $request,
    $cursoId,
    $itemId
): JsonResponse {

    $cursoId = (int) $cursoId;
    $itemId  = (int) $itemId;

    $data = $request->validate([
        'destinos' => 'required|array|min:1',
        'destinos.*.estudiante_id' => 'required|integer', // moodle_user_id
        'destinos.*.destino'       => 'required|string',
        'destinos.*.nota'          => 'nullable|numeric'
    ]);

    DB::beginTransaction();

    try {

        foreach ($data['destinos'] as $d) {

            $moodleUserId = (int) $d['estudiante_id']; // 👈 ID de Moodle
            $destino      = $d['destino'];
            $notaMoodle   = $d['nota'];

            if ($notaMoodle === null) {
                continue;
            }

            /**
             * =====================================
             * 1️⃣ Moodle → usuarios.id
             * =====================================
             */
            $usuarioId = DB::table('usuarios')
                ->where('moodle_user_id', $moodleUserId)
                ->value('id');

            if (!$usuarioId) {
                continue; // no vinculado
            }

            /**
             * =====================================
             * 2️⃣ usuarios.id → postulantes.id_postulante
             * =====================================
             */
            $postulanteId = DB::table('postulantes')
                ->where('usuario_id', $usuarioId)
                ->value('id_postulante');

            if (!$postulanteId) {
                continue; // no es estudiante
            }

            // ============================
            // DESTINO: NOTA FINAL
            // ============================
            if ($destino === 'final') {

                NotaFinal::updateOrCreate(
                    [
                        'curso_id'      => $cursoId,
                        'estudiante_id' => $postulanteId
                    ],
                    [
                        'promedio' => $notaMoodle
                    ]
                );
            }

            // ============================
            // DESTINO: LOGRO
            // ============================
            elseif (str_starts_with($destino, 'logro_')) {

                $logroId = (int) str_replace('logro_', '', $destino);

                NotaLogro::updateOrCreate(
                    [
                        'curso_id'       => $cursoId,
                        'estudiante_id'  => $postulanteId,
                        'logro_curso_id' => $logroId
                    ],
                    [
                        'nota' => $notaMoodle
                    ]
                );
            }

            // ============================
            // DESTINO: SUBCOMPONENTE
            // ============================
            elseif (str_starts_with($destino, 'sub_')) {

                $subId = (int) str_replace('sub_', '', $destino);

                NotaSubcomponente::updateOrCreate(
                    [
                        'subcomponente_id' => $subId,
                        'estudiante_id'    => $postulanteId
                    ],
                    [
                        'nota' => $notaMoodle
                    ]
                );
            }
        }

        DB::commit();

        return response()->json([
            'success' => true,
            'message' => 'Notas importadas correctamente'
        ]);

    } catch (\Throwable $e) {

        DB::rollBack();

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


}
