<?php

use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Migrations\Migration;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * 将 orders 表转换为 TimescaleDB hypertable
     *
     * 注意事项：
     * 1. Hypertable 要求主键和唯一约束必须包含分区键 (created_date)
     * 2. Hypertable 不支持被外键引用，需先删除 order_items 的外键
     * 3. 转换后数据完整性需在应用层保证
     */
    public function up(): void
    {
        // 1. 删除 order_items 表对 orders 的外键约束
        Schema::table('order_items', function ($table) {
            $table->dropForeign(['order_id']);
        });

        // 2. 删除原有的主键约束
        Schema::getConnection()->statement('ALTER TABLE orders DROP CONSTRAINT orders_pkey');

        // 3. 删除原有的唯一约束
        Schema::getConnection()->statement('ALTER TABLE orders DROP CONSTRAINT orders_store_platform_order_unique');

        // 4. 创建新的复合主键（包含分区键）
        Schema::getConnection()->statement('ALTER TABLE orders ADD PRIMARY KEY (id, created_date)');

        // 5. 转换为 hypertable（按年分区）
        Schema::getConnection()->statement("
            SELECT create_hypertable('orders', 'created_date',
                chunk_time_interval => INTERVAL '1 year',
                migrate_data => true
            )
        ");

        // 6. 创建新的唯一约束（包含分区键）
        Schema::getConnection()->statement('
            ALTER TABLE orders ADD CONSTRAINT orders_store_platform_order_unique
            UNIQUE (store_id, platform_order_id, created_date)
        ');
    }

    /**
     * Reverse the migrations.
     *
     * 警告：回滚 hypertable 会丢失分区结构，数据会保留但需要手动处理
     */
    public function down(): void
    {
        // 注意：TimescaleDB 不支持直接将 hypertable 转回普通表
        // 需要创建新表、迁移数据、删除 hypertable、重命名新表

        // 1. 创建临时表
        Schema::getConnection()->statement('
            CREATE TABLE orders_temp AS SELECT * FROM orders
        ');

        // 2. 删除 hypertable
        Schema::getConnection()->statement('DROP TABLE orders');

        // 3. 重命名临时表
        Schema::getConnection()->statement('ALTER TABLE orders_temp RENAME TO orders');

        // 4. 重建原有约束
        Schema::getConnection()->statement('ALTER TABLE orders ADD PRIMARY KEY (id)');
        Schema::getConnection()->statement('
            ALTER TABLE orders ADD CONSTRAINT orders_store_platform_order_unique
            UNIQUE (store_id, platform_order_id)
        ');

        // 5. 重建外键
        Schema::table('order_items', function ($table) {
            $table->foreign('order_id')
                ->references('id')
                ->on('orders')
                ->onDelete('cascade');
        });

        // 6. 重建序列（如果需要）
        Schema::getConnection()->statement("
            SELECT setval('orders_id_seq', (SELECT MAX(id) FROM orders))
        ");
    }
};
