<?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
    {
        // 业务幂等保护：
        // - credit_ledger: 同一 (ref_type, ref_id, reason) 三元组只允许一条；同 ticket_item 可存在
        //   多 reason 流水（bet_hold_release + game_settlement_loss），但同一笔业务动作（同一 reason）
        //   重复插入会被拒。注：ref_id IS NULL 的行（如 bet 占位）不参与唯一约束。
        // - share_ledger.reversal_of_id: 同一原账只允许一条反转（业务语义「补差冲正」每张原票仅一次）。
        $driver = Schema::getConnection()->getDriverName();

        if (Schema::hasTable('credit_ledger') && ! $this->hasIndex('credit_ledger', 'uk_credit_ledger_ref_reason')) {
            if ($driver === 'pgsql') {
                DB::statement('CREATE UNIQUE INDEX uk_credit_ledger_ref_reason ON credit_ledger (ref_type, ref_id, reason) WHERE ref_id IS NOT NULL');
            } elseif ($driver === 'sqlite') {
                DB::statement('CREATE UNIQUE INDEX uk_credit_ledger_ref_reason ON credit_ledger (ref_type, ref_id, reason) WHERE ref_id IS NOT NULL');
            } else {
                Schema::table('credit_ledger', function (Blueprint $table): void {
                    $table->unique(['ref_type', 'ref_id', 'reason'], 'uk_credit_ledger_ref_reason');
                });
            }
        }

        if (Schema::hasTable('share_ledger') && ! $this->hasIndex('share_ledger', 'uk_share_ledger_reversal_of')) {
            if ($driver === 'pgsql') {
                DB::statement('CREATE UNIQUE INDEX uk_share_ledger_reversal_of ON share_ledger (reversal_of_id) WHERE reversal_of_id IS NOT NULL');
            } elseif ($driver === 'sqlite') {
                DB::statement('CREATE UNIQUE INDEX uk_share_ledger_reversal_of ON share_ledger (reversal_of_id) WHERE reversal_of_id IS NOT NULL');
            } else {
                Schema::table('share_ledger', function (Blueprint $table): void {
                    $table->unique('reversal_of_id', 'uk_share_ledger_reversal_of');
                });
            }
        }
    }

    public function down(): void
    {
        $driver = Schema::getConnection()->getDriverName();

        if (Schema::hasTable('share_ledger') && $this->hasIndex('share_ledger', 'uk_share_ledger_reversal_of')) {
            if (in_array($driver, ['pgsql', 'sqlite'], true)) {
                DB::statement('DROP INDEX IF EXISTS uk_share_ledger_reversal_of');
            } else {
                Schema::table('share_ledger', function (Blueprint $table): void {
                    $table->dropUnique('uk_share_ledger_reversal_of');
                });
            }
        }

        if (Schema::hasTable('credit_ledger') && $this->hasIndex('credit_ledger', 'uk_credit_ledger_ref_reason')) {
            if (in_array($driver, ['pgsql', 'sqlite'], true)) {
                DB::statement('DROP INDEX IF EXISTS uk_credit_ledger_ref_reason');
            } else {
                Schema::table('credit_ledger', function (Blueprint $table): void {
                    $table->dropUnique('uk_credit_ledger_ref_reason');
                });
            }
        }
    }

    private function hasIndex(string $table, string $indexName): bool
    {
        return Schema::hasIndex($table, $indexName);
    }
};
