<?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
    {
        if (DB::getDriverName() === 'mysql') {
            DB::statement("ALTER TABLE playlists MODIFY COLUMN visibility ENUM('public', 'private', 'unlisted') NOT NULL DEFAULT 'private'");
        } else {
            // SQLite stores enums as CHECK constraints; use table rebuild to update the constraint.
            $this->rebuildSqliteEnum(['public', 'private', 'unlisted']);
        }
    }

    public function down(): void
    {
        if (DB::getDriverName() === 'mysql') {
            DB::table('playlists')->where('visibility', 'unlisted')->update(['visibility' => 'private']);
            DB::statement("ALTER TABLE playlists MODIFY COLUMN visibility ENUM('public', 'private') NOT NULL DEFAULT 'private'");
        } else {
            DB::table('playlists')->where('visibility', 'unlisted')->update(['visibility' => 'private']);
            $this->rebuildSqliteEnum(['public', 'private']);
        }
    }

    private function rebuildSqliteEnum(array $values): void
    {
        $inList = implode(', ', array_map(fn($v) => "'$v'", $values));

        DB::statement('PRAGMA foreign_keys = OFF');

        DB::statement("
            CREATE TABLE playlists_new (
                id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                user_id INTEGER NOT NULL,
                name VARCHAR(255) NOT NULL,
                description TEXT,
                thumbnail VARCHAR(255),
                visibility VARCHAR(255) CHECK (visibility IN ({$inList})) NOT NULL DEFAULT 'private',
                is_default TINYINT(1) NOT NULL DEFAULT 0,
                created_at DATETIME,
                updated_at DATETIME,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");

        DB::statement('INSERT INTO playlists_new SELECT * FROM playlists');
        DB::statement('DROP TABLE playlists');
        DB::statement('ALTER TABLE playlists_new RENAME TO playlists');

        // Recreate indexes
        DB::statement('CREATE INDEX playlists_user_id_visibility_index ON playlists (user_id, visibility)');

        DB::statement('PRAGMA foreign_keys = ON');
    }
};
