<?php

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

/**
 * 系统级修复：扩展 config_items.code 字段长度到 VARCHAR(150)
 *
 * 背景：历史生产环境（从旧版升级）为 VARCHAR(50)，install.sql 标准为 VARCHAR(100)。
 *       随着应用配置项命名规范 app_{app_id}_{key} 的使用，code 容易超过 50 字符。
 *       例如 app_cmspro_rabbitmath_target_bonus_fragment_multiplier（53字符）会触发
 *       SQLSTATE[22001]: Data too long for column 'code' 错误。
 *
 * 长度选择：VARCHAR(150)，基于 188 个配置项长度分析：
 *   - 当前最长 54 字符，P99=50 字符
 *   - 极端场景（超长应用ID 28字符 + 超长配置项名 50 字符）= 83 字符
 *   - VARCHAR(150) 给未来留 67 字符余量，存储和性能与 VARCHAR(100) 无差异
 *
 * 作用：确保所有环境（无论从哪个旧版本升级）的 config_items.code 都是 VARCHAR(150)。
 *
 * 幂等性：检查当前字段长度，仅在 < 150 时执行 ALTER。
 * 回滚策略：不提供 down()，避免影响已存储的长 code 配置项。
 *           如需回滚：ALTER TABLE config_items MODIFY COLUMN code VARCHAR(50) NOT NULL;
 */
return new class extends Migration
{
    public function up(): void
    {
        // SQLite 是动态类型，不需要修改字段长度
        if (DB::getDriverName() === 'sqlite') {
            return;
        }

        $currentLength = $this->getConfigItemCodeColumnLength();

        if ($currentLength > 0 && $currentLength < 150) {
            DB::statement("ALTER TABLE `config_items` MODIFY COLUMN `code` VARCHAR(150) NOT NULL");
        }
    }

    /**
     * 获取 config_items.code 字段的当前长度。
     *
     * 兼容 MySQL（SHOW COLUMNS）和 SQLite（PRAGMA table_info）。
     * 返回 0 表示字段不存在或无法解析。
     */
    private function getConfigItemCodeColumnLength(): int
    {
        // MySQL: SHOW COLUMNS
        try {
            $column = DB::selectOne("SHOW COLUMNS FROM `config_items` WHERE Field = 'code'");
            if ($column && preg_match('/varchar\((\d+)\)/', $column->Type ?? '', $matches)) {
                return (int) $matches[1];
            }
        } catch (\Throwable) {
            // SQLite 不支持 SHOW COLUMNS，继续尝试 PRAGMA
        }

        // SQLite: PRAGMA table_info
        try {
            $columns = DB::select("PRAGMA table_info(`config_items`)");
            foreach ($columns as $col) {
                if (($col->name ?? null) === 'code') {
                    // SQLite 的 type 字段格式如 "varchar(150)" 或 "VARCHAR(150)"
                    if (preg_match('/varchar\((\d+)\)/i', $col->type ?? '', $matches)) {
                        return (int) $matches[1];
                    }
                    return 100; // 默认长度
                }
            }
        } catch (\Throwable) {
            // 忽略
        }

        return 0;
    }

    public function down(): void
    {
        // 不回滚系统表变更，避免影响已存储的长 code 配置项
        // 如需回滚请手动执行：ALTER TABLE config_items MODIFY COLUMN code VARCHAR(50) NOT NULL;
    }
};
