<?php
declare(strict_types=1);

namespace App\Infrastructure\GeoIp;

use PDO;
use RuntimeException;

final class CountryDataService
{
    private const string RESTCOUNTRIES_API_URL = 'https://restcountries.com/v3.1/all?fields=cca2,name,translations';

    public function __construct(
        private readonly PDO $database
    ) {
    }

    public function loadCountryData(): int
    {
        echo "Lade Länderdaten von RestCountries API...\n";

        $jsonData = file_get_contents(self::RESTCOUNTRIES_API_URL);
        if (!$jsonData) {
            throw new RuntimeException('Konnte Länderdaten nicht herunterladen');
        }

        $countries = json_decode($jsonData, true);
        if (!$countries) {
            throw new RuntimeException('Ungültige JSON-Daten erhalten');
        }

        $this->database->beginTransaction();
        $this->database->exec('DELETE FROM countries');

        $stmt = $this->database->prepare('INSERT INTO countries (code, name_en, name_de, name_native, updated_at) VALUES (?, ?, ?, ?, ?)');

        $processed = 0;
        foreach ($countries as $countryData) {
            $country = $this->parseCountryData($countryData);
            if ($country) {
                $stmt->execute([
                    $country->code,
                    $country->nameEn,
                    $country->nameDe,
                    $country->nameNative,
                    $country->updatedAt
                ]);
                $processed++;
            }
        }

        $this->database->commit();
        echo "Länderdatenbank aktualisiert: {$processed} Länder geladen\n";

        return $processed;
    }

    public function getCountryByCode(string $code): ?Country
    {
        $stmt = $this->database->prepare('SELECT * FROM countries WHERE code = ?');
        $stmt->execute([$code]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$result) {
            return null;
        }

        return new Country(
            code: $result['code'],
            nameEn: $result['name_en'],
            nameDe: $result['name_de'],
            nameNative: $result['name_native'],
            updatedAt: $result['updated_at']
        );
    }

    private function parseCountryData(array $countryData): ?Country
    {
        $code = $countryData['cca2'] ?? null;
        $nameEn = $countryData['name']['common'] ?? null;

        if (!$code || !$nameEn) {
            return null;
        }

        $nameDe = $countryData['translations']['deu']['common'] ?? $nameEn;
        $nativeNames = $countryData['name']['nativeName'] ?? [];
        $nameNative = !empty($nativeNames)
            ? $nativeNames[array_key_first($nativeNames)]['common'] ?? $nameEn
            : $nameEn;

        return new Country(
            code: $code,
            nameEn: $nameEn,
            nameDe: $nameDe,
            nameNative: $nameNative,
            updatedAt: date('Y-m-d H:i:s')
        );
    }
}
