<?php

namespace App\Http\Controllers;

use App\Models\Diferencia;
use App\Models\PrecioDia;
use App\Models\TipoCombustible;
use App\Models\Turno;
use Illuminate\Http\Request;

class DiferenciasController extends Controller
{
    public function index()
    {
        $items = Diferencia::with(['turno', 'tipoCombustible', 'usuario'])
            ->orderByDesc('id')
            ->get();

        return view('diferencias.index', compact('items'));
    }

    public function create()
    {
        $turnos = Turno::orderBy('id_turno')->get();
        $tipos = TipoCombustible::orderBy('nombre')->get();

        return view('diferencias.create', compact('turnos', 'tipos'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'observacion' => 'nullable|string|max:1000',
            'id_turno' => 'required|integer|exists:turnos,id_turno',
            'id_tipo_combustible' => 'required|integer|exists:tipos_combustible,id_tipo_combustible',
            'cantidad_galones' => 'required|numeric|min:0',
            'estado' => 'required|integer|in:0,1',
        ]);

        $data['id_usuario'] = (int) auth()->id();
        $data['precio'] = $this->obtenerPrecioPorTurno(
            (int) $data['id_tipo_combustible'],
            (int) $data['id_turno'],
            date('Y-m-d')
        );
        $data['total'] = round(((float) $data['cantidad_galones']) * ((float) $data['precio']), 2);

        Diferencia::create($data);

        return redirect()->route('diferencias.index')->with('success', 'Diferencia creada.');
    }

    public function edit(string $id)
    {
        $item = Diferencia::findOrFail($id);
        $turnos = Turno::orderBy('id_turno')->get();
        $tipos = TipoCombustible::orderBy('nombre')->get();

        return view('diferencias.edit', compact('item', 'turnos', 'tipos'));
    }

    public function update(Request $request, string $id)
    {
        $item = Diferencia::findOrFail($id);

        $data = $request->validate([
            'observacion' => 'nullable|string|max:1000',
            'id_turno' => 'required|integer|exists:turnos,id_turno',
            'id_tipo_combustible' => 'required|integer|exists:tipos_combustible,id_tipo_combustible',
            'cantidad_galones' => 'required|numeric|min:0',
            'estado' => 'required|integer|in:0,1',
        ]);

        $data['precio'] = $this->obtenerPrecioPorTurno(
            (int) $data['id_tipo_combustible'],
            (int) $data['id_turno'],
            date('Y-m-d')
        );
        $data['total'] = round(((float) $data['cantidad_galones']) * ((float) $data['precio']), 2);

        $item->update($data);

        return redirect()->route('diferencias.index')->with('success', 'Diferencia actualizada.');
    }

    public function destroy(string $id)
    {
        $item = Diferencia::findOrFail($id);
        $item->delete();

        return redirect()->route('diferencias.index')->with('success', 'Diferencia eliminada.');
    }

    private function obtenerPrecioPorTurno(int $idTipoCombustible, int $idTurno, string $fecha): float
    {
        $precioDia = PrecioDia::where('tipo_combustible', $idTipoCombustible)
            ->whereDate('fecha', $fecha)
            ->orderByDesc('id')
            ->first();

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

        if (!$precioDia) {
            return 0.0;
        }

        $turno = Turno::find($idTurno);
        $turnoNombre = strtolower((string) ($turno->turnos ?? ''));

        if (str_contains($turnoNombre, 'mañ') || str_contains($turnoNombre, 'mana') || str_contains($turnoNombre, 'morning')) {
            return (float) ($precioDia->precio_turno_manana ?? 0);
        }

        if (str_contains($turnoNombre, 'tarde') || str_contains($turnoNombre, 'afternoon')) {
            return (float) ($precioDia->precio_turno_tarde ?? 0);
        }

        if (str_contains($turnoNombre, 'noche') || str_contains($turnoNombre, 'night')) {
            return (float) ($precioDia->precio_turno_noche ?? 0);
        }

        return 0.0;
    }
}
