<?php

namespace App\Http\Controllers;

use App\Models\Empleado;
use App\Models\HojaTiempo;
use App\Models\Periodo;
use App\Services\HojaTiempoService;
use Dompdf\Dompdf;
use Dompdf\Options;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ReporteController extends Controller
{
    public function __construct(protected HojaTiempoService $service) {}

    private function soloSupervisor(): void
    {
        if (!Auth::user()->puedeVerReportes()) abort(403);
    }

    private function autorizarHoja(HojaTiempo $hojaTiempo): void
    {
        $user = Auth::user();
        if ($user->esSupervisor()) return;
        if (!$user->empleado_id || $user->empleado_id !== $hojaTiempo->empleado_id) abort(403);
    }

    /** Genera un PDF con Dompdf directo (evita "Cannot resolve public path") */
    private function generarPdf(string $view, array $datos, string $papel = 'a4', string $ori = 'portrait'): Dompdf
    {
        $opts = new Options();
        $opts->setChroot(public_path());
        $opts->setIsRemoteEnabled(false);
        $opts->setIsHtml5ParserEnabled(true);
        $opts->setDefaultFont('DejaVu Sans');

        $dompdf = new Dompdf($opts);
        $dompdf->loadHtml(view($view, $datos)->render(), 'UTF-8');
        $dompdf->setPaper($papel, $ori);
        $dompdf->render();
        return $dompdf;
    }

    private function descargar(Dompdf $dompdf, string $nombre)
    {
        return response($dompdf->output(), 200, [
            'Content-Type'        => 'application/pdf',
            'Content-Disposition' => "attachment; filename=\"{$nombre}\"",
        ]);
    }

    // ─── VISTAS ────────────────────────────────────────────

    public function consolidado(Request $request)
    {
        $this->soloSupervisor();
        $periodos = Periodo::orderByDesc('anio')->orderByDesc('mes')->get();
        $periodo  = $request->periodo_id ? Periodo::findOrFail($request->periodo_id) : Periodo::activo()->first();
        $datos    = $periodo ? $this->service->consolidadoPeriodo($periodo) : collect();
        return view('reportes.consolidado', compact('datos','periodo','periodos'));
    }

    // ─── PDF 1 — Hoja de Tiempo individual ─────────────────

    public function pdfHoja(HojaTiempo $hojaTiempo)
    {
        $this->autorizarHoja($hojaTiempo);
        $hojaTiempo->load(['empleado','periodo']);
        $grilla  = $this->service->construirGrilla($hojaTiempo);
        $resumen = $this->service->calcularResumen($hojaTiempo);

        $dompdf = $this->generarPdf(
            'reportes.pdf.hoja-tiempo',
            compact('hojaTiempo','grilla','resumen'),
            'a3', 'landscape'
        );
        $nombre = "HojaTiempo_{$hojaTiempo->empleado->cedula}_{$hojaTiempo->periodo->nombre_completo}.pdf";
        return $this->descargar($dompdf, $nombre);
    }

    // ─── PDF 2 — Consolidado por empleado ──────────────────

    public function pdfConsolidadoEmpleado(Request $request)
    {
        $this->soloSupervisor();
        $periodo = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $datos   = $this->service->consolidadoEmpleadoPdf($periodo);

        $dompdf = $this->generarPdf(
            'reportes.pdf.consolidado-empleado',
            compact('datos','periodo'),
            'a3', 'landscape'
        );
        return $this->descargar($dompdf, "Consolidado_Empleado_{$periodo->nombre_completo}.pdf");
    }

    // ─── PDF 3 — Horas Adicionales ─────────────────

    public function pdfHorasAdicionales(Request $request)
    {
        $this->soloSupervisor();
        $periodo = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $data    = $this->service->gridHorasAdicionales($periodo);

        $dompdf = $this->generarPdf(
            'reportes.pdf.horas-adicionales',
            $data, 'a3', 'landscape'
        );
        return $this->descargar($dompdf, "HorasAdicionales_{$periodo->nombre_completo}.pdf");
    }

    // ─── PDF 4 — Domingos y Festivos ───────────────────────

    public function pdfFestivos(Request $request)
    {
        $this->soloSupervisor();
        $periodo = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $data    = $this->service->gridFestivos($periodo);

        $dompdf = $this->generarPdf(
            'reportes.pdf.festivos',
            $data, 'a3', 'landscape'
        );
        return $this->descargar($dompdf, "Festivos_{$periodo->nombre_completo}.pdf");
    }

    // ─── PDF 5 — Compensatorios ────────────────────────────

    public function pdfCompensatorios(Request $request)
    {
        $this->soloSupervisor();
        $periodo = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $data    = $this->service->gridCompensatorios($periodo);

        $dompdf = $this->generarPdf(
            'reportes.pdf.compensatorios',
            $data, 'a3', 'landscape'
        );
        return $this->descargar($dompdf, "Compensatorios_{$periodo->nombre_completo}.pdf");
    }

    // ─── CSV CONSOLIDADO ───────────────────────────────────

    public function csvConsolidado(Request $request)
    {
        $this->soloSupervisor();
        $periodo = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $datos   = $this->service->consolidadoPeriodo($periodo);

        return response()->stream(function () use ($datos) {
            $out = fopen('php://output','w');
            fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($out, ['Empleado','Cedula','Cargo','Estado','Total Horas','Horas Productivas','Horas Exentas','Costo Periodo (COP)'], ';');
            foreach ($datos as $r) {
                $emp = $r['empleado'];
                fputcsv($out, [$emp->nombre,$emp->cedula,$emp->cargo,strtoupper($r['hoja']->estado),
                    number_format($r['total_horas'],2,'.',''),
                    number_format($r['horas_productivas'],2,'.',''),
                    number_format($r['horas_exentas'],2,'.',''),
                    number_format($r['costo_real_mes'],2,'.',''),
                ], ';');
            }
            fclose($out);
        }, 200, [
            'Content-Type'        => 'text/csv; charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"consolidado_{$periodo->nombre_completo}.csv\"",
        ]);
    }

    // ─── CSV NÓMINA ────────────────────────────────────────

    public function csvNomina(Request $request)
    {
        $this->soloSupervisor();
        $periodo   = Periodo::findOrFail($request->periodo_id ?? Periodo::activo()->first()?->id);
        $empleados = Empleado::activos()->orderBy('nombre')->get();

        return response()->stream(function () use ($empleados) {
            $out = fopen('php://output','w');
            fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($out, ['Empleado','Cedula','Cargo','Tipo Contrato','Salario Base',
                'Medicina Prepagada','Alimentacion','Zafiro','Aux Transporte',
                'Salud Empleador (8.5%)','Pension Empleador (12%)','ARL (%)','Valor ARL',
                'Caja Compensacion (4%)','SENA (2%)','ICBF (3%)',
                'Prima (8.33%)','Cesantias (8.33%)','Int Cesantias (1%)','Vacaciones (4.17%)',
                'Total Carga Prestacional','Costo Real Mensual','Valor Hora Base','Valor Hora Real',
            ], ';');
            foreach ($empleados as $emp) {
                $d = $emp->desgloste_costo;
                fputcsv($out, [$emp->nombre,$emp->cedula,$emp->cargo,$emp->tipo_contrato,
                    number_format($emp->salario,2,'.',''),
                    number_format($emp->medicina_prepagada,2,'.',''),
                    number_format($emp->alimentacion,2,'.',''),
                    number_format($emp->zafiro,2,'.',''),
                    number_format($d['aux_transporte'],2,'.',''),
                    number_format($d['salud_empleador'],2,'.',''),
                    number_format($d['pension_empleador'],2,'.',''),
                    number_format($emp->arl_porcentaje,4,'.','').'%',
                    number_format($d['arl'],2,'.',''),
                    number_format($d['caja_compensacion'],2,'.',''),
                    number_format($d['sena'],2,'.',''),
                    number_format($d['icbf'],2,'.',''),
                    number_format($d['prima'],2,'.',''),
                    number_format($d['cesantias'],2,'.',''),
                    number_format($d['int_cesantias'],2,'.',''),
                    number_format($d['vacaciones'],2,'.',''),
                    number_format($emp->carga_prestacional,2,'.',''),
                    number_format($emp->costo_real_mensual,2,'.',''),
                    number_format($emp->valor_hora_base,2,'.',''),
                    number_format($emp->valor_hora_real,2,'.',''),
                ], ';');
            }
            fclose($out);
        }, 200, [
            'Content-Type'        => 'text/csv; charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"nomina_{$periodo->nombre_completo}.csv\"",
        ]);
    }

}
