<?php

declare(strict_types=1);

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
    {
        // v3 additions to nova_cards — guarded so a partially-applied migration can re-run safely
        Schema::table('nova_cards', function (Blueprint $table): void {
            if (! Schema::hasColumn('nova_cards', 'allow_background_reuse')) {
                $table->boolean('allow_background_reuse')->default(true)->after('allow_remix');
            }
            if (! Schema::hasColumn('nova_cards', 'allow_export')) {
                $table->boolean('allow_export')->default(true)->after('allow_background_reuse');
            }
            if (! Schema::hasColumn('nova_cards', 'style_family')) {
                $table->string('style_family', 64)->nullable()->after('allow_export');
            }
            if (! Schema::hasColumn('nova_cards', 'palette_family')) {
                $table->string('palette_family', 64)->nullable()->after('style_family');
            }
            if (! Schema::hasColumn('nova_cards', 'featured_score')) {
                $table->decimal('featured_score', 12, 4)->nullable()->after('trending_score');
            }
            if (! Schema::hasColumn('nova_cards', 'density_score')) {
                $table->tinyInteger('density_score')->unsigned()->nullable()->after('featured_score');
            }
            if (! Schema::hasColumn('nova_cards', 'editor_mode_last_used')) {
                $table->string('editor_mode_last_used', 24)->nullable()->after('density_score');
            }
            if (! Schema::hasColumn('nova_cards', 'original_creator_id')) {
                $table->foreignId('original_creator_id')->nullable()->after('root_card_id')->constrained('users')->nullOnDelete();
            }
            if (! Schema::hasColumn('nova_cards', 'last_ranked_at')) {
                $table->timestamp('last_ranked_at')->nullable()->after('last_engaged_at');
            }
            if (! Schema::hasColumn('nova_cards', 'last_rendered_at')) {
                $table->timestamp('last_rendered_at')->nullable()->after('last_ranked_at');
            }

            // Indexes — ignore errors if they already exist (handled below via DB::statement)
        });

        // Add indexes only if absent (guard against duplicate-index errors)
        $hasIndex = static function (string $table, string $index): bool {
            $driver = DB::getDriverName();

            if ($driver === 'sqlite') {
                return collect(DB::select("PRAGMA index_list('{$table}')"))
                    ->contains(static fn (object $row): bool => ($row->name ?? null) === $index);
            }

            return collect(DB::select("SHOW INDEX FROM `{$table}` WHERE Key_name = ?", [$index]))->isNotEmpty();
        };

        if (! $hasIndex('nova_cards', 'nova_cards_style_family_index')) {
            Schema::table('nova_cards', fn (Blueprint $t) => $t->index('style_family'));
        }
        if (! $hasIndex('nova_cards', 'nova_cards_palette_family_index')) {
            Schema::table('nova_cards', fn (Blueprint $t) => $t->index('palette_family'));
        }
        if (! $hasIndex('nova_cards', 'nova_cards_featured_score_index')) {
            Schema::table('nova_cards', fn (Blueprint $t) => $t->index('featured_score'));
        }
        if (! $hasIndex('nova_cards', 'nova_cards_original_creator_id_index')) {
            Schema::table('nova_cards', fn (Blueprint $t) => $t->index('original_creator_id'));
        }

        // Creator presets table
        if (! Schema::hasTable('nova_card_creator_presets')) {
            Schema::create('nova_card_creator_presets', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('user_id')->constrained()->cascadeOnDelete();
                $table->string('name', 120);
                $table->enum('preset_type', ['style', 'layout', 'background', 'typography', 'starter'])->default('style');
                $table->json('config_json');
                $table->boolean('is_default')->default(false);
                $table->timestamps();
                $table->softDeletes();

                $table->index(['user_id', 'preset_type']);
                $table->index(['user_id', 'is_default']);
            });
        }

        // v3 enhancements to nova_card_collections
        Schema::table('nova_card_collections', function (Blueprint $table): void {
            if (! Schema::hasColumn('nova_card_collections', 'cover_card_id')) {
                $table->unsignedBigInteger('cover_card_id')->nullable()->after('featured');
            }
            if (! Schema::hasColumn('nova_card_collections', 'cover_image_path')) {
                $table->string('cover_image_path', 500)->nullable()->after('cover_card_id');
            }
            if (! Schema::hasColumn('nova_card_collections', 'intro_heading')) {
                $table->string('intro_heading', 160)->nullable()->after('cover_image_path');
            }
            if (! Schema::hasColumn('nova_card_collections', 'sort_mode')) {
                $table->string('sort_mode', 32)->default('manual')->after('intro_heading');
            }
        });

        // v3 enhancements to nova_card_challenges
        Schema::table('nova_card_challenges', function (Blueprint $table): void {
            if (! Schema::hasColumn('nova_card_challenges', 'category')) {
                $table->string('category', 80)->nullable()->after('featured');
            }
            if (! Schema::hasColumn('nova_card_challenges', 'series_slug')) {
                $table->string('series_slug', 120)->nullable()->after('category');
            }
            if (! Schema::hasColumn('nova_card_challenges', 'edition_number')) {
                $table->unsignedInteger('edition_number')->nullable()->after('series_slug');
            }
            if (! Schema::hasColumn('nova_card_challenges', 'cover_image_path')) {
                $table->string('cover_image_path', 500)->nullable()->after('edition_number');
            }
        });

        if (! $hasIndex('nova_card_challenges', 'nova_card_challenges_series_slug_index')) {
            Schema::table('nova_card_challenges', fn (Blueprint $t) => $t->index('series_slug'));
        }
        if (! $hasIndex('nova_card_challenges', 'nova_card_challenges_category_index')) {
            Schema::table('nova_card_challenges', fn (Blueprint $t) => $t->index('category'));
        }

        // Nova card export requests (for queued export generation)
        if (! Schema::hasTable('nova_card_exports')) {
            Schema::create('nova_card_exports', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('card_id')->constrained('nova_cards')->cascadeOnDelete();
                $table->foreignId('user_id')->constrained()->cascadeOnDelete();
                $table->enum('export_type', ['preview', 'hires', 'square', 'story', 'wallpaper', 'og'])->default('preview');
                $table->enum('status', ['pending', 'processing', 'ready', 'failed'])->default('pending');
                $table->string('output_path', 500)->nullable();
                $table->unsignedInteger('width')->nullable();
                $table->unsignedInteger('height')->nullable();
                $table->string('format', 12)->default('webp');
                $table->json('options_json')->nullable();
                $table->timestamp('ready_at')->nullable();
                $table->timestamp('expires_at')->nullable();
                $table->timestamps();

                $table->index(['card_id', 'status']);
                $table->index(['user_id', 'created_at']);
            });
        }
    }

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

        Schema::table('nova_card_challenges', function (Blueprint $table): void {
            $table->dropIndex(['series_slug']);
            $table->dropIndex(['category']);
            $table->dropColumn(['category', 'series_slug', 'edition_number', 'cover_image_path']);
        });

        Schema::table('nova_card_collections', function (Blueprint $table): void {
            $table->dropColumn(['cover_card_id', 'cover_image_path', 'intro_heading', 'sort_mode']);
        });

        Schema::dropIfExists('nova_card_creator_presets');

        Schema::table('nova_cards', function (Blueprint $table): void {
            $table->dropIndex(['style_family']);
            $table->dropIndex(['palette_family']);
            $table->dropIndex(['featured_score']);
            $table->dropIndex(['original_creator_id']);
            $table->dropForeign(['original_creator_id']);
            $table->dropColumn([
                'allow_background_reuse',
                'allow_export',
                'style_family',
                'palette_family',
                'featured_score',
                'density_score',
                'editor_mode_last_used',
                'original_creator_id',
                'last_ranked_at',
                'last_rendered_at',
            ]);
        });
    }
};
