<?php

namespace App\Services\Achievements\Checkers;

use App\Models\Aircraft;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Support\Collection;

class AircraftChecker extends BaseChecker
{
    private const array DOUBLE_DECKER_DESIGNATORS = [
        // A380
        'A380', 'A388',
        // 747 variants
        'B741', 'B742', 'B743', 'B744', 'B748', 'B74D', 'B74R', 'B74S',
    ];

    public function check(): void
    {
        /**
         * @var $flights Collection<int, UserFlight>
         */
        $flights = $this->flights();


        $flightsWithAircraft = $flights->filter(fn($f) => $f->aircraft !== null);


        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => in_array($f->aircraft->aircraft_description, ['LandPlane', 'SeaPlane'])
            ),
            'aircraft.fly_on_a_plane'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => $f->aircraft->aircraft_description === 'Helicopter'
            ),
            'aircraft.fly_on_a_helicopter'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => $f->aircraft->engine_type === 'Jet'
            ),
            'aircraft.fly_on_a_jet'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => $f->aircraft->engine_type === 'Turboprop/Turboshaft' || $f->aircraft->engine_type === 'Piston'
            ),
            'aircraft.fly_on_a_prop'
        );

        // --- Engine count achievements ---

        $this->awardIf(
            $flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 1 && $f->aircraft->aircraft_description !== 'Helicopter'),
            'aircraft.single_engine'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 2 && $f->aircraft->aircraft_description !== 'Helicopter'),
            'aircraft.twin_engine'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 3 && $f->aircraft->aircraft_description !== 'Helicopter'),
            'aircraft.tri_engine'
        );

        $this->awardIf(
            $flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 4 && $f->aircraft->aircraft_description !== 'Helicopter'),
            'aircraft.quad_engine'
        );

        // --- Double decker ---

        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => in_array($f->aircraft->designator, self::DOUBLE_DECKER_DESIGNATORS)
            ),
            'aircraft.double_decker'
        );

        // --- Smaller manufacturer (scheduled service only) ---

        $this->awardIf(
            $flightsWithAircraft->contains(
                fn(UserFlight $f) => $f->airline && $f->flight_number && !in_array(strtolower($f->aircraft->manufacturer_code), ['boeing', 'airbus'])
            ),
            'aircraft.smaller_manufacturer'
        );

        // --- Boeing 7x7 families ---

        $flownBoeingFamilies = collect(Aircraft::BOEING_FAMILIES)
            ->filter(fn($designators) =>
                $flightsWithAircraft->contains(
                    fn(UserFlight $f) => in_array($f->aircraft->designator, $designators)
                )
            )
            ->count();

        $this->awardProgress($flownBoeingFamilies, 'aircraft.all_boeing_7x7');

        // --- Airbus A3xx families ---

        $flownAirbusFamilies = collect(Aircraft::AIRBUS_FAMILIES)
            ->filter(fn($designators) =>
                $flightsWithAircraft->contains(
                    fn(UserFlight $f) => in_array($f->aircraft->designator, $designators)
                )
            )
            ->count();

        $this->awardProgress($flownAirbusFamilies, 'aircraft.all_airbus_a3xx');

        $flown737Variants = collect(Aircraft::BOEING_737_VARIANTS)
            ->filter(fn($designators) =>
                $flightsWithAircraft->contains(
                    fn(UserFlight $f) => in_array($f->aircraft->designator, $designators)
                )
            )
            ->count();
        $this->awardProgress($flown737Variants, 'aircraft.all_boeing_737');

    }
}
