<?php

namespace App\Services\Achievements\Checkers;

use App\Models\User;
use App\Models\UserFlight;

class FunChallengesChecker extends BaseChecker
{
    const array US_STATES = [
        'US-AK', 'US-AL', 'US-AR', 'US-AZ', 'US-CA', 'US-CO', 'US-CT', 'US-DC',
        'US-DE', 'US-FL', 'US-GA', 'US-HI', 'US-IA', 'US-ID', 'US-IL', 'US-IN',
        'US-KS', 'US-KY', 'US-LA', 'US-MA', 'US-MD', 'US-ME', 'US-MI', 'US-MN',
        'US-MO', 'US-MS', 'US-MT', 'US-NC', 'US-ND', 'US-NE', 'US-NH', 'US-NJ',
        'US-NM', 'US-NV', 'US-NY', 'US-OH', 'US-OK', 'US-OR', 'US-PA', 'US-RI',
        'US-SC', 'US-SD', 'US-TN', 'US-TX', 'US-UT', 'US-VA', 'US-VT', 'US-WA',
        'US-WI', 'US-WV', 'US-WY',
    ];

    const array AUSTRALIAN_STATES = [
            'AU-ACT', 'AU-NSW', 'AU-NT', 'AU-QLD', 'AU-SA', 'AU-TAS', 'AU-VIC', 'AU-WA',
    ];

    const array CHINESE_PROVINCES = [
            'CN-11', 'CN-12', 'CN-13', 'CN-14', 'CN-15', 'CN-21', 'CN-22', 'CN-23',
            'CN-31', 'CN-32', 'CN-33', 'CN-34', 'CN-35', 'CN-36', 'CN-37', 'CN-41',
            'CN-42', 'CN-43', 'CN-44', 'CN-45', 'CN-46', 'CN-50', 'CN-51', 'CN-52',
            'CN-53', 'CN-54', 'CN-61', 'CN-62', 'CN-63', 'CN-64', 'CN-65',

    ];

    const array BRAZILIAN_STATES = [
        'BR-AC', 'BR-AL', 'BR-AM', 'BR-AP', 'BR-BA', 'BR-CE', 'BR-DF', 'BR-ES',
        'BR-GO', 'BR-MA', 'BR-MG', 'BR-MS', 'BR-MT', 'BR-PA', 'BR-PB', 'BR-PE',
        'BR-PI', 'BR-PR', 'BR-RJ', 'BR-RN', 'BR-RO', 'BR-RR', 'BR-RS', 'BR-SC',
        'BR-SE', 'BR-SP', 'BR-TO',
    ];

    const array CANADIAN_PROVINCES = [
        'CA-AB', 'CA-BC', 'CA-MB', 'CA-NB', 'CA-NL', 'CA-NS', 'CA-NT',
        'CA-NU', 'CA-ON', 'CA-PE', 'CA-QC', 'CA-SK', 'CA-YT',
    ];

    public function check(): void
    {
        $flights = $this->flights();

        $airlineLetters = $flights
            ->filter(fn(UserFlight $f) => $f->airline?->iata_code !== null)
            ->map(fn(UserFlight $f) => strtoupper($f->airline->iata_code[0]))
            ->filter(fn($letter) => ctype_alpha($letter))
            ->unique()
            ->count();

        $this->awardProgress($airlineLetters, 'fun_challenges.airline_alphabet');


        $airportLetters = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->iata_code,
                $f->arrivalAirport?->iata_code,
            ])
            ->filter()
            ->map(fn($code) => strtoupper($code[0]))
            ->unique()
            ->count();

        $this->awardProgress($airportLetters, 'fun_challenges.airport_alphabet');

        // --- US States ---
        $visitedUsStates = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->region?->code,
                $f->arrivalAirport?->region?->code,
            ])
            ->filter()
            ->filter(fn($code) => in_array($code, self::US_STATES))
            ->unique()
            ->count();

        $this->awardProgress($visitedUsStates, 'fun_challenges.us_states');

        // --- Australian States ---
        $visitedAustralianStates = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->region?->code,
                $f->arrivalAirport?->region?->code,
            ])
            ->filter()
            ->filter(fn($code) => in_array($code, self::AUSTRALIAN_STATES))
            ->unique()
            ->count();

        $this->awardProgress($visitedAustralianStates, 'fun_challenges.australian_states');

        // --- Chinese Provinces ---
        $visitedChineseProvinces = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->region?->code,
                $f->arrivalAirport?->region?->code,
            ])
            ->filter()
            ->filter(fn($code) => in_array($code, self::CHINESE_PROVINCES))
            ->unique()
            ->count();

        $this->awardProgress($visitedChineseProvinces, 'fun_challenges.chinese_provinces');

        // --- Brazilian States ---
        $visitedBrazilianStates = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->region?->code,
                $f->arrivalAirport?->region?->code,
            ])
            ->filter()
            ->filter(fn($code) => in_array($code, self::BRAZILIAN_STATES))
            ->unique()
            ->count();

        $this->awardProgress($visitedBrazilianStates, 'fun_challenges.brazilian_states');

        // --- Canadian Provinces ---
        $visitedCanadianProvinces = $flights
            ->flatMap(fn(UserFlight $f) => [
                $f->departureAirport?->region?->code,
                $f->arrivalAirport?->region?->code,
            ])
            ->filter()
            ->filter(fn($code) => in_array($code, self::CANADIAN_PROVINCES))
            ->unique()
            ->count();

        $this->awardProgress($visitedCanadianProvinces, 'fun_challenges.canadian_provinces');
    }
}
