<?php

declare(strict_types=1);

use Hyperf\DbConnection\Db;
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // 1. 新增 bundled 字段（组合商品映射标记）
        // 注意：PostgreSQL 不支持 ALTER TABLE ... AFTER column，因此不使用 ->after()
        Schema::table('skus_mapping', function (Blueprint $table) {
            $table->boolean('bundled')->default(false)->comment('是否为组合商品映射');
        });

        // 2. 回填 origin_sku_id：通过 (origin_sku, company_id) 关联 skus_origin
        // 预部署阶段：若回填后仍存在 NULL（孤儿记录），后续 SET NOT NULL 会失败，
        // 由开发者手动清理；此处不做静默兜底
        Db::statement('
            UPDATE skus_mapping sm
            SET origin_sku_id = so.id
            FROM skus_origin so
            WHERE sm.origin_sku_id IS NULL
              AND so.sku = sm.origin_sku
              AND so.company_id = sm.company_id
        ');

        // 3. 收紧 origin_sku_id 为 NOT NULL
        Db::statement('ALTER TABLE skus_mapping ALTER COLUMN origin_sku_id SET NOT NULL');

        // 4. 回填 platform_outer_sku：NULL 或空串回落到 origin_sku（保持最小可行映射值）
        Db::statement("
            UPDATE skus_mapping
            SET platform_outer_sku = origin_sku
            WHERE platform_outer_sku IS NULL OR platform_outer_sku = ''
        ");

        // 5. 收紧 platform_outer_sku 为 NOT NULL
        Db::statement('ALTER TABLE skus_mapping ALTER COLUMN platform_outer_sku SET NOT NULL');

        // 6. 替换唯一索引：uk_platform_product → uk_origin_platform_sku
        // 旧索引形态：CREATE UNIQUE INDEX uk_platform_product ... WHERE platform_product_id IS NOT NULL
        // 因此必须用 DROP INDEX（兼容 constraint 形态的历史数据用 IF EXISTS 两边兜底）
        Db::statement('ALTER TABLE skus_mapping DROP CONSTRAINT IF EXISTS uk_platform_product');
        Db::statement('DROP INDEX IF EXISTS uk_platform_product');

        Db::statement('
            CREATE UNIQUE INDEX uk_origin_platform_sku
            ON skus_mapping (origin_sku_id, platform_id, platform_outer_sku)
        ');
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        // 反向顺序：删新索引 → 恢复旧索引 → 放宽 outer → 放宽 origin_sku_id → 删除 bundled
        Db::statement('DROP INDEX IF EXISTS uk_origin_platform_sku');

        // 恢复旧索引（保留 2026_04_14_120000 中的 WHERE 子句形态）
        // DROP IF EXISTS 兜底：若 up 半途失败使旧索引未被 drop，此 down 仍能幂等恢复
        Db::statement('ALTER TABLE skus_mapping DROP CONSTRAINT IF EXISTS uk_platform_product');
        Db::statement('DROP INDEX IF EXISTS uk_platform_product');
        Db::statement('
            CREATE UNIQUE INDEX uk_platform_product
            ON skus_mapping (platform_id, platform_product_id)
            WHERE platform_product_id IS NOT NULL
        ');

        Db::statement('ALTER TABLE skus_mapping ALTER COLUMN platform_outer_sku DROP NOT NULL');
        Db::statement('ALTER TABLE skus_mapping ALTER COLUMN origin_sku_id DROP NOT NULL');

        Schema::table('skus_mapping', function (Blueprint $table) {
            $table->dropColumn('bundled');
        });
    }
};
