<?php

namespace App\Http\Controllers;

use App\Models\Calendario;
use App\Models\Empleado;
use App\Models\HojaTiempo;
use App\Models\Periodo;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;

class PeriodoController extends Controller
{
    public function index()
    {
        $periodos = Periodo::orderByDesc('anio')->orderByDesc('mes')->paginate(20);
        return view('periodos.index', compact('periodos'));
    }

    public function create()
    {
        $meses = Periodo::meses();
        $anios = range(date('Y') - 1, date('Y') + 2);
        $diaCorte = \App\Models\Configuracion::getInt('periodo_dia_corte', 25);
        return view('periodos.create', compact('meses', 'anios', 'diaCorte'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'mes'        => 'required|integer|between:1,12',
            'anio'       => 'required|integer|min:2020|max:2099',
            'dia_corte'  => 'nullable|integer|min:1|max:28',
        ]);

        // Día de corte: del día N (mes anterior) al día N-1 (mes seleccionado)
        $corte = $data['dia_corte'] ?? \App\Models\Configuracion::getInt('periodo_dia_corte', 25);

        $prevYear  = $data['mes'] == 1 ? $data['anio'] - 1 : $data['anio'];
        $prevMonth = $data['mes'] == 1 ? 12 : $data['mes'] - 1;

        $fechaInicio = Carbon::create($prevYear, $prevMonth, $corte)->startOfDay();
        $fechaFin    = Carbon::create($data['anio'], $data['mes'], $corte)->subDay()->endOfDay();

        // Verificar si ya existe
        if (Periodo::where('mes', $data['mes'])->where('anio', $data['anio'])->exists()) {
            return back()->withErrors(['mes' => 'Ya existe un período para ese mes y año.'])->withInput();
        }

        // Generar días del calendario para ese período si no existen
        $this->generarCalendario($fechaInicio, $fechaFin);

        $periodo = Periodo::create([
            'mes'          => $data['mes'],
            'anio'         => $data['anio'],
            'fecha_inicio' => $fechaInicio->format('Y-m-d'),
            'fecha_fin'    => $fechaFin->format('Y-m-d'),
            'activo'       => false,
            'cerrado'      => false,
        ]);

        return redirect()->route('periodos.index')
            ->with('success', "Período {$periodo->nombre_completo} creado ({$fechaInicio->format('d/m/Y')} al {$fechaFin->format('d/m/Y')}).");
    }

    public function activar(Periodo $periodo)
    {
        Periodo::where('activo', true)->update(['activo' => false]);
        $periodo->update(['activo' => true]);
        return back()->with('success', "Período {$periodo->nombre_completo} activado.");
    }

    public function inactivar(Periodo $periodo)
    {
        $periodo->update(['activo' => false]);
        return back()->with('success', "Período {$periodo->nombre_completo} inactivado.");
    }

    public function cerrar(Periodo $periodo)
    {
        $periodo->update(['cerrado' => true, 'activo' => false]);
        return back()->with('success', "Período {$periodo->nombre_completo} cerrado.");
    }

    public function crearHojas(Periodo $periodo)
    {
        $empleados = Empleado::activos()->get();
        $creadas = 0;
        foreach ($empleados as $emp) {
            HojaTiempo::firstOrCreate(
                ['empleado_id' => $emp->id, 'periodo_id' => $periodo->id],
                ['estado' => 'borrador']
            );
            $creadas++;
        }
        return back()->with('success', "Se crearon/verificaron {$creadas} hojas de tiempo.");
    }

    private function generarCalendario(Carbon $inicio, Carbon $fin): void
    {
        $cursor = $inicio->copy();
        while ($cursor->lte($fin)) {
            Calendario::firstOrCreate(
                ['fecha' => $cursor->format('Y-m-d')],
                [
                    'dia_semana' => (int) $cursor->dayOfWeek,
                    'es_festivo' => false,
                ]
            );
            $cursor->addDay();
        }
    }

    public function limpiar(Periodo $periodo)
    {
        if (!Auth::user()->esSupervisor()) abort(403);

        DB::transaction(function () use ($periodo) {
            foreach ($periodo->hojasTiempo as $hoja) {
                foreach ($hoja->entradas as $entrada) {
                    $entrada->comentarios()->delete();
                }
                $hoja->entradas()->delete();
            }
            $periodo->hojasTiempo()->update([
                'estado'       => 'borrador',
                'enviado_at'   => null,
                'aprobado_at'  => null,
                'aprobado_por' => null,
            ]);
        });

        return back()->with('success', "Período {$periodo->nombre_completo} limpiado — entradas eliminadas, hojas en borrador.");
    }

    public function destroy(Periodo $periodo)
    {
        if (!Auth::user()->esSupervisor()) abort(403);

        if ($periodo->activo) {
            return back()->with('error', 'No puedes eliminar el período activo. Activa otro primero.');
        }

        DB::transaction(function () use ($periodo) {
            foreach ($periodo->hojasTiempo as $hoja) {
                foreach ($hoja->entradas as $entrada) {
                    $entrada->comentarios()->delete();
                }
                $hoja->entradas()->delete();
            }
            $periodo->hojasTiempo()->delete();
            $periodo->delete();
        });

        return redirect()->route('periodos.index')
            ->with('success', "Período eliminado correctamente.");
    }
}
