-- ===========================================================================
-- S0-LINESKILL-TENANT-UK-CLOSURE-1 —— 产线岗位（line-post）
--
-- 本脚本做两件互相独立的事：
--
-- 【1】MULTI-TENANT SCHEMA CORRECTNESS（主要目的）
--     LineSkillMaster / LineSkillDetail 的 UNIQUE 索引缺少 tenant_id：
--        IX_LineSkillMaster : Domain + Site + ProdLine + JOBNo
--        IX_LineSkillDetail : Domain + Site + ProdLine + JOBNo + SkillNo
--     两者都是「跨租户唯一」，一旦 Site 被启用（非 NULL），两个租户持有相同
--     (Domain, Site, ProdLine, JOBNo) 就会互相顶撞。这属于多租户索引缺陷，
--     必须补 tenant_id。
--
--     ⚠️ 这不是为了「让下面 22 行插得进去」。已实测证明：当前 Site 全为 NULL，
--     MySQL 的 UNIQUE 索引不对 NULL 做相等判定，因此即使不改索引，
--     11 master + 11 detail 也能插入成功（事务内实测 11/11 + 11/11，随后回滚）。
--     索引修复的唯一目的是 schema 正确性。
--
-- 【2】line-post 演示数据（22 行）
--     来源 AIDOP 797：仅取 ProdLine 命中目标租户 LineMaster 的 11 条产线；
--     其余 29 条因产线不存在于目标租户而丢弃，不为凑数复制。
--
-- Site 处理：保持 NULL。
--     族级证据显示 Site = 工作组/工作中心类历史列（EmpSkills.Site 注释「工作组」，
--     AIDOPB 实测取值为 数控组/冲压组 等；ProdLineDetail.Site 注释「工作中心编码」），
--     且 LineSkill 全库 296 行 Site 100% 为 NULL、无 UI、无校验。
--     因此新行沿用 NULL —— 不得写入租户/工厂/组织编码。
--
-- ⚠️ 事务性说明：MySQL 的 DDL 会隐式提交，且 AutoVersionUpdate 的
--     SqlScriptSplitter.Execute 不开启显式事务。因此本脚本**不是原子的**。
--     为此所有语句均写成可安全重入：
--       - DDL 以「索引是否已包含 tenant_id」为条件，已修则整段跳过；
--       - 数据以业务键 NOT EXISTS 兜底，重跑影响行数为 0。
-- ===========================================================================

SET @src := (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId WHERE o.Code = 'AIDOP'       AND t.Status = 1 LIMIT 1);
SET @dst := (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId WHERE o.Code = 'UATTEST_CHL' AND t.Status = 1 LIMIT 1);


-- ---------------------------------------------------------------------------
-- 01 · 前置守卫：新 UK 定义下不得存在重复（否则不能建唯一索引）
--      重复则抛错中止，不带病改索引。
-- ---------------------------------------------------------------------------
SET @dup_m := (SELECT COUNT(*) FROM (
    SELECT tenant_id, Domain, Site, ProdLine, JOBNo
    FROM LineSkillMaster GROUP BY tenant_id, Domain, Site, ProdLine, JOBNo HAVING COUNT(*) > 1) x);

SET @dup_d := (SELECT COUNT(*) FROM (
    SELECT tenant_id, Domain, Site, ProdLine, JOBNo, SkillNo
    FROM LineSkillDetail GROUP BY tenant_id, Domain, Site, ProdLine, JOBNo, SkillNo HAVING COUNT(*) > 1) x);

SET @g := IF(@dup_m = 0 AND @dup_d = 0, 'DO 0',
    'SELECT RAISE_LINESKILL_UK_DUPLICATE_FOUND');
PREPARE gstmt FROM @g;
EXECUTE gstmt;
DEALLOCATE PREPARE gstmt;


-- ---------------------------------------------------------------------------
-- 02 · IX_LineSkillMaster → 补 tenant_id
--      条件：该索引存在且**不含** tenant_id 才重建；已含则整段 no-op（可重入）。
-- ---------------------------------------------------------------------------
SET @m_fixed := (SELECT COUNT(*) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillMaster'
      AND INDEX_NAME = 'IX_LineSkillMaster' AND COLUMN_NAME = 'tenant_id');

SET @m_exists := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillMaster'
      AND INDEX_NAME = 'IX_LineSkillMaster');

SET @s := IF(@m_fixed = 0 AND @m_exists > 0,
    'DROP INDEX IX_LineSkillMaster ON LineSkillMaster', 'DO 0');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @m_now := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillMaster'
      AND INDEX_NAME = 'IX_LineSkillMaster');

SET @s := IF(@m_now = 0,
    'CREATE UNIQUE INDEX IX_LineSkillMaster ON LineSkillMaster (tenant_id, Domain, Site, ProdLine, JOBNo)',
    'DO 0');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


-- ---------------------------------------------------------------------------
-- 03 · IX_LineSkillDetail → 补 tenant_id（同样条件化、可重入）
-- ---------------------------------------------------------------------------
SET @d_fixed := (SELECT COUNT(*) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillDetail'
      AND INDEX_NAME = 'IX_LineSkillDetail' AND COLUMN_NAME = 'tenant_id');

SET @d_exists := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillDetail'
      AND INDEX_NAME = 'IX_LineSkillDetail');

SET @s := IF(@d_fixed = 0 AND @d_exists > 0,
    'DROP INDEX IX_LineSkillDetail ON LineSkillDetail', 'DO 0');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @d_now := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'LineSkillDetail'
      AND INDEX_NAME = 'IX_LineSkillDetail');

SET @s := IF(@d_now = 0,
    'CREATE UNIQUE INDEX IX_LineSkillDetail ON LineSkillDetail (tenant_id, Domain, Site, ProdLine, JOBNo, SkillNo)',
    'DO 0');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


-- ---------------------------------------------------------------------------
-- 04 · LineSkillMaster COPY 11
--      只取 ProdLine 命中目标租户 LineMaster 的产线（JOIN 即门禁）；
--      Site 保持 NULL；RecID 为 auto_increment，不赋值、不复制源主键。
-- ---------------------------------------------------------------------------
INSERT INTO LineSkillMaster
    (tenant_id, Domain, Site, ProdLine, JOBNo, JOBDescr, Orderby, WType, RunCrew, CreateTime, UpdateTime)
SELECT @dst, s.Domain, NULL, s.ProdLine, s.JOBNo, s.JOBDescr, s.Orderby, s.WType, s.RunCrew, NOW(), NOW()
FROM LineSkillMaster s
JOIN LineMaster l ON l.tenant_id = @dst AND l.Line = s.ProdLine
WHERE s.tenant_id = @src
  AND @src IS NOT NULL AND @dst IS NOT NULL
  AND NOT EXISTS (
      SELECT 1 FROM LineSkillMaster x
      WHERE x.tenant_id = @dst AND x.Domain = s.Domain
        AND x.ProdLine = s.ProdLine AND x.JOBNo = s.JOBNo AND x.Site IS NULL);


-- ---------------------------------------------------------------------------
-- 05 · LineSkillDetail COPY 11
--      ★ 内部 ID remap（禁止复制源主键 / 源 PersonSkillId）：
--        LineSkillRecID ← 目标租户刚插入的 master RecID（按业务键回查）
--        PersonSkillId  ← 目标租户 PersonSkill.Code = 源 SkillNo 的 Id
--        （源库该列指向的是他租户的 PersonSkill，属源侧既有缺陷，不得沿用）
-- ---------------------------------------------------------------------------
INSERT INTO LineSkillDetail
    (tenant_id, Domain, Site, ProdLine, JOBNo, SkillNo, LineSkillRecID, PersonSkillId,
     required_level, is_enabled, CreateTime, UpdateTime)
SELECT @dst, m.Domain, NULL, m.ProdLine, m.JOBNo, sd.SkillNo, m.RecID, p.Id,
       sd.required_level, 1, NOW(), NOW()
FROM LineSkillMaster m
JOIN LineSkillMaster sm
      ON sm.tenant_id = @src AND sm.Domain = m.Domain
     AND sm.ProdLine = m.ProdLine AND sm.JOBNo = m.JOBNo AND sm.Site IS NULL
JOIN LineSkillDetail sd
      ON sd.tenant_id = @src AND sd.LineSkillRecID = sm.RecID
JOIN PersonSkill p
      ON p.tenant_id = @dst AND p.Code = sd.SkillNo
WHERE m.tenant_id = @dst AND m.Site IS NULL
  AND @src IS NOT NULL AND @dst IS NOT NULL
  AND NOT EXISTS (
      SELECT 1 FROM LineSkillDetail d
      WHERE d.tenant_id = @dst AND d.LineSkillRecID = m.RecID AND d.PersonSkillId = p.Id);
