<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * @intent Migração resiliente e isolada para PostgreSQL 18 (Grep-Friendly) do módulo {{ module }}
 *         (`{{ module_lower }}`).
 *
 * @description Schema isolation, lock timeout, uuidv7() nativo, corpo em jsonb e `down()`
 *              que **não destrói dados** (ADR-017): renomeia para `backup_{{ table }}_<ts>`.
 */
return new class extends Migration
{
    private const string MODULE_SCHEMA = '{{ schema }}';

    public function up(): void
    {
        DB::statement("SET lock_timeout = '3s';");
        DB::statement('CREATE SCHEMA IF NOT EXISTS '.self::MODULE_SCHEMA.';');
        DB::statement('SET search_path TO '.self::MODULE_SCHEMA.', public;');

        // ADR-017/spec 10: idempotente — reexecutar não recria a tabela.
        if (Schema::hasTable('{{ table }}')) {
            DB::statement('RESET search_path;');

            return;
        }

        Schema::create('{{ table }}', function (Blueprint $table) {
            $table->uuid('id')->primary()->default(new Expression('uuidv7()'));

            // ADR-007: `text` (não varchar(n)); JSONB para conteúdo (ADR-017).
            $table->text('title');
            $table->text('description')->nullable();
            $table->jsonb('corpo')->nullable();
            $table->jsonb('metadados')->nullable();
            $table->boolean('is_active')->default(true);

            $table->timestampsTz();
            $table->softDeletesTz();
        });

        DB::statement(
            'CREATE INDEX IF NOT EXISTS {{ table }}_ativos_idx ON {{ table }} (id) WHERE deleted_at IS NULL;'
        );

        DB::statement('RESET search_path;');
    }

    /**
     * ADR-017: nunca dropa. Renomeia a tabela para backup datado e deixa o DBA decidir.
     */
    public function down(): void
    {
        $backup = 'backup_{{ table }}_'.date('YmdHis');

        DB::statement('SET search_path TO '.self::MODULE_SCHEMA.', public;');
        DB::statement("ALTER TABLE IF EXISTS {{ table }} RENAME TO \"{$backup}\";");
        DB::statement('RESET search_path;');
    }
};
