<?php

namespace Modules\Booking\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BookingResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'booking_ref' => $this->booking_ref,
            'status' => $this->status,
            'travel_date' => $this->travel_date?->toDateString(),
            'is_round_trip' => $this->is_round_trip,
            'is_return_leg' => $this->is_return_leg,
            'passenger_name' => $this->passenger_name,
            'passenger_phone' => $this->passenger_phone,
            'notes' => $this->notes,
            'pickup_address' => $this->pickup_address,
            'pickup_lat' => $this->pickup_lat,
            'pickup_lng' => $this->pickup_lng,
            'dropoff_address' => $this->dropoff_address,
            'dropoff_lat' => $this->dropoff_lat,
            'dropoff_lng' => $this->dropoff_lng,
            'price' => $this->price,
            // This leg's own price, same value CancelBookingAction/
            // RefundBookingAction use for this specific leg. total_price is
            // the round-trip total (this leg + linked leg) — computed here,
            // not left to the client to sum, since it must always match what
            // InitiatePaymentAction actually charges (bcadd, same as there).
            // Equal to `price` for a plain one-way booking.
            'total_price' => $this->relationLoaded('linkedBooking') && $this->linkedBooking !== null
                ? bcadd((string) $this->price, (string) $this->linkedBooking->price, 2)
                : $this->price,
            'created_by_channel' => $this->created_by_channel,
            // Only ever populated once status is confirmed — see AssignDriverAction.
            'driver_name' => $this->driver_name,
            'driver_phone' => $this->driver_phone,
            'car_plate_number' => $this->car_plate_number,
            'car_model' => $this->car_model,
            'vehicle_options' => $this->whenLoaded('vehicleOptions', fn () => $this->vehicleOptions->map(fn ($selection) => [
                'vehicle_option' => $selection->vehicle_option,
                'passenger_count' => $selection->passenger_count,
                'unit_price' => $selection->unit_price,
                'line_total' => $selection->line_total,
            ])),
            'route' => $this->whenLoaded('route', fn () => [
                'id' => $this->route->id,
                'ev_company_id' => $this->route->ev_company_id,
                'from_destination_id' => $this->route->from_destination_id,
                'to_destination_id' => $this->route->to_destination_id,
            ]),
            'time_slot' => $this->whenLoaded('timeSlot', fn () => [
                'id' => $this->timeSlot->id,
                'label' => $this->timeSlot->label,
                'time' => $this->timeSlot->time?->format('H:i'),
            ]),
            // Hand-built, not a nested BookingResource — the linked leg's
            // own linked_booking points right back here, so nesting the
            // full resource would recurse forever (domain.md §2b).
            'linked_booking' => $this->whenLoaded('linkedBooking', fn () => [
                'id' => $this->linkedBooking->id,
                'booking_ref' => $this->linkedBooking->booking_ref,
                'status' => $this->linkedBooking->status,
                'travel_date' => $this->linkedBooking->travel_date?->toDateString(),
                'is_return_leg' => $this->linkedBooking->is_return_leg,
                'route' => $this->linkedBooking->relationLoaded('route') ? [
                    'id' => $this->linkedBooking->route->id,
                    'ev_company_id' => $this->linkedBooking->route->ev_company_id,
                    'from_destination_id' => $this->linkedBooking->route->from_destination_id,
                    'to_destination_id' => $this->linkedBooking->route->to_destination_id,
                ] : null,
                'time_slot' => $this->linkedBooking->relationLoaded('timeSlot') ? [
                    'id' => $this->linkedBooking->timeSlot->id,
                    'label' => $this->linkedBooking->timeSlot->label,
                    'time' => $this->linkedBooking->timeSlot->time?->format('H:i'),
                ] : null,
                'vehicle_options' => $this->linkedBooking->relationLoaded('vehicleOptions')
                    ? $this->linkedBooking->vehicleOptions->map(fn ($selection) => [
                        'vehicle_option' => $selection->vehicle_option,
                        'passenger_count' => $selection->passenger_count,
                        'unit_price' => $selection->unit_price,
                        'line_total' => $selection->line_total,
                    ])
                    : null,
                // Each leg gets its own independent driver/vehicle
                // assignment — the return leg is never guaranteed the same
                // car as the outbound leg (domain.md §2b). Only ever
                // populated once that leg's own status is confirmed — see
                // AssignDriverAction.
                'driver_name' => $this->linkedBooking->driver_name,
                'driver_phone' => $this->linkedBooking->driver_phone,
                'car_plate_number' => $this->linkedBooking->car_plate_number,
                'car_model' => $this->linkedBooking->car_model,
            ]),
            'created_at' => $this->created_at,
        ];
    }
}
