<?php

namespace App\Http\Requests\Admin;

use App\Models\Customer;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;

class BookingRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            // "__new__" is a sentinel meaning "create a new customer from
            // the quick-add fields below" — same resolve-before-save pattern
            // used for account_id.
            'customer_id' => [
                'required', 'string',
                Rule::when($this->input('customer_id') !== '__new__', ['exists:customers,id']),
            ],
            'quick_customer_name' => ['nullable', 'required_if:customer_id,__new__', 'string', 'max:255'],
            'quick_customer_phone' => ['nullable', 'required_if:customer_id,__new__', 'string', 'max:50'],
            'quick_customer_email' => ['nullable', 'email', 'max:255'],

            // Each line is one vehicle *type* plus how many of that type to
            // book for this trip (e.g. 2 Saloons + 1 Estate) — store() turns
            // this into one Booking row per unit, sharing a group_id when
            // the total across all lines is more than one.
            'vehicles' => ['required', 'array', 'min:1'],
            'vehicles.*.vehicle_type_id' => ['required', 'distinct', 'exists:vehicle_types,id'],
            'vehicles.*.quantity' => ['required', 'integer', 'min:1', 'max:10'],
            'vehicles.*.fare_override' => ['nullable', 'numeric', 'min:0'],
            'driver_id' => ['nullable', 'exists:drivers,id'],
            'payment_method_id' => ['nullable', 'exists:payment_methods,id'],
            'pickup_address' => ['required', 'string', 'max:800'],
            'pickup_lat' => ['nullable', 'numeric'],
            'pickup_lng' => ['nullable', 'numeric'],
            'dropoff_address' => ['required', 'string', 'max:800'],
            'dropoff_lat' => ['nullable', 'numeric'],
            'dropoff_lng' => ['nullable', 'numeric'],
            'pickup_datetime' => ['required', 'date'],
            'passengers' => ['required', 'integer', 'min:1', 'max:20'],
            'luggage' => ['nullable', 'integer', 'min:0', 'max:20'],
            'flight_number' => ['nullable', 'string', 'max:50'],
            'customer_reference' => ['nullable', 'string', 'max:255'],
            'notes' => ['nullable', 'string', 'max:2000'],
            'send_sms' => ['sometimes', 'boolean'],

            // "__new__" is a sentinel meaning "create a new account with the
            // name/number below" — resolved to a real id in the controller
            // before the booking is saved, so the FK check only applies
            // once we know it's an actual id rather than the sentinel.
            'account_id' => ['nullable', 'string'],
            'new_account_name' => ['nullable', 'required_if:account_id,__new__', 'string', 'max:255'],
            'new_account_number' => ['nullable', 'string', 'max:255'],

            'stops' => ['nullable', 'array'],
            'stops.*' => ['required', 'string', 'max:800'],
        ];
    }

    public function withValidator(Validator $validator): void
    {
        $validator->after(function ($validator) {
            $totalVehicles = collect($this->input('vehicles', []))->sum('quantity');

            if ($totalVehicles > 1 && $this->filled('driver_id')) {
                $validator->errors()->add('driver_id', 'A driver can only be assigned when booking a single vehicle.');
            }

            // ORG-03: a company can have multi-vehicle bookings switched off
            // via its feature flags — Super Admin bypasses every flag.
            $user = $this->user();
            $company = $user?->company;
            if ($totalVehicles > 1 && $company && ! $company->hasFeature('multi_vehicle_bookings')) {
                $validator->errors()->add('vehicles', 'Multi-vehicle bookings are not enabled for your company.');
            }
        });
    }
}
