<?php

declare(strict_types=1);

namespace App\Services\Countries;

use App\Models\Country;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;

final class CountryCatalogService
{
    public const ACTIVE_ALL_CACHE_KEY = 'countries.active.all';
    public const PROFILE_SELECT_CACHE_KEY = 'countries.profile.select';

    /**
     * @return Collection<int, Country>
     */
    public function activeCountries(): Collection
    {
        if (! Schema::hasTable('countries')) {
            return collect();
        }

        /** @var Collection<int, Country> $countries */
        $countries = Cache::remember(
            self::ACTIVE_ALL_CACHE_KEY,
            max(60, (int) config('skinbase-countries.cache_ttl', 86400)),
            fn (): Collection => Country::query()->active()->ordered()->get(),
        );

        return $countries;
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function profileSelectOptions(): array
    {
        return Cache::remember(
            self::PROFILE_SELECT_CACHE_KEY,
            max(60, (int) config('skinbase-countries.cache_ttl', 86400)),
            fn (): array => $this->activeCountries()
                ->map(fn (Country $country): array => [
                    'id' => $country->id,
                    'iso2' => $country->iso2,
                    'name' => $country->name_common,
                    'flag_emoji' => $country->flag_emoji,
                    'flag_css_class' => $country->flag_css_class,
                    'is_featured' => $country->is_featured,
                    'flag_path' => $country->local_flag_path,
                ])
                ->values()
                ->all(),
        );
    }

    public function findById(?int $countryId): ?Country
    {
        if ($countryId === null || $countryId <= 0 || ! Schema::hasTable('countries')) {
            return null;
        }

        return Country::query()->find($countryId);
    }

    public function findByIso2(?string $iso2): ?Country
    {
        $normalized = strtoupper(trim((string) $iso2));

        if ($normalized === '' || ! preg_match('/^[A-Z]{2}$/', $normalized) || ! Schema::hasTable('countries')) {
            return null;
        }

        return Country::query()->where('iso2', $normalized)->first();
    }

    public function resolveUserCountry(User $user): ?Country
    {
        if ($user->relationLoaded('country') && $user->country instanceof Country) {
            return $user->country;
        }

        if (! empty($user->country_id)) {
            return $this->findById((int) $user->country_id);
        }

        $countryCode = strtoupper((string) ($user->profile?->country_code ?? ''));

        return $countryCode !== '' ? $this->findByIso2($countryCode) : null;
    }

    public function flushCache(): void
    {
        Cache::forget(self::ACTIVE_ALL_CACHE_KEY);
        Cache::forget(self::PROFILE_SELECT_CACHE_KEY);
    }
}
