<?php

namespace App\Http\Controllers\Academico;

use App\Http\Controllers\Controller;
use App\Http\Requests\Academico\CicloRequest;
use App\Models\Academico\Ciclo;
use App\Models\PivoteHorario;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;

class CicloController extends Controller
{
    private function searchCiclos(string $search): Builder
    {
        return Ciclo::where(function ($query) use ($search) {
            $query->where('nombre', 'like', "%$search%");
        });
    }

    public function getAll(Request $request): JsonResponse
    {
        $query = Ciclo::query();
        $pagination = $request->input('pagination', 10);
        $search = $request->input('search');

        if ($search) {
            $query = $this->searchCiclos($search);
        }

        $ciclos = $query->with('pivote_horarios.horario')->latest()->paginate($pagination)->appends($request->query());

        return response()->json(
            [
                'ciclos' => $ciclos,
                'params' => $request->query() ?: null,
            ],
            200,
        );
    }

    public function show($id): JsonResponse
    {
        $ciclo = Ciclo::findOrFail($id);

        if (!$ciclo) {
            return response()->json(['message' => 'Ciclo no encontrado.'], 404);
        }

        return response()->json(
            [
                'ciclo' => $ciclo,
                'message' => 'Ciclo: ' . $ciclo->nombre . ', encontrado exitosamente!.',
            ],
            200,
        );
    }

    public function save(CicloRequest $request): JsonResponse
    {
        $ciclo = Ciclo::create($request->validated());

        $ciclo->save();

        $horarios = $request->horarios;

        foreach ($horarios as $horario) {
            PivoteHorario::create([
                'id_horario' => $horario['id'],
                'id_ciclo' => $ciclo->id,
            ]);
        }

        return response()->json(
            [
                'ciclo' => $ciclo,
                'message' => 'El ciclo: ' . $ciclo->nombre . ', se ha creado exitosamente!.',
            ],
            201,
        );
    }

    public function update($id, CicloRequest $request): JsonResponse
    {
        $ciclo = Ciclo::findOrFail($id);

        if (!$ciclo) {
            return response()->json(['message' => 'El ciclo ' . $request->nombre . ' no se encontró.'], 404);
        }

        $ciclo->update($request->validated());

        $ciclo->save();

        $nuevosHorarios = collect($request->horarios)->pluck('id');

        $horariosActuales = $ciclo->pivote_horarios()->pluck('id_horario');

        $horariosParaEliminar = $horariosActuales->diff($nuevosHorarios);

        $ciclo->pivote_horarios()->whereIn('id_horario', $horariosParaEliminar)->delete();

        $horariosParaAgregar = $nuevosHorarios->diff($horariosActuales);

        foreach ($horariosParaAgregar as $idHorario) {
            PivoteHorario::create([
                'id_horario' => $idHorario,
                'id_ciclo' => $ciclo->id,
            ]);
        }

        return response()->json(
            [
                'ciclo' => $ciclo,
                'message' => 'El ciclo: ' . $ciclo->nombre . ' se ha actualizado exitosamente.',
            ],
            200,
        );
    }

    public function delete($id): JsonResponse
    {
        $ciclo = Ciclo::findOrFail($id);

        if (!$ciclo) {
            return response()->json(['message' => 'Ciclo no encontrado.'], 404);
        }

        $ciclo->delete();

        return response()->json(
            [
                'message' => 'El ciclo: ' . $ciclo->nombre . ', se ha eliminado exitosamente!.',
            ],
            200,
        );
    }
}
