-- iMeeting legacy DB upgrade
-- Goal: upgrade an old schema to the latest application-facing structure
-- Strategy:
-- 1) standardize system tables to sys_* base tables
-- 2) align shared table columns/indexes
-- 3) create missing configuration tables
-- 4) migrate legacy configuration/hot-word data into new tables
-- 5) rebuild menu tree and role permissions needed by the latest backend
-- 6) recreate compatibility views

-- ----------------------------------------------------------------------
-- 1. Rename legacy system tables to sys_* base tables when needed
-- ----------------------------------------------------------------------
SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'users' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_users'
    ),
    'RENAME TABLE users TO sys_users',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'roles' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_roles'
    ),
    'RENAME TABLE roles TO sys_roles',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'menus' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus'
    ),
    'RENAME TABLE menus TO sys_menus',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'role_menu_permissions' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions'
    ),
    'RENAME TABLE role_menu_permissions TO sys_role_menu_permissions',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'dict_data' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_dict_data'
    ),
    'RENAME TABLE dict_data TO sys_dict_data',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'system_parameters' AND table_type = 'BASE TABLE'
    ) AND NOT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = DATABASE() AND table_name = 'sys_system_parameters'
    ),
    'RENAME TABLE system_parameters TO sys_system_parameters',
    'SELECT 1'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

-- ----------------------------------------------------------------------
-- 2. Align existing sys_* tables
-- ----------------------------------------------------------------------
SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_users' AND index_name = 'idx_role_id'
    ),
    'SELECT 1',
    'ALTER TABLE sys_users ADD KEY idx_role_id (role_id)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_roles' AND index_name = 'uk_role_name'
    ),
    'SELECT 1',
    'ALTER TABLE sys_roles ADD UNIQUE KEY uk_role_name (role_name)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND column_name = 'menu_level'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD COLUMN menu_level TINYINT(3) NOT NULL DEFAULT 1 COMMENT ''菜单层级（根节点为1）'' AFTER parent_id'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND column_name = 'tree_path'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD COLUMN tree_path VARCHAR(255) DEFAULT NULL COMMENT ''树路径（如 /3/6）'' AFTER menu_level'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND column_name = 'is_visible'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD COLUMN is_visible TINYINT(1) NOT NULL DEFAULT 1 COMMENT ''是否在侧边菜单显示'' AFTER is_active'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND index_name = 'idx_menu_level'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD KEY idx_menu_level (menu_level)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND index_name = 'idx_tree_path'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD KEY idx_tree_path (tree_path)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND index_name = 'idx_is_visible'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD KEY idx_is_visible (is_visible)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_menus' AND index_name = 'idx_menus_visible_tree'
    ),
    'SELECT 1',
    'ALTER TABLE sys_menus ADD KEY idx_menus_visible_tree (is_active, is_visible, parent_id, sort_order, menu_id)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND column_name = 'granted_by'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD COLUMN granted_by INT(11) DEFAULT NULL COMMENT ''授权操作人ID'' AFTER menu_id'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND column_name = 'granted_at'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD COLUMN granted_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT ''授权时间'' AFTER granted_by'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND index_name = 'idx_granted_by'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD KEY idx_granted_by (granted_by)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND index_name = 'idx_granted_at'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD KEY idx_granted_at (granted_at)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND index_name = 'idx_rmp_role'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD KEY idx_rmp_role (role_id)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'sys_role_menu_permissions' AND index_name = 'idx_rmp_menu'
    ),
    'SELECT 1',
    'ALTER TABLE sys_role_menu_permissions ADD KEY idx_rmp_menu (menu_id)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

ALTER TABLE `terminals`
MODIFY COLUMN `current_user_id` INT(11) DEFAULT NULL COMMENT '终端绑定账号';

-- prompts: add is_system and composite index
SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = DATABASE() AND table_name = 'prompts' AND column_name = 'is_system'
    ),
    'SELECT 1',
    'ALTER TABLE prompts ADD COLUMN is_system TINYINT(1) NOT NULL DEFAULT 0 AFTER creator_id'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @sql := (
  SELECT IF(
    EXISTS (
      SELECT 1 FROM information_schema.statistics
      WHERE table_schema = DATABASE() AND table_name = 'prompts' AND index_name = 'idx_prompts_task_scope_active'
    ),
    'SELECT 1',
    'CREATE INDEX idx_prompts_task_scope_active ON prompts (task_type, is_system, creator_id, is_active, is_default)'
  )
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

UPDATE prompts
SET is_system = 1
WHERE creator_id = 1;

-- ----------------------------------------------------------------------
-- 3. Create missing tables with latest structure
-- ----------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `sys_system_parameters` (
  `param_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `param_key` varchar(128) NOT NULL,
  `param_name` varchar(255) NOT NULL,
  `param_value` text,
  `value_type` varchar(32) NOT NULL DEFAULT 'string',
  `category` varchar(64) NOT NULL DEFAULT 'system',
  `description` varchar(500) DEFAULT NULL,
  `is_active` tinyint(1) NOT NULL DEFAULT '1',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`param_id`),
  UNIQUE KEY `uk_param_key` (`param_key`),
  KEY `idx_param_category` (`category`),
  KEY `idx_param_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS `ai_model_configs` (
  `model_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `model_code` varchar(128) NOT NULL,
  `model_name` varchar(255) NOT NULL,
  `model_type` varchar(32) NOT NULL,
  `provider` varchar(64) DEFAULT NULL,
  `endpoint_url` varchar(512) DEFAULT NULL,
  `api_key` varchar(512) DEFAULT NULL,
  `llm_model_name` varchar(128) DEFAULT NULL,
  `llm_timeout` int(11) DEFAULT NULL,
  `llm_temperature` decimal(5,2) DEFAULT NULL,
  `llm_top_p` decimal(5,2) DEFAULT NULL,
  `llm_max_tokens` int(11) DEFAULT NULL,
  `llm_system_prompt` text,
  `asr_model_name` varchar(128) DEFAULT NULL,
  `asr_vocabulary_id` varchar(255) DEFAULT NULL,
  `asr_speaker_count` int(11) DEFAULT NULL,
  `asr_language_hints` varchar(255) DEFAULT NULL,
  `asr_disfluency_removal_enabled` tinyint(1) DEFAULT NULL,
  `asr_diarization_enabled` tinyint(1) DEFAULT NULL,
  `config_json` json DEFAULT NULL,
  `description` varchar(500) DEFAULT NULL,
  `is_active` tinyint(1) NOT NULL DEFAULT '1',
  `is_default` tinyint(1) NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`model_id`),
  UNIQUE KEY `uk_model_code` (`model_code`),
  KEY `idx_model_type` (`model_type`),
  KEY `idx_model_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS `llm_model_config` (
  `config_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `model_code` varchar(128) NOT NULL,
  `model_name` varchar(255) NOT NULL,
  `provider` varchar(64) DEFAULT NULL,
  `endpoint_url` varchar(512) DEFAULT NULL,
  `api_key` varchar(512) DEFAULT NULL,
  `llm_model_name` varchar(128) NOT NULL,
  `llm_timeout` int(11) NOT NULL DEFAULT '120',
  `llm_temperature` decimal(5,2) NOT NULL DEFAULT '0.70',
  `llm_top_p` decimal(5,2) NOT NULL DEFAULT '0.90',
  `llm_max_tokens` int(11) NOT NULL DEFAULT '2048',
  `llm_system_prompt` text,
  `description` varchar(500) DEFAULT NULL,
  `is_active` tinyint(1) NOT NULL DEFAULT '1',
  `is_default` tinyint(1) NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`config_id`),
  UNIQUE KEY `uk_llm_model_code` (`model_code`),
  KEY `idx_llm_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS `audio_model_config` (
  `config_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `model_code` varchar(128) NOT NULL,
  `model_name` varchar(255) NOT NULL,
  `audio_scene` varchar(32) NOT NULL,
  `provider` varchar(64) DEFAULT NULL,
  `endpoint_url` varchar(512) DEFAULT NULL,
  `api_key` varchar(512) DEFAULT NULL,
  `asr_model_name` varchar(128) DEFAULT NULL,
  `asr_vocabulary_id` varchar(255) DEFAULT NULL,
  `hot_word_group_id` int(11) DEFAULT NULL COMMENT '关联热词组ID',
  `extra_config` json DEFAULT NULL COMMENT '音频模型差异化配置(JSON)',
  `asr_speaker_count` int(11) DEFAULT NULL,
  `asr_language_hints` varchar(255) DEFAULT NULL,
  `asr_disfluency_removal_enabled` tinyint(1) DEFAULT NULL,
  `asr_diarization_enabled` tinyint(1) DEFAULT NULL,
  `vp_template_text` text,
  `vp_duration_seconds` int(11) DEFAULT NULL,
  `vp_sample_rate` int(11) DEFAULT NULL,
  `vp_channels` int(11) DEFAULT NULL,
  `vp_max_size_bytes` bigint(20) DEFAULT NULL,
  `description` varchar(500) DEFAULT NULL,
  `is_active` tinyint(1) NOT NULL DEFAULT '1',
  `is_default` tinyint(1) NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`config_id`),
  UNIQUE KEY `uk_audio_model_code` (`model_code`),
  KEY `idx_audio_scene` (`audio_scene`),
  KEY `idx_audio_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS `hot_word_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '热词组名称',
  `description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述',
  `vocabulary_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '阿里云 DashScope 词表ID',
  `last_sync_time` datetime DEFAULT NULL COMMENT '最后同步时间',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1:启用 0:停用',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='热词组主表';

CREATE TABLE IF NOT EXISTS `hot_word_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL COMMENT '热词组ID',
  `text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '热词内容',
  `weight` int(11) NOT NULL DEFAULT '4' COMMENT '权重 1-10',
  `lang` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'zh' COMMENT 'zh/en',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1:启用 0:停用',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_group_text` (`group_id`,`text`),
  KEY `idx_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='热词条目从表';

CREATE TABLE IF NOT EXISTS `prompt_config` (
  `config_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `task_type` enum('MEETING_TASK','KNOWLEDGE_TASK') NOT NULL,
  `prompt_id` int(11) NOT NULL,
  `is_enabled` tinyint(1) NOT NULL DEFAULT '1',
  `sort_order` int(11) NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`config_id`),
  UNIQUE KEY `uk_user_task_prompt` (`user_id`,`task_type`,`prompt_id`),
  KEY `idx_user_task_order` (`user_id`,`task_type`,`sort_order`),
  KEY `idx_prompt_id` (`prompt_id`),
  CONSTRAINT `fk_upc_prompt` FOREIGN KEY (`prompt_id`) REFERENCES `prompts` (`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_upc_user` FOREIGN KEY (`user_id`) REFERENCES `sys_users` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS `sys_user_mcp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `bot_id` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
  `bot_secret` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1',
  `last_used_at` datetime DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_sys_user_mcp_user_id` (`user_id`),
  UNIQUE KEY `uk_sys_user_mcp_bot_id` (`bot_id`),
  KEY `idx_sys_user_mcp_status` (`status`),
  CONSTRAINT `fk_sys_user_mcp_user` FOREIGN KEY (`user_id`) REFERENCES `sys_users` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户MCP接入凭证';

-- ----------------------------------------------------------------------
-- 4. Migrate legacy system config data into new parameter/model tables
-- ----------------------------------------------------------------------
INSERT INTO `sys_system_parameters`
(`param_key`, `param_name`, `param_value`, `value_type`, `category`, `description`, `is_active`)
SELECT
  CASE
    WHEN d.`dict_code` = 'timeline_pagesize' THEN 'page_size'
    WHEN d.`dict_code` = 'branding_app_name' THEN 'app_name'
    WHEN d.`dict_code` = 'branding_console_subtitle' THEN 'console_subtitle'
    WHEN d.`dict_code` = 'branding_preview_title' THEN 'preview_title'
    WHEN d.`dict_code` = 'branding_login_welcome' THEN 'login_welcome'
    WHEN d.`dict_code` = 'branding_footer_text' THEN 'footer_text'
    ELSE d.`dict_code`
  END,
  d.`label_cn`,
  JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.value')),
  'string',
  CASE
    WHEN d.`dict_code` IN (
      'timeline_pagesize',
      'page_size',
      'branding_app_name',
      'app_name',
      'branding_console_subtitle',
      'console_subtitle',
      'branding_preview_title',
      'preview_title',
      'branding_login_welcome',
      'login_welcome',
      'branding_footer_text',
      'footer_text',
      'max_audio_size',
      'max_image_size'
    ) THEN 'public'
    ELSE 'system'
  END,
  CONCAT('migrated from dict_data.system_config(', d.`dict_code`, ')'),
  CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END
FROM `sys_dict_data` d
WHERE d.`dict_type` = 'system_config'
  AND d.`dict_code` NOT IN ('llm_model', 'voiceprint')
  AND JSON_EXTRACT(d.`extension_attr`, '$.value') IS NOT NULL
ON DUPLICATE KEY UPDATE
  `param_name` = VALUES(`param_name`),
  `param_value` = VALUES(`param_value`),
  `category` = VALUES(`category`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`);

INSERT INTO `ai_model_configs`
(`model_code`, `model_name`, `model_type`, `provider`, `endpoint_url`, `api_key`,
 `llm_model_name`, `llm_timeout`, `llm_temperature`, `llm_top_p`, `llm_max_tokens`, `llm_system_prompt`,
 `config_json`, `description`, `is_active`, `is_default`)
SELECT
  'llm_model',
  '默认文本模型',
  'llm',
  'dashscope',
  'https://dashscope.aliyuncs.com/compatible-mode/v1',
  NULL,
  COALESCE(JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.model_name')), 'qwen-plus'),
  COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.time_out')) AS UNSIGNED), 120),
  COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.temperature')) AS DECIMAL(5,2)), 0.70),
  COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.top_p')) AS DECIMAL(5,2)), 0.90),
  COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.max_tokens')) AS UNSIGNED), 2048),
  JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.system_prompt')),
  d.`extension_attr`,
  'migrated from dict_data.system_config.llm_model',
  CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END,
  1
FROM `sys_dict_data` d
WHERE d.`dict_type` = 'system_config'
  AND d.`dict_code` = 'llm_model'
LIMIT 1
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `llm_model_name` = VALUES(`llm_model_name`),
  `llm_timeout` = VALUES(`llm_timeout`),
  `llm_temperature` = VALUES(`llm_temperature`),
  `llm_top_p` = VALUES(`llm_top_p`),
  `llm_max_tokens` = VALUES(`llm_max_tokens`),
  `llm_system_prompt` = VALUES(`llm_system_prompt`),
  `config_json` = VALUES(`config_json`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

INSERT INTO `ai_model_configs`
(`model_code`, `model_name`, `model_type`, `provider`, `endpoint_url`, `api_key`,
 `asr_model_name`, `asr_vocabulary_id`, `asr_speaker_count`, `asr_language_hints`,
 `asr_disfluency_removal_enabled`, `asr_diarization_enabled`,
 `config_json`, `description`, `is_active`, `is_default`)
SELECT
  'audio_model',
  '默认音频识别模型',
  'audio',
  'dashscope',
  'https://dashscope.aliyuncs.com/api/v1/services/audio/asr/transcription',
  NULL,
  'paraformer-v2',
  (
    SELECT JSON_UNQUOTE(JSON_EXTRACT(d2.`extension_attr`, '$.value'))
    FROM `sys_dict_data` d2
    WHERE d2.`dict_type` = 'system_config' AND d2.`dict_code` = 'asr_vocabulary_id'
    LIMIT 1
  ),
  10,
  'zh, en',
  1,
  1,
  JSON_OBJECT(
    'model', 'paraformer-v2',
    'vocabulary_id', (
      SELECT JSON_UNQUOTE(JSON_EXTRACT(d3.`extension_attr`, '$.value'))
      FROM `sys_dict_data` d3
      WHERE d3.`dict_type` = 'system_config' AND d3.`dict_code` = 'asr_vocabulary_id'
      LIMIT 1
    ),
    'speaker_count', 10,
    'language_hints', 'zh, en',
    'disfluency_removal_enabled', TRUE,
    'diarization_enabled', TRUE
  ),
  'migrated default ASR config',
  1,
  1
FROM DUAL
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `asr_model_name` = VALUES(`asr_model_name`),
  `asr_vocabulary_id` = VALUES(`asr_vocabulary_id`),
  `asr_speaker_count` = VALUES(`asr_speaker_count`),
  `asr_language_hints` = VALUES(`asr_language_hints`),
  `asr_disfluency_removal_enabled` = VALUES(`asr_disfluency_removal_enabled`),
  `asr_diarization_enabled` = VALUES(`asr_diarization_enabled`),
  `config_json` = VALUES(`config_json`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

INSERT INTO `ai_model_configs`
(`model_code`, `model_name`, `model_type`, `provider`, `endpoint_url`, `api_key`,
 `config_json`, `description`, `is_active`, `is_default`)
SELECT
  'voiceprint_model',
  '默认声纹模型',
  'audio',
  'funasr',
  'http://127.0.0.1:10095',
  NULL,
  d.`extension_attr`,
  'migrated from dict_data.system_config.voiceprint',
  CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END,
  0
FROM `sys_dict_data` d
WHERE d.`dict_type` = 'system_config'
  AND d.`dict_code` = 'voiceprint'
LIMIT 1
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `config_json` = VALUES(`config_json`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

INSERT INTO `llm_model_config`
(`model_code`, `model_name`, `provider`, `endpoint_url`, `api_key`, `llm_model_name`, `llm_timeout`,
 `llm_temperature`, `llm_top_p`, `llm_max_tokens`, `llm_system_prompt`, `description`, `is_active`, `is_default`)
SELECT
  `model_code`,
  `model_name`,
  `provider`,
  `endpoint_url`,
  `api_key`,
  COALESCE(`llm_model_name`, JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.model_name')), 'qwen-plus'),
  COALESCE(`llm_timeout`, CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.time_out')) AS UNSIGNED), 120),
  COALESCE(`llm_temperature`, CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.temperature')) AS DECIMAL(5,2)), 0.70),
  COALESCE(`llm_top_p`, CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.top_p')) AS DECIMAL(5,2)), 0.90),
  COALESCE(`llm_max_tokens`, CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.max_tokens')) AS UNSIGNED), 2048),
  COALESCE(`llm_system_prompt`, JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.system_prompt'))),
  `description`,
  `is_active`,
  `is_default`
FROM `ai_model_configs`
WHERE `model_type` = 'llm'
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `api_key` = VALUES(`api_key`),
  `llm_model_name` = VALUES(`llm_model_name`),
  `llm_timeout` = VALUES(`llm_timeout`),
  `llm_temperature` = VALUES(`llm_temperature`),
  `llm_top_p` = VALUES(`llm_top_p`),
  `llm_max_tokens` = VALUES(`llm_max_tokens`),
  `llm_system_prompt` = VALUES(`llm_system_prompt`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

INSERT INTO `audio_model_config`
(`model_code`, `model_name`, `audio_scene`, `provider`, `endpoint_url`, `api_key`, `asr_model_name`, `asr_vocabulary_id`,
 `asr_speaker_count`, `asr_language_hints`, `asr_disfluency_removal_enabled`, `asr_diarization_enabled`,
 `description`, `is_active`, `is_default`)
SELECT
  `model_code`,
  `model_name`,
  'asr',
  `provider`,
  `endpoint_url`,
  `api_key`,
  COALESCE(`asr_model_name`, JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.model')), 'paraformer-v2'),
  COALESCE(`asr_vocabulary_id`, JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.vocabulary_id'))),
  COALESCE(`asr_speaker_count`, CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.speaker_count')) AS UNSIGNED), 10),
  COALESCE(`asr_language_hints`, 'zh, en'),
  COALESCE(`asr_disfluency_removal_enabled`, 1),
  COALESCE(`asr_diarization_enabled`, 1),
  `description`,
  `is_active`,
  `is_default`
FROM `ai_model_configs`
WHERE `model_code` = 'audio_model'
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `api_key` = VALUES(`api_key`),
  `asr_model_name` = VALUES(`asr_model_name`),
  `asr_vocabulary_id` = VALUES(`asr_vocabulary_id`),
  `asr_speaker_count` = VALUES(`asr_speaker_count`),
  `asr_language_hints` = VALUES(`asr_language_hints`),
  `asr_disfluency_removal_enabled` = VALUES(`asr_disfluency_removal_enabled`),
  `asr_diarization_enabled` = VALUES(`asr_diarization_enabled`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

INSERT INTO `audio_model_config`
(`model_code`, `model_name`, `audio_scene`, `provider`, `endpoint_url`, `api_key`,
 `vp_template_text`, `vp_duration_seconds`, `vp_sample_rate`, `vp_channels`, `vp_max_size_bytes`,
 `description`, `is_active`, `is_default`)
SELECT
  `model_code`,
  `model_name`,
  'voiceprint',
  `provider`,
  `endpoint_url`,
  `api_key`,
  JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.template_text')),
  CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.duration_seconds')) AS UNSIGNED),
  CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.sample_rate')) AS UNSIGNED),
  CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.channels')) AS UNSIGNED),
  CAST(JSON_UNQUOTE(JSON_EXTRACT(`config_json`, '$.voiceprint_max_size')) AS UNSIGNED),
  `description`,
  `is_active`,
  `is_default`
FROM `ai_model_configs`
WHERE `model_code` = 'voiceprint_model'
ON DUPLICATE KEY UPDATE
  `model_name` = VALUES(`model_name`),
  `provider` = VALUES(`provider`),
  `endpoint_url` = VALUES(`endpoint_url`),
  `api_key` = VALUES(`api_key`),
  `vp_template_text` = VALUES(`vp_template_text`),
  `vp_duration_seconds` = VALUES(`vp_duration_seconds`),
  `vp_sample_rate` = VALUES(`vp_sample_rate`),
  `vp_channels` = VALUES(`vp_channels`),
  `vp_max_size_bytes` = VALUES(`vp_max_size_bytes`),
  `description` = VALUES(`description`),
  `is_active` = VALUES(`is_active`),
  `is_default` = VALUES(`is_default`);

-- Backfill extra_config JSON for audio model configs
UPDATE `audio_model_config`
SET `extra_config` = CASE
  WHEN `audio_scene` = 'asr' THEN JSON_OBJECT(
    'model', `asr_model_name`,
    'vocabulary_id', `asr_vocabulary_id`,
    'speaker_count', `asr_speaker_count`,
    'language_hints', `asr_language_hints`,
    'disfluency_removal_enabled', `asr_disfluency_removal_enabled`,
    'diarization_enabled', `asr_diarization_enabled`
  )
  WHEN `audio_scene` = 'voiceprint' THEN JSON_OBJECT(
    'model', `model_name`,
    'template_text', `vp_template_text`,
    'duration_seconds', `vp_duration_seconds`,
    'sample_rate', `vp_sample_rate`,
    'channels', `vp_channels`,
    'max_size_bytes', `vp_max_size_bytes`
  )
  ELSE JSON_OBJECT()
END
WHERE `extra_config` IS NULL;

-- ----------------------------------------------------------------------
-- 5. Hot-word migration: old hot_words -> group/item
-- ----------------------------------------------------------------------
INSERT INTO `hot_word_group` (`name`, `description`, `status`)
SELECT '默认热词组', '从旧 hot_words 表迁移的热词', 1
FROM DUAL
WHERE EXISTS (SELECT 1 FROM `hot_words` LIMIT 1)
  AND NOT EXISTS (SELECT 1 FROM `hot_word_group` WHERE `name` = '默认热词组');

UPDATE `hot_word_group` g
JOIN (
  SELECT JSON_UNQUOTE(JSON_EXTRACT(`extension_attr`, '$.value')) AS vocab_id
  FROM `sys_dict_data`
  WHERE `dict_type` = 'system_config' AND `dict_code` = 'asr_vocabulary_id'
  LIMIT 1
) p ON 1 = 1
SET g.`vocabulary_id` = p.`vocab_id`,
    g.`last_sync_time` = COALESCE(g.`last_sync_time`, NOW())
WHERE g.`name` = '默认热词组'
  AND (g.`vocabulary_id` IS NULL OR g.`vocabulary_id` = '');

INSERT INTO `hot_word_item`
(`group_id`, `text`, `weight`, `lang`, `status`, `create_time`, `update_time`)
SELECT
  g.`id`,
  hw.`text`,
  hw.`weight`,
  hw.`lang`,
  hw.`status`,
  hw.`create_time`,
  hw.`update_time`
FROM `hot_words` hw
JOIN `hot_word_group` g ON g.`name` = '默认热词组'
LEFT JOIN `hot_word_item` i
  ON i.`group_id` = g.`id`
 AND i.`text` = hw.`text`
WHERE i.`id` IS NULL;

UPDATE `audio_model_config` a
JOIN `hot_word_group` g ON g.`name` = '默认热词组'
SET a.`hot_word_group_id` = g.`id`
WHERE a.`audio_scene` = 'asr'
  AND a.`hot_word_group_id` IS NULL
  AND a.`asr_vocabulary_id` IS NOT NULL
  AND a.`asr_vocabulary_id` <> '';

-- ----------------------------------------------------------------------
-- 6. Rebuild menu tree for the latest backend
-- ----------------------------------------------------------------------
-- Reuse legacy root rows when possible
SET @has_dashboard := (SELECT COUNT(*) FROM `sys_menus` WHERE `menu_code` = 'dashboard');
UPDATE `sys_menus`
SET
  `menu_code` = 'dashboard',
  `menu_name` = 'Dashboard',
  `menu_icon` = 'DashboardOutlined',
  `menu_url` = '/dashboard',
  `menu_type` = 'link',
  `parent_id` = NULL,
  `sort_order` = 1,
  `is_active` = 1,
  `is_visible` = 1,
  `description` = '管理员桌面'
WHERE `menu_code` = 'account_settings'
  AND @has_dashboard = 0;

SET @has_desktop := (SELECT COUNT(*) FROM `sys_menus` WHERE `menu_code` = 'desktop');
UPDATE `sys_menus`
SET
  `menu_code` = 'desktop',
  `menu_name` = 'Desktop',
  `menu_icon` = 'DesktopOutlined',
  `menu_url` = '/dashboard',
  `menu_type` = 'link',
  `parent_id` = NULL,
  `sort_order` = 2,
  `is_active` = 1,
  `is_visible` = 1,
  `description` = '普通用户桌面'
WHERE `menu_code` = 'logout'
  AND @has_desktop = 0;

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
VALUES
('dashboard', 'Dashboard', 'DashboardOutlined', '/dashboard', 'link', NULL, 1, NULL, 1, 1, 1, '管理员桌面')
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
VALUES
('desktop', 'Desktop', 'DesktopOutlined', '/dashboard', 'link', NULL, 1, NULL, 2, 1, 1, '普通用户桌面')
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
VALUES
('platform_admin', '平台管理', 'Shield', '/admin/management/hot-word-management', 'link', NULL, 1, NULL, 3, 1, 1, '平台管理员后台'),
('system_management', '系统管理', 'Setting', '/admin/management/user-management', 'link', NULL, 1, NULL, 4, 1, 1, '系统基础配置管理（用户、权限、字典、参数）'),
('meeting_manage', '会议管理', 'CalendarOutlined', '/meetings/center', 'link', NULL, 1, NULL, 2, 1, 1, '普通用户会议菜单')
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'prompt_management', '提示词库', 'BookText', '/prompt-management', 'link',
  p.`menu_id`, 2, NULL, 3, 1, 1, '管理AI提示词模版'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'hot_word_management', '热词管理', 'Text', '/admin/management/hot-word-management', 'link',
  p.`menu_id`, 2, NULL, 1, 1, 1, 'ASR 热词与同步'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'model_management', '模型管理', 'Appstore', '/admin/management/model-management', 'link',
  p.`menu_id`, 2, NULL, 2, 1, 1, '音频/LLM模型配置管理'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'client_management', '客户端管理', 'Smartphone', '/admin/management/client-management', 'link',
  p.`menu_id`, 2, NULL, 5, 1, 1, '版本、下载地址、发布状态'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'external_app_management', '外部应用管理', 'AppWindow', '/admin/management/external-app-management', 'link',
  p.`menu_id`, 2, NULL, 6, 1, 1, '外部系统入口与图标配置'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'terminal_management', '终端管理', 'Monitor', '/admin/management/terminal-management', 'link',
  p.`menu_id`, 2, NULL, 7, 1, 1, '专用设备、激活和绑定状态'
FROM `sys_menus` p
WHERE p.`menu_code` = 'platform_admin'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'user_management', '用户管理', 'Users', '/admin/management/user-management', 'link',
  p.`menu_id`, 2, NULL, 1, 1, 1, '账号、角色、密码重置'
FROM `sys_menus` p
WHERE p.`menu_code` = 'system_management'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'permission_management', '权限管理', 'KeyRound', '/admin/management/permission-management', 'link',
  p.`menu_id`, 2, NULL, 2, 1, 1, '菜单与角色授权矩阵'
FROM `sys_menus` p
WHERE p.`menu_code` = 'system_management'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'dict_management', '字典管理', 'BookMarked', '/admin/management/dict-management', 'link',
  p.`menu_id`, 2, NULL, 3, 1, 1, '码表、平台类型、扩展属性'
FROM `sys_menus` p
WHERE p.`menu_code` = 'system_management'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'parameter_management', '参数管理', 'Setting', '/admin/management/parameter-management', 'link',
  p.`menu_id`, 2, NULL, 8, 1, 1, '系统参数管理'
FROM `sys_menus` p
WHERE p.`menu_code` = 'system_management'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'permission_menu_tree', '菜单树维护', 'AppstoreAdd', '/admin/management/permission-management', 'link',
  p.`menu_id`, 3, NULL, 20, 1, 0, '权限管理中的菜单树维护入口（隐藏于侧栏）'
FROM `sys_menus` p
WHERE p.`menu_code` = 'permission_management'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'meeting_center', '会议中心', 'CalendarOutlined', '/meetings/center', 'link',
  p.`menu_id`, 2, NULL, 1, 1, 1, '普通用户会议中心'
FROM `sys_menus` p
WHERE p.`menu_code` = 'meeting_manage'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'prompt_config', '提示词配置', 'Book', '/prompt-config', 'link',
  p.`menu_id`, 2, NULL, 2, 1, 1, '用户可配置启用提示词与排序'
FROM `sys_menus` p
WHERE p.`menu_code` = 'meeting_manage'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

INSERT INTO `sys_menus`
(`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `menu_level`, `tree_path`, `sort_order`, `is_active`, `is_visible`, `description`)
SELECT
  'personal_prompt_library', '个人提示词仓库', 'ReadOutlined', '/personal-prompts', 'link',
  p.`menu_id`, 2, NULL, 3, 0, 1, '普通用户个人提示词仓库'
FROM `sys_menus` p
WHERE p.`menu_code` = 'meeting_manage'
ON DUPLICATE KEY UPDATE
  `menu_name` = VALUES(`menu_name`),
  `menu_icon` = VALUES(`menu_icon`),
  `menu_url` = VALUES(`menu_url`),
  `menu_type` = VALUES(`menu_type`),
  `parent_id` = VALUES(`parent_id`),
  `sort_order` = VALUES(`sort_order`),
  `is_active` = VALUES(`is_active`),
  `is_visible` = VALUES(`is_visible`),
  `description` = VALUES(`description`);

-- Menu tree metadata (supports current depth 3)
UPDATE `sys_menus`
SET `menu_level` = 1,
    `tree_path` = CONCAT('/', `menu_id`)
WHERE `parent_id` IS NULL;

UPDATE `sys_menus` c
JOIN `sys_menus` p ON c.`parent_id` = p.`menu_id`
SET c.`menu_level` = p.`menu_level` + 1,
    c.`tree_path` = CONCAT(p.`tree_path`, '/', c.`menu_id`);

UPDATE `sys_menus` c
JOIN `sys_menus` p ON c.`parent_id` = p.`menu_id`
SET c.`menu_level` = p.`menu_level` + 1,
    c.`tree_path` = CONCAT(p.`tree_path`, '/', c.`menu_id`);

-- ----------------------------------------------------------------------
-- 7. Align role-menu permissions for latest menu model
-- ----------------------------------------------------------------------
-- Keep existing role-menu permissions unchanged.
-- The upgrade must preserve current grants instead of rebuilding defaults,
-- so repeated execution will not auto-complete or reset menu permissions.

-- ----------------------------------------------------------------------
-- 8. Recreate compatibility views
-- ----------------------------------------------------------------------
DROP VIEW IF EXISTS `users`;
DROP VIEW IF EXISTS `roles`;
DROP VIEW IF EXISTS `menus`;
DROP VIEW IF EXISTS `role_menu_permissions`;
DROP VIEW IF EXISTS `dict_data`;
DROP VIEW IF EXISTS `system_parameters`;

CREATE VIEW `users` AS SELECT * FROM `sys_users`;
CREATE VIEW `roles` AS SELECT * FROM `sys_roles`;
CREATE VIEW `menus` AS SELECT * FROM `sys_menus`;
CREATE VIEW `role_menu_permissions` AS SELECT * FROM `sys_role_menu_permissions`;
CREATE VIEW `dict_data` AS SELECT * FROM `sys_dict_data`;
CREATE VIEW `system_parameters` AS SELECT * FROM `sys_system_parameters`;
