<?php

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

/**
 * Phase 2: 견적 시스템 FK 제약조건 제거
 * - estimates.tenant_id → tenants (유지 - 멀티테넌트 핵심)
 * - estimates.model_set_id → categories (제거 - 견적은 스냅샷 성격)
 * - estimate_items.tenant_id → tenants (유지 - 멀티테넌트 핵심)
 * - estimate_items.estimate_id → estimates (제거 - 성능 우선)
 *
 * 목적: 견적 시스템 성능 향상 및 데이터 유연성 확보
 * 주의: 견적 데이터는 스냅샷 성격이므로 참조 무결성보다 성능/유연성이 중요
 */
return new class extends Migration
{
    /**
     * 기존 FK 제약조건 이름을 동적으로 찾는 헬퍼 함수
     */
    private function findForeignKeyName(string $table, string $column): ?string
    {
        $result = DB::selectOne('
            SELECT CONSTRAINT_NAME
            FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
            WHERE TABLE_SCHEMA = DATABASE()
              AND TABLE_NAME = ?
              AND COLUMN_NAME = ?
              AND REFERENCED_TABLE_NAME IS NOT NULL
            LIMIT 1
        ', [$table, $column]);

        return $result ? $result->CONSTRAINT_NAME : null;
    }

    /**
     * FK 제약조건을 안전하게 제거하는 헬퍼 함수
     */
    private function dropForeignKeyIfExists(string $table, string $column): void
    {
        $fkName = $this->findForeignKeyName($table, $column);
        if ($fkName) {
            DB::statement("ALTER TABLE `{$table}` DROP FOREIGN KEY `{$fkName}`");
            echo "✅ Dropped FK: {$table}.{$column} ({$fkName})\n";
        } else {
            echo "ℹ️  No FK found: {$table}.{$column}\n";
        }
    }

    public function up(): void
    {
        echo "🚀 Phase 2: 견적 시스템 FK 제약조건 제거 시작\n\n";

        // 견적 시스템 테이블 존재 여부 확인
        $estimatesExists = Schema::hasTable('estimates');
        $estimateItemsExists = Schema::hasTable('estimate_items');

        if (! $estimatesExists && ! $estimateItemsExists) {
            echo "ℹ️  견적 시스템 테이블이 존재하지 않습니다. 건너뜁니다.\n";

            return;
        }

        if ($estimatesExists) {
            echo "1️⃣  Estimates 테이블 FK 검토...\n";

            // estimates.model_set_id → categories 제거 (견적 스냅샷 특성상 불필요)
            echo "   - model_set_id FK 제거 (견적 스냅샷 특성)\n";
            $this->dropForeignKeyIfExists('estimates', 'model_set_id');

            // estimates.tenant_id → tenants 유지 (멀티테넌트 핵심)
            echo "   - tenant_id FK 유지 (멀티테넌트 보안)\n";

            // 성능을 위한 인덱스 확인/추가
            $indexExists = DB::selectOne("
                SHOW INDEX FROM estimates WHERE Key_name = 'idx_estimates_tenant_model_set'
            ");
            if (! $indexExists) {
                DB::statement('CREATE INDEX idx_estimates_tenant_model_set ON estimates (tenant_id, model_set_id)');
                echo "✅ Added performance index: estimates(tenant_id, model_set_id)\n";
            }
        }

        if ($estimateItemsExists) {
            echo "\n2️⃣  Estimate_items 테이블 FK 검토...\n";

            // estimate_items.estimate_id → estimates 제거 (성능 우선)
            echo "   - estimate_id FK 제거 (성능 우선)\n";
            $this->dropForeignKeyIfExists('estimate_items', 'estimate_id');

            // estimate_items.tenant_id → tenants 유지 (멀티테넌트 핵심)
            echo "   - tenant_id FK 유지 (멀티테넌트 보안)\n";

            // 성능을 위한 인덱스 확인/추가
            $indexExists = DB::selectOne("
                SHOW INDEX FROM estimate_items WHERE Key_name = 'idx_estimate_items_tenant_estimate'
            ");
            if (! $indexExists) {
                DB::statement('CREATE INDEX idx_estimate_items_tenant_estimate ON estimate_items (tenant_id, estimate_id)');
                echo "✅ Added performance index: estimate_items(tenant_id, estimate_id)\n";
            }
        }

        echo "\n🎉 Phase 2 견적 시스템 FK 제거 완료!\n";
        echo "📋 제거된 FK:\n";
        if ($estimatesExists) {
            echo "   - estimates.model_set_id → categories\n";
        }
        if ($estimateItemsExists) {
            echo "   - estimate_items.estimate_id → estimates\n";
        }
        echo "📈 예상 효과: 견적 생성/수정 성능 향상, 카테고리 변경 시 유연성 증가\n";
        echo "🔒 유지된 FK: 멀티테넌트 보안을 위한 tenant_id 관계\n";
    }

    public function down(): void
    {
        echo "🔄 Phase 2 견적 시스템 FK 복구 시작...\n\n";

        if (Schema::hasTable('estimate_items')) {
            echo "1️⃣  Estimate_items FK 복구...\n";
            try {
                Schema::table('estimate_items', function (Blueprint $table) {
                    $table->foreign('estimate_id')
                        ->references('id')
                        ->on('estimates')
                        ->cascadeOnDelete();
                });
                echo "✅ Restored FK: estimate_items.estimate_id → estimates\n";
            } catch (\Throwable $e) {
                echo '⚠️  Could not restore FK: estimate_items.estimate_id - '.$e->getMessage()."\n";
            }
        }

        if (Schema::hasTable('estimates')) {
            echo "\n2️⃣  Estimates FK 복구...\n";
            try {
                Schema::table('estimates', function (Blueprint $table) {
                    $table->foreign('model_set_id')
                        ->references('id')
                        ->on('categories')
                        ->restrictOnDelete();
                });
                echo "✅ Restored FK: estimates.model_set_id → categories\n";
            } catch (\Throwable $e) {
                echo '⚠️  Could not restore FK: estimates.model_set_id - '.$e->getMessage()."\n";
            }
        }

        echo "\n🔄 Phase 2 FK 복구 완료!\n";
    }
};
