<?php

namespace App\Http\Controllers;

use App\Exports\ReservationExport;
use App\Http\Requests\UpdateReservationRequest;
use App\Http\Resources\ReservationList;
use App\Http\Resources\ReservationView;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Mtc\VehicleReservations\Reservation;

class ReservationController extends Controller
{
    public function index(Request $request)
    {
        return new ReservationList(
            Reservation::query()
                ->with(['vehicle' => fn ($query) => $query->withTrashed()->with('dealership')])
                ->whereNotNull('confirmed_at')
                ->when(
                    $request->filled('customer_id'),
                    fn ($query) => $query->where('customer_id', $request->input('customer_id'))
                )
                ->when(
                    $request->filled('dealership_id'),
                    fn ($query) => $query->whereHas(
                        'vehicle',
                        fn ($q) => $q->withTrashed()
                            ->where('dealership_id', $request->input('dealership_id'))
                    )
                )
                ->when(
                    $request->filled('search_term'),
                    fn ($query) => $query->whereHas(
                        'vehicle',
                        fn ($q) => $q->withTrashed()
                            ->where(
                                'registration_number',
                                'like',
                                '%' . $request->input('search_term') . '%'
                            )
                    )
                )
                ->latest()
                ->paginate()
        );
    }

    public function show(Reservation $reservation)
    {
        return new ReservationView($reservation);
    }

    public function update(UpdateReservationRequest $request, Reservation $reservation): ReservationView
    {
        $reservation->update($request->validated());
        return new ReservationView($reservation);
    }

    public function getExport(): array
    {
        $statuses = Reservation::query()
            ->whereNotNull('confirmed_at')
            ->select('status')
            ->distinct()
            ->orderBy('status')
            ->pluck('status')
            ->map(fn (string $status) => ['name' => ucfirst($status), 'id' => $status]);

        return [
            'statuses' => $statuses->prepend(['name' => 'All', 'id' => 'all']),
        ];
    }

    public function runExport(Request $request)
    {
        return Excel::download(
            new ReservationExport($request->input()),
            'reservations-' . Carbon::now()->format('Y-m-d-H-i') . '.xlsx'
        );
    }

    public function destroy(Request $request, Reservation $reservation): ReservationList
    {
        $reservation->update(['status' => 'cancelled']);

        $vehicleHasNoReservation = $reservation->vehicle->reservations()
            ->whereNotIn('status', ['pending', 'cancelled'])
            ->exists();
        if ($vehicleHasNoReservation) {
            $reservation->vehicle->update(['is_reserved' => false]);
        }

        return $this->index($request);
    }
}
