<?php

declare(strict_types=1);

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

/**
 * Sanctum's default `morphs('tokenable')` creates BIGINT UNSIGNED tokenable_id,
 * but every W·Dot model uses CHAR(36) UUID primary keys.  Widen the column so
 * fresh installs do not need a manual ALTER.
 *
 * Empty tables are altered safely; existing numeric values cannot fit but
 * Sanctum is fresh at install time so this only fires when the table is empty.
 */
return new class extends Migration
{
    public function up(): void
    {
        if (! Schema::hasTable('personal_access_tokens')) {
            return;
        }

        // Detect current column type — skip if already CHAR(36)/VARCHAR.
        $col = collect(DB::select(
            "SHOW COLUMNS FROM personal_access_tokens WHERE Field = 'tokenable_id'"
        ))->first();
        if (! $col) {
            return;
        }
        $type = strtolower((string) $col->Type);
        if (str_contains($type, 'char') || str_contains($type, 'varchar')) {
            return; // already UUID-compatible
        }

        // Drop the morphs index (Laravel default name).
        try {
            DB::statement('ALTER TABLE personal_access_tokens DROP INDEX personal_access_tokens_tokenable_type_tokenable_id_index');
        } catch (\Throwable) {
            // ignore — index may be named differently or already gone
        }

        DB::statement('ALTER TABLE personal_access_tokens MODIFY tokenable_id CHAR(36) NOT NULL');

        // Re-create the composite index with the same name.
        try {
            DB::statement('CREATE INDEX personal_access_tokens_tokenable_type_tokenable_id_index ON personal_access_tokens (tokenable_type, tokenable_id)');
        } catch (\Throwable) {
            // ignore — index may already exist
        }
    }

    public function down(): void
    {
        // Reverting to BIGINT would break existing UUID tokens; intentionally a no-op.
    }
};
