<?php

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

return new class extends Migration
{
    public function up(): void
    {
        // MariaDB does not support "DROP INDEX IF EXISTS" inside ALTER TABLE.
        // We check information_schema manually before each drop.

        $this->dropIndexIfExists('devices', 'devices_fcm_token_index');
        $this->dropIndexIfExists('devices', 'devices_device_id_fcm_token_unique');

        // Change column to TEXT (FCM tokens can exceed 255 chars)
        DB::statement('ALTER TABLE devices MODIFY COLUMN fcm_token TEXT NOT NULL');

        // Recreate indexes with a 191-char prefix (required for TEXT columns in MySQL/MariaDB)
        $this->addIndexIfMissing('devices', 'devices_fcm_token_index',
            'ADD INDEX devices_fcm_token_index (fcm_token(191))');

        $this->addIndexIfMissing('devices', 'devices_device_id_fcm_token_unique',
            'ADD UNIQUE INDEX devices_device_id_fcm_token_unique (device_id, fcm_token(191))');
    }

    public function down(): void
    {
        $this->dropIndexIfExists('devices', 'devices_fcm_token_index');
        $this->dropIndexIfExists('devices', 'devices_device_id_fcm_token_unique');

        // Revert to VARCHAR(255)
        DB::statement('ALTER TABLE devices MODIFY COLUMN fcm_token VARCHAR(255) NOT NULL');

        $this->addIndexIfMissing('devices', 'devices_fcm_token_index',
            'ADD INDEX devices_fcm_token_index (fcm_token)');

        $this->addIndexIfMissing('devices', 'devices_device_id_fcm_token_unique',
            'ADD UNIQUE INDEX devices_device_id_fcm_token_unique (device_id, fcm_token)');
    }

    // -------------------------------------------------------------------------

    private function dropIndexIfExists(string $table, string $indexName): void
    {
        $exists = DB::selectOne("
            SELECT COUNT(*) AS cnt
            FROM information_schema.statistics
            WHERE table_schema = DATABASE()
              AND table_name   = ?
              AND index_name   = ?
        ", [$table, $indexName]);

        if ($exists && $exists->cnt > 0) {
            DB::statement("ALTER TABLE `{$table}` DROP INDEX `{$indexName}`");
        }
    }

    private function addIndexIfMissing(string $table, string $indexName, string $alterClause): void
    {
        $exists = DB::selectOne("
            SELECT COUNT(*) AS cnt
            FROM information_schema.statistics
            WHERE table_schema = DATABASE()
              AND table_name   = ?
              AND index_name   = ?
        ", [$table, $indexName]);

        if (!$exists || $exists->cnt === 0) {
            DB::statement("ALTER TABLE `{$table}` {$alterClause}");
        }
    }
};
