<?php

namespace App\Http\Controllers;

use App\Models\Airline;
use App\Models\Airport;
use App\Models\CrewType;
use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\SeatType;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class FlightController extends Controller
{
    use AuthorizesRequests;
    public function rules(): array
    {
        return [
            'flight_number'         => ['nullable', 'string', 'max:10'],
            'departure_date'        => ['required', 'date'],
            'arrival_date'          => ['required', 'date'],
            'from_id'               => ['required', 'integer', 'exists:airports,id'],
            'to_id'                 => ['required', 'integer', 'exists:airports,id'],
            'airline_id'            => ['nullable', 'integer', 'exists:airlines,id'],
            'aircraft_id'           => ['nullable', 'integer', 'exists:aircraft,id'],
            'aircraft_registration' => ['nullable', 'string', 'max:10'],
            'seat_number'           => ['nullable', 'string', 'max:10'],
            'seat_type_id'          => ['integer', 'exists:seat_types,id'],
            'flight_class_id'       => ['integer', 'exists:flight_classes,id'],
            'flight_reason_id'      => ['integer', 'exists:flight_reasons,id'],
            'note'                  => ['nullable', 'string', 'max:5000'],
            'auto_update'           => ['boolean'],
            'crew_type_id' => ['nullable', 'exists:crew_types,id'],
        ];
    }

    public function lookup(Request $request)
    {
        $number = strtoupper(trim($request->query('number', '')));

        // Extract the airline code prefix — letters at the start e.g. "QF" from "QF1"
        preg_match('/^([A-Z]{2,3})/', $number, $matches);
        $code = $matches[1] ?? null;
        $isIata = strlen($code) === 2;
        $codeColumn = $isIata ? 'IATA_code' : 'ICAO_code';

        $airlines = $code
            ? Airline::where($codeColumn, $code)
                ->get()
                ->map(fn ($airline) => ['value' => $airline->id, 'title' => $airline->display_name])
            : collect()->toArray();
        return response()->json([
            'airline_options'  => $airlines,
            'from_options'     => [],
            'to_options'       => [],
            'aircraft_options' => [],
        ]);
    }

    private function convertedDates(array $validated): array
    {
        $departureAirport = Airport::find($validated['from_id']);
        $arrivalAirport   = Airport::find($validated['to_id']);

        return [
            Carbon::createFromFormat('Y-m-d\TH:i', $validated['departure_date'], $departureAirport->timezone)->utc(),
            Carbon::createFromFormat('Y-m-d\TH:i', $validated['arrival_date'],   $arrivalAirport->timezone)->utc(),
        ];
    }

    private function flightPayload(array $validated): array
    {
        [$departureUtc, $arrivalUtc] = $this->convertedDates($validated);
        return [
            'departure_date'        => $departureUtc,
            'arrival_date'          => $arrivalUtc,
            'flight_number'         => $validated['flight_number'],
            'departure_airport_id'  => $validated['from_id'],
            'arrival_airport_id'    => $validated['to_id'],
            'airline_id'            => $validated['airline_id'],
            'aircraft_id'           => $validated['aircraft_id'],
            'aircraft_registration' => $validated['aircraft_registration'],
            'seat_number'           => $validated['seat_number'],
            'seat_type_id'          => $validated['seat_type_id'],
            'flight_class_id'       => $validated['flight_class_id'],
            'flight_reason_id'      => $validated['flight_reason_id'],
            'note'                  => $validated['note'],
            'auto_update'           => $validated['auto_update'],
            'crew_type_id' => $validated['crew_type_id'],
        ];
    }



    public function store(Request $request)
    {
        $validated = $request->validate($this->rules());

        $newFlight = auth()->user()->flights()->create($this->flightPayload($validated));

        return redirect()->route('profile.departure-board', [Auth::user()->name, $newFlight->id]);
    }

    public function update(Request $request, UserFlight $flight)
    {
        $this->authorize('update', $flight);

        $validated = $request->validate($this->rules());

        $flight->update($this->flightPayload($validated));

        return redirect()->route('profile.departure-board', [Auth::user()->name, $flight->id]);
    }

    public function staticData() : array {
        return [
            'seat_types'     => SeatType::orderBy('id')->get()->toArray(),
            'flight_reasons' => FlightReason::orderBy('id')->get()->toArray(),
            'flight_classes' => FlightClass::orderBy('id')->get()->toArray(),
            'crew_types' => CrewType::orderBy('id')->get()->toArray(),
        ];
    }

    public function add(){
        return Inertia::render('AddFlight', $this->staticData());
    }

    public function edit(UserFlight $flight)
    {
        $this->authorize('update', $flight);
        $flight->load('airline', 'aircraft', 'departureAirport.region.country', 'arrivalAirport.region.country', 'seatType', 'flightClass', 'flightReason');
        $flightData = [
            'id'                    => $flight->id,
            'flight_number'         => $flight->flight_number,
            'departure_date' => $flight->departure_date->setTimezone($flight->departureAirport->timezone)->format('Y-m-d\TH:i'),
            'arrival_date'   => $flight->arrival_date->setTimezone($flight->arrivalAirport->timezone)->format('Y-m-d\TH:i'),
            'aircraft_registration' => $flight->aircraft_registration,
            'seat_number'           => $flight->seat_number,
            'note'                  => $flight->note,
            'auto_update'           => $flight->auto_update,
            'seat_type'             => $flight->seatType->toArray(),
            'flight_class'          => $flight->flightClass->toArray(),
            'crew_type'           =>     $flight->crewType?->toArray() ?? [],
            'flight_reason'         => $flight->flightReason->toArray(),
            'airline_options'       => $flight->airline
                ? [['value' => $flight->airline->id, 'title' => $flight->airline->display_name]]
                : [],
            'from_options'          => [['value' => $flight->departureAirport->id, 'title' => $flight->departureAirport->display_name, 'country_code' => strtolower($flight->departureAirport->region->country->code)]],
            'to_options'            => [['value' => $flight->arrivalAirport->id,   'title' => $flight->arrivalAirport->display_name,   'country_code' => strtolower($flight->arrivalAirport->region->country->code)]],
            'aircraft_options'      => $flight->aircraft
                ? [['value' => $flight->aircraft->id, 'title' => $flight->aircraft->display_name]]
                : [],
        ];
        return Inertia::render('AddFlight', [
            'flight' => $flightData,
            ...$this->staticData(),
        ]);
    }
}
