<?php

namespace Modules\Booking\Services;

use Modules\Booking\Data\VehicleSelectionData;
use Modules\Booking\Exceptions\InvalidVehicleSelectionException;
use Modules\Shared\Enums\VehicleOption;

class BookingService
{
    /**
     * Enforces the same two blunt, config-driven rules for every Vehicle
     * Option — an on/off toggle and a max passenger_count per booking (see
     * domain.md §2) — plus shape rules around combining options in one
     * booking (no duplicate option lines, Whole Vehicle can't be mixed with
     * anything else since it already covers the whole car).
     *
     * Deliberately does not check real capacity/availability — that's an
     * explicitly deferred future phase (domain.md §2, §7).
     *
     * @param  list<VehicleSelectionData>  $selections
     *
     * @throws InvalidVehicleSelectionException
     */
    public function validateSelections(array $selections): void
    {
        $seen = [];

        foreach ($selections as $selection) {
            if (isset($seen[$selection->vehicleOption->value])) {
                throw InvalidVehicleSelectionException::duplicateOption($selection->vehicleOption);
            }

            $seen[$selection->vehicleOption->value] = true;

            $this->validateOption($selection->vehicleOption, $selection->passengerCount);
        }

        if (isset($seen[VehicleOption::WholeVehicle->value]) && count($seen) > 1) {
            throw InvalidVehicleSelectionException::wholeVehicleCannotBeCombined();
        }
    }

    private function validateOption(VehicleOption $vehicleOption, int $passengerCount): void
    {
        $this->validateEnabled($vehicleOption);
        $this->validateMax($vehicleOption, $passengerCount);
    }

    private function validateEnabled(VehicleOption $vehicleOption): void
    {
        if (! config("booking.{$vehicleOption->value}_enabled")) {
            throw InvalidVehicleSelectionException::optionDisabled($vehicleOption);
        }
    }

    private function validateMax(VehicleOption $vehicleOption, int $passengerCount): void
    {
        $max = config("booking.{$vehicleOption->value}_max_per_booking");

        if ($passengerCount > $max) {
            throw InvalidVehicleSelectionException::passengerLimitExceeded($vehicleOption, $passengerCount, $max);
        }
    }
}
