<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('airports', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->decimal('latitude_deg', 10, 6);
            $table->decimal('longitude_deg', 10, 6);
            $table->integer('elevation_ft')->nullable();
            $table->foreignId('region_id')->constrained('regions');
            $table->string('municipality')->nullable();
            $table->string('icao_code')->nullable();
            $table->string('iata_code')->nullable();
            $table->string('local_code')->nullable();
            $table->string('type');
            $table->timestamps();
        });

        $this->importCsv();
    }

    public function down(): void
    {
        Schema::dropIfExists('airports');
    }

    private function importCsv(): void
    {
        $path = storage_path('app/private/seed_data/airports.csv');

        if (! file_exists($path)) {
            throw new \RuntimeException("Airports CSV not found at: {$path}");
        }

        $handle = fopen($path, 'rb');

        if ($handle === false) {
            throw new \RuntimeException("Failed to open airports CSV at: {$path}");
        }

        // Skip header row
        fgetcsv($handle);

        $regionMap = DB::table('regions')->pluck('id', 'code')->all();

        $batch     = [];
        $batchSize = 500;
        $now       = now()->toDateTimeString();

        while (($row = fgetcsv($handle)) !== false) {
            if (count($row) < 19) {
                continue;
            }

            // id, ident, type, name, latitude_deg, longitude_deg, elevation_ft,
            // continent, iso_country, iso_region, municipality, scheduled_service,
            // icao_code, iata_code, gps_code, local_code, home_link, wikipedia_link, keywords
            [
                ,
                ,
                $type,
                $name,
                $latitudeDeg,
                $longitudeDeg,
                $elevationFt,
                ,
                ,
                $isoRegion,
                $municipality,
                ,
                $icaoCode,
                $iataCode,
                ,
                $localCode,
            ] = $row;

            $icaoCode = trim(str_replace(["\r", "\n"], '', $icaoCode));
            $iataCode = trim(str_replace(["\r", "\n"], '', $iataCode));

            // Skip rows without at least one of iata or icao
            if ($icaoCode === '' && $iataCode === '') {
                continue;
            }

            $isoRegion = trim($isoRegion);

            if (! isset($regionMap[$isoRegion])) {
                continue;
            }

            $elevationFt = trim($elevationFt);

            $batch[] = [
                'type'              => trim($type),
                'name'              => trim($name),
                'latitude_deg'      => (float) trim($latitudeDeg),
                'longitude_deg'     => (float) trim($longitudeDeg),
                'elevation_ft'      => $elevationFt !== '' ? (int) $elevationFt : null,
                'region_id'         => $regionMap[$isoRegion],
                'municipality'      => trim($municipality) !== '' ? trim($municipality) : null,
                'icao_code'         => $icaoCode !== '' ? $icaoCode : null,
                'iata_code'         => $iataCode !== '' ? $iataCode : null,
                'local_code'        => trim($localCode) !== '' ? trim($localCode) : null,
                'created_at'        => $now,
                'updated_at'        => $now,
            ];

            if (count($batch) >= $batchSize) {
                DB::table('airports')->insert($batch);
                $batch = [];
            }
        }

        fclose($handle);

        if (! empty($batch)) {
            DB::table('airports')->insert($batch);
        }
    }
};
