<?php

namespace Modules\Booking\Actions;

use Modules\Booking\Data\AssignDriverData;
use Modules\Booking\Enums\BookingStatus;
use Modules\Booking\Events\DriverAssigned;
use Modules\Booking\Exceptions\DriverAssignmentNotAllowedException;
use Modules\Booking\Models\Booking;

/**
 * Driver/vehicle details only make sense once a booking is confirmed
 * (paid) — dispatch assigns who's actually doing the trip at that point,
 * not before. Re-running this (e.g. reassigning a different driver) is
 * allowed as long as the booking is still confirmed.
 */
class AssignDriverAction
{
    public function handle(Booking $booking, AssignDriverData $data): Booking
    {
        if ($booking->status !== BookingStatus::Confirmed) {
            throw DriverAssignmentNotAllowedException::notConfirmed($booking);
        }

        if ($booking->travel_date->lt(today())) {
            throw DriverAssignmentNotAllowedException::travelDateInPast($booking);
        }

        $isFirstAssignment = $booking->driver_name === null;

        $booking->update([
            'driver_name' => $data->driverName,
            'driver_phone' => $data->driverPhone,
            'car_plate_number' => $data->carPlateNumber,
            'car_model' => $data->carModel,
        ]);

        // Guards against a double-submit of the same form resulting in two
        // identical SMS notifications to the passenger — a genuine
        // reassignment always changes at least one of these columns.
        if ($booking->wasChanged(['driver_name', 'driver_phone', 'car_plate_number', 'car_model'])) {
            DriverAssigned::dispatch($booking, $isFirstAssignment);
        }

        return $booking;
    }
}
