<?php

namespace App\Http\Controllers;

use App\Models\CierreTurno;
use App\Models\Diferencia;
use App\Models\PrecioDia;
use App\Models\RegistroSalida;
use App\Models\Turno;
use App\Models\User;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;

class ReportesController extends Controller
{
    public function index(Request $request)
    {
        $data = $this->buildReporteData($request);

        return view('reportes.index', $data);
    }

    public function export(Request $request)
    {
        $data = $this->buildReporteData($request);

        $filename = 'reporte_' . date('Ymd_His') . '.xls';
        $html = view('reportes.export_excel', $data)->render();

        return response($html, 200, [
            'Content-Type' => 'application/vnd.ms-excel; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ]);
    }

    public function exportPdf(Request $request)
    {
        $data = $this->buildReporteData($request);

        $filename = 'reporte_' . date('Ymd_His') . '.pdf';

        return Pdf::loadView('reportes.export_pdf', $data)
            ->setPaper('a4', 'landscape')
            ->download($filename);
    }

    private function buildReporteData(Request $request): array
    {
        $fechaDesde = $request->input('fecha_desde', date('Y-m-d'));
        $fechaHasta = $request->input('fecha_hasta', date('Y-m-d'));
        $idTurno = $request->input('id_turno');
        $idUsuario = $request->input('id_usuario');

        $authUser = auth()->user();
        $esOperador = strtoupper((string)($authUser->rol ?? '')) === 'OPERADOR';

        if ($esOperador) {
            $idUsuario = $authUser->id_usuario ?? $authUser->id ?? null;
        }

        $turnos = Turno::orderBy('id_turno')->get();
        $usuarios = $esOperador
            ? User::where('id_usuario', $idUsuario)->orderBy('id_usuario')->get()
            : User::orderBy('id_usuario')->get();

        $query = RegistroSalida::with([
            'manguera.cara.estacion',
            'manguera.tipoCombustible',
            'turno',
            'usuario',
        ])
            ->whereDate('fecha_inicio', '>=', $fechaDesde)
            ->whereDate('fecha_inicio', '<=', $fechaHasta);

        if (!empty($idTurno)) {
            $query->where('id_turno', (int)$idTurno);
        }

        if (!empty($idUsuario)) {
            $query->where('id_usuario', (int)$idUsuario);
        }

        $registros = $query
            ->orderBy('fecha_inicio', 'desc')
            ->orderBy('id_salida', 'desc')
            ->get();

        $items = $registros->map(function ($r) {
            $tipoId = $r->manguera?->id_tipo_combustible;
            $fecha = optional($r->fecha_inicio)->format('Y-m-d');

            $precioDia = null;
            if ($tipoId && $fecha) {
                $precioDia = PrecioDia::where('tipo_combustible', $tipoId)
                    ->whereDate('fecha', $fecha)
                    ->orderByDesc('id')
                    ->first();

                if (!$precioDia) {
                    $precioDia = PrecioDia::where('tipo_combustible', $tipoId)
                        ->whereDate('fecha', '<=', $fecha)
                        ->orderByDesc('fecha')
                        ->orderByDesc('id')
                        ->first();
                }
            }

            $turnoNombre = strtolower((string)($r->turno->turnos ?? $r->turno->nombre ?? ''));
            $precioTurno = null;

            if ($precioDia) {
                if (str_contains($turnoNombre, 'mañ') || str_contains($turnoNombre, 'mana') || str_contains($turnoNombre, 'morning')) {
                    $precioTurno = $precioDia->precio_turno_manana;
                } elseif (str_contains($turnoNombre, 'tarde') || str_contains($turnoNombre, 'afternoon')) {
                    $precioTurno = $precioDia->precio_turno_tarde;
                } elseif (str_contains($turnoNombre, 'noche') || str_contains($turnoNombre, 'night')) {
                    $precioTurno = $precioDia->precio_turno_noche;
                }
            }

            $saldoInicial = $r->saldo_inicial ?? $r->galones ?? null;
            $saldoFinal = $r->saldo_final;
            $galonesVendidos = (is_null($saldoInicial) || is_null($saldoFinal))
                ? null
                : ((float)$saldoFinal - (float)$saldoInicial);

            $precioGalon = (float)($r->precio_galon ?? 0);
            if ($precioGalon <= 0.0 && $precioTurno !== null) {
                $precioGalon = (float)$precioTurno;
            }

            $totalVentaCalculado = (is_null($galonesVendidos) || $precioGalon <= 0.0)
                ? null
                : ((float)$galonesVendidos * $precioGalon);

            $usuarioNombre = trim(
                (string)($r->usuario?->nombres ?? $r->usuario?->name ?? '') . ' ' .
                (string)($r->usuario?->apellidos ?? '')
            );

            return [
                'fecha' => $r->fecha_inicio,
                'manguera' => $r->manguera,
                'turno' => $r->turno,
                'usuario' => $r->usuario ?? null,
                'usuario_nombre' => $usuarioNombre !== '' ? $usuarioNombre : 'Usuario #' . ($r->id_usuario ?? '-'),
                'saldo_inicial' => $saldoInicial,
                'saldo_final' => $saldoFinal,
                'galones_vendidos' => $galonesVendidos,
                'precio_turno' => $precioGalon,
                'precio_galon' => $precioGalon,
                'total_registro' => (float)($r->total ?? 0),
                'total_venta_calculado' => $totalVentaCalculado,
                'precio_dia' => $precioDia,
            ];
        });

        $totalGeneralVentas = (float) $items->sum(function ($it) {
            return (float)($it['total_registro'] ?? 0);
        });

        $mostrarGastosDiferencias = !empty($idTurno) && !empty($idUsuario);
        $gastosDiferencias = collect();

        $totalesCierre = [
            'efectivo' => 0.0,
            'credito' => 0.0,
            'visa' => 0.0,
            'descuentos' => 0.0,
            'diferencia' => 0.0,
            'resta_final' => null,
        ];

        if (!empty($idTurno)) {
            $cierresQuery = CierreTurno::query()
                ->whereDate('fecha', '>=', $fechaDesde)
                ->whereDate('fecha', '<=', $fechaHasta)
                ->where('id_turno', (int)$idTurno);

            if (!empty($idUsuario)) {
                $cierresQuery->where('id_usuario', (int)$idUsuario);
            }

            $totalesCierre['efectivo'] = (float) $cierresQuery->sum('efectivo');
            $totalesCierre['credito'] = (float) $cierresQuery->sum('credito');
            $totalesCierre['visa'] = (float) $cierresQuery->sum('visa');
            $totalesCierre['descuentos'] = (float) $cierresQuery->sum('descuentos');

            $gastosDiferenciasQuery = Diferencia::query()
                ->with(['turno', 'tipoCombustible', 'usuario'])
                ->whereDate('created_at', '>=', $fechaDesde)
                ->whereDate('created_at', '<=', $fechaHasta)
                ->where('id_turno', (int) $idTurno);

            if (!empty($idUsuario)) {
                $gastosDiferenciasQuery->where('id_usuario', (int) $idUsuario);
            }

            $gastosDiferencias = $gastosDiferenciasQuery
                ->orderByDesc('created_at')
                ->get();

            $totalGastosDiferencias = (float) $gastosDiferencias->sum('total');
            $totalesCierre['diferencia'] = (float) $cierresQuery->sum('diferencia') - $totalGastosDiferencias;

            $totalesCierre['resta_final'] = $totalGeneralVentas
                - (
                    $totalesCierre['efectivo']
                    + $totalesCierre['credito']
                    + $totalesCierre['visa']
                    + $totalesCierre['descuentos']
                    + $totalesCierre['diferencia']
                );
        }

        return [
            'items' => $items,
            'fechaDesde' => $fechaDesde,
            'fechaHasta' => $fechaHasta,
            'turnos' => $turnos,
            'usuarios' => $usuarios,
            'idTurno' => $idTurno,
            'idUsuario' => $idUsuario,
            'totalGeneralVentas' => $totalGeneralVentas,
            'totalesCierre' => $totalesCierre,
            'gastosDiferencias' => $gastosDiferencias,
            'mostrarGastosDiferencias' => $mostrarGastosDiferencias,
            'esOperador' => $esOperador,
        ];
    }
}
