<?php

use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\UserFlight;
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
    {
        // ---------------------------------------------------------------------
        // Crew Types
        // ---------------------------------------------------------------------
        Schema::create('crew_types', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('internal_name')->unique();
        });

        DB::table('crew_types')->insert([
            ['name' => 'Unspecified',       'internal_name' => 'unspecified'],
            ['name' => 'Cabin Crew',       'internal_name' => 'cabin_crew'],
            ['name' => 'Purser / CSM',           'internal_name' => 'purser'],
            ['name' => 'Captain',          'internal_name' => 'captain'],
            ['name' => 'First Officer',    'internal_name' => 'first_officer'],
            ['name' => 'Second Officer',   'internal_name' => 'second_officer'],
            ['name' => 'Deadhead',     'internal_name' => 'deadhead'],
            ['name' => 'Marshal / Security',  'internal_name' => 'marshal'],
        ]);

        // ---------------------------------------------------------------------
        // Followees
        // ---------------------------------------------------------------------
        Schema::create('followees', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
            $table->foreignId('followee_id')->constrained('users')->cascadeOnDelete();
            $table->timestamps();

            $table->unique(['user_id', 'followee_id']);
        });

        // ---------------------------------------------------------------------
        // User Actions
        // ---------------------------------------------------------------------
        Schema::create('user_actions', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
            $table->unsignedBigInteger('user_flight_id');
            $table->text('message');
            $table->timestamps();
        });

        // ---------------------------------------------------------------------
        // Achievements
        // ---------------------------------------------------------------------
        Schema::create('achievements', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('internal_name')->unique();
            $table->text('description');
            $table->string('icon');
        });

        // ---------------------------------------------------------------------
        // User Achievements
        // ---------------------------------------------------------------------
        Schema::create('user_achievements', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
            $table->foreignId('achievement_id')->constrained('achievements')->cascadeOnDelete();
            $table->timestamps();

            $table->unique(['user_id', 'achievement_id']);
        });

        DB::statement('ALTER TABLE flight_classes ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY');
        DB::statement('ALTER TABLE flight_reasons ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY');

        DB::statement("
            SELECT setval(
                pg_get_serial_sequence('flight_classes', 'id'),
                (SELECT MAX(id) FROM flight_classes)
            )
        ");

        DB::statement("
            SELECT setval(
                pg_get_serial_sequence('flight_reasons', 'id'),
                (SELECT MAX(id) FROM flight_reasons)
            )
        ");

        DB::table('flight_classes')->insert([
            ['name' => 'General Aviation'],
            ['name' => 'Crew'],
        ]);

        DB::table('flight_reasons')->insert([
            ['name' => 'Visiting Friends / Relatives'],
        ]);

        Schema::table('flight_classes', function (Blueprint $table) {
            $table->string('internal_name')->nullable();
        });

        DB::table('flight_classes')->get()->each(function ($row) {
            DB::table('flight_classes')
                ->where('id', $row->id)
                ->update(['internal_name' => Str::slug($row->name, '_')]);
        });

        Schema::table('flight_classes', function (Blueprint $table) {
            $table->string('internal_name')->nullable(false)->unique()->change();
        });

        Schema::table('user_flights', function (Blueprint $table) {
            $table->foreignId('crew_type_id')->nullable()->constrained('crew_types')->nullOnDelete();
        });

        $economy = FlightClass::where('internal_name', 'economy')->first();
        $unspecified = FlightClass::where('internal_name', 'unspecified')->first();
        UserFlight::where('flight_class_id', $unspecified->id)->update(['flight_class_id' => $economy->id]);

        FlightReason::where('name', 'Other')->update(['id' => 999]);
    }

    public function down(): void
    {
        Schema::dropIfExists('user_achievements');
        Schema::dropIfExists('achievements');
        Schema::dropIfExists('user_actions');
        Schema::dropIfExists('followees');
        Schema::dropIfExists('crew_types');
        DB::table('flight_classes')->whereIn('name', ['General Aviation', 'Crew'])->delete();
        DB::table('flight_reasons')->where('name', 'Crew')->delete();
    }
};
