-- ============================================================
-- 表名规范化迁移 v2：通用表加 common_ / 会员相关表加 member_ 前缀
-- 作用：将老库中无前缀的业务表重命名为带前缀的新表名，
--       与 public/install/install.sql 最新定义保持一致。
-- 覆盖映射（前缀自动探测，任意数据库前缀通用）：
--   addon         -> common_addon
--   attachment    -> common_attachment
--   configure     -> common_configure
--   links         -> common_links
--   spider_log    -> common_spider_log
--   spider_stat   -> common_spider_stat
--   sms           -> common_sms
--   member_wallets-> member_wallet          （去复数，不加前缀）
--   notice        -> common_notice
--   ad            -> common_ad
--   task          -> common_task
--   prop          -> common_prop
--   medal         -> common_medal
--   help          -> common_help
--   card          -> common_card
--   score_rule    -> member_score_rule
--   score_log     -> member_score_log
--   addon_config  -> common_addonconf          （框架统一插件配置表）
-- 字段变更：
--   common_nav_menu 新增 app varchar(30) NOT NULL DEFAULT ''（url 之后）
-- 说明：
--   1) 自动从框架核心表 backend_admin 反推表前缀（如 wxapp_），
--      无需手工替换前缀。
--   2) 幂等：仅当「旧表存在 && 新表不存在」才 RENAME，重复执行安全。
--   3) RENAME TABLE 是原子操作，不影响列定义与数据。
--   4) 若库中同时存在旧表与新表（数据分裂），旧表将被跳过、不合并，
--      请先人工核对处理再执行。
--   5) 列级变更（nav_menu.app）通过 information_schema 检查，已存在则跳过。
-- ============================================================

DELIMITER //

-- 单表重命名：旧表存在且新表不存在时才执行
DROP PROCEDURE IF EXISTS `__rename_if`//
CREATE PROCEDURE `__rename_if`(IN p_old VARCHAR(64), IN p_new VARCHAR(64))
BEGIN
  IF EXISTS (
    SELECT 1 FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_old
  ) AND NOT EXISTS (
    SELECT 1 FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_new
  ) THEN
    SET @sql = CONCAT('RENAME TABLE `', p_old, '` TO `', p_new, '`');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END IF;
END//

-- 加列：列不存在时才加（幂等）
DROP PROCEDURE IF EXISTS `__add_col_if_missing`//
CREATE PROCEDURE `__add_col_if_missing`(IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_definition TEXT)
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = p_table
      AND COLUMN_NAME = p_column
  ) AND EXISTS (
    SELECT 1 FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table
  ) THEN
    SET @sql = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_definition);
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END IF;
END//

-- 主流程：探测前缀 + 批量重命名 + 加列
DROP PROCEDURE IF EXISTS `__migrate_table_prefix`//
CREATE PROCEDURE `__migrate_table_prefix`()
BEGIN
  DECLARE v_prefix VARCHAR(64) DEFAULT '';
  DECLARE v_p VARCHAR(70) DEFAULT '';

  -- 1) 反推表前缀：wxapp_backend_admin -> wxapp（不含尾部下划线）
  SELECT SUBSTRING_INDEX(TABLE_NAME, '_backend_admin', 1) INTO v_prefix
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA = DATABASE()
    AND TABLE_NAME LIKE '%\_backend\_admin'
  LIMIT 1;

  -- 2) 兜底：无 backend_admin 的库尝试用导航表反推
  IF v_prefix = '' THEN
    SELECT SUBSTRING_INDEX(TABLE_NAME, '_common_nav_menu', 1) INTO v_prefix
    FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME LIKE '%\_common\_nav\_menu'
    LIMIT 1;
  END IF;

  -- 3) 无法探测则输出提示并终止
  IF v_prefix = '' THEN
    SELECT '无法自动探测表前缀，请将脚本中 CONCAT(v_prefix,...) 替换为真实前缀（如 wxapp_）后执行' AS notice;
  ELSE
    SET v_p = CONCAT(v_prefix, '_');

    -- 表重命名（17 张）
    CALL __rename_if(CONCAT(v_p, 'addon'),         CONCAT(v_p, 'common_addon'));
    CALL __rename_if(CONCAT(v_p, 'attachment'),    CONCAT(v_p, 'common_attachment'));
    CALL __rename_if(CONCAT(v_p, 'configure'),     CONCAT(v_p, 'common_configure'));
    CALL __rename_if(CONCAT(v_p, 'links'),         CONCAT(v_p, 'common_links'));
    CALL __rename_if(CONCAT(v_p, 'spider_log'),    CONCAT(v_p, 'common_spider_log'));
    CALL __rename_if(CONCAT(v_p, 'spider_stat'),   CONCAT(v_p, 'common_spider_stat'));
    CALL __rename_if(CONCAT(v_p, 'sms'),           CONCAT(v_p, 'common_sms'));
    CALL __rename_if(CONCAT(v_p, 'member_wallets'),CONCAT(v_p, 'member_wallet'));
    CALL __rename_if(CONCAT(v_p, 'notice'),        CONCAT(v_p, 'common_notice'));
    CALL __rename_if(CONCAT(v_p, 'ad'),            CONCAT(v_p, 'common_ad'));
    CALL __rename_if(CONCAT(v_p, 'task'),          CONCAT(v_p, 'common_task'));
    CALL __rename_if(CONCAT(v_p, 'prop'),          CONCAT(v_p, 'common_prop'));
    CALL __rename_if(CONCAT(v_p, 'medal'),         CONCAT(v_p, 'common_medal'));
    CALL __rename_if(CONCAT(v_p, 'help'),          CONCAT(v_p, 'common_help'));
    CALL __rename_if(CONCAT(v_p, 'card'),          CONCAT(v_p, 'common_card'));
    CALL __rename_if(CONCAT(v_p, 'score_rule'),    CONCAT(v_p, 'member_score_rule'));
    CALL __rename_if(CONCAT(v_p, 'score_log'),     CONCAT(v_p, 'member_score_log'));
    CALL __rename_if(CONCAT(v_p, 'addon_config'),  CONCAT(v_p, 'common_addonconf'));

    -- 字段变更：导航菜单新增 app 列（url 之后）
    CALL __add_col_if_missing(
      CONCAT(v_p, 'common_nav_menu'),
      'app',
      "varchar(30) NOT NULL DEFAULT '' COMMENT '所属应用（跨应用链接用，空=当前应用）' AFTER `url`"
    );

    -- 数据修复：软删除字段值为 NULL/空 的行（defaultSoftDelete=0 的表会被误过滤，导致角色/菜单查不到）
    -- 幂等：已修复为 0 的行不受影响，可重复执行
    SET @sql := CONCAT('UPDATE `', v_p, 'backend_role` SET `delete_at` = 0 WHERE `delete_at` IS NULL OR `delete_at` = ''''');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END IF;
END//

DELIMITER ;

CALL __migrate_table_prefix();

DROP PROCEDURE IF EXISTS `__rename_if`;
DROP PROCEDURE IF EXISTS `__add_col_if_missing`;
DROP PROCEDURE IF EXISTS `__migrate_table_prefix`;
