/**
 * 为已存在的表添加缺失的列（因 drizzle-kit push 阻塞未同步的 schema 变更）
 *
 * 缺失列清单：
 *   - learning_diagnostic_reports.class_id        (v4-P1-4 班级报告关联)
 *   - announcements.is_pinned                     (V2-P2-13d 公告置顶)
 *   - messages.is_starred                         (V2-P2-13c 消息星标)
 *   - message_notifications.priority              (V2-P2-13b 通知优先级)
 *   - message_notifications.is_archived           (V2-P2-13b 通知归档)
 */
require("dotenv/config");
const mysql = require("mysql2/promise");

// 每个 ALTER 操作：[表名, 描述, SQL语句数组]
const ALTER_OPERATIONS = [
  {
    table: "learning_diagnostic_reports",
    description: "添加 class_id 列（班级报告关联）",
    sql: [
      "ALTER TABLE `learning_diagnostic_reports` ADD COLUMN `class_id` varchar(128) NULL AFTER `generated_by`",
      "ALTER TABLE `learning_diagnostic_reports` ADD INDEX `diagnostic_class_idx` (`class_id`)",
      "ALTER TABLE `learning_diagnostic_reports` ADD CONSTRAINT `diagnostic_class_fk` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id`) ON DELETE SET NULL",
    ],
  },
  {
    table: "announcements",
    description: "添加 is_pinned 列（公告置顶）",
    sql: [
      "ALTER TABLE `announcements` ADD COLUMN `is_pinned` boolean NOT NULL DEFAULT false AFTER `published_at`",
      "ALTER TABLE `announcements` ADD INDEX `announcements_status_pinned_idx` (`status`, `is_pinned`)",
    ],
  },
  {
    table: "messages",
    description: "添加 is_starred 列（消息星标）",
    sql: [
      "ALTER TABLE `messages` ADD COLUMN `is_starred` boolean NOT NULL DEFAULT false AFTER `receiver_deleted_at`",
      "ALTER TABLE `messages` ADD INDEX `messages_receiver_starred_idx` (`receiver_id`, `is_starred`)",
    ],
  },
  {
    table: "message_notifications",
    description: "添加 priority 和 is_archived 列（通知优先级与归档）",
    sql: [
      "ALTER TABLE `message_notifications` ADD COLUMN `priority` varchar(16) NOT NULL DEFAULT 'normal' AFTER `is_read`",
      "ALTER TABLE `message_notifications` ADD COLUMN `is_archived` boolean NOT NULL DEFAULT false AFTER `priority`",
      "ALTER TABLE `message_notifications` ADD INDEX `message_notifications_priority_idx` (`priority`)",
      "ALTER TABLE `message_notifications` ADD INDEX `message_notifications_user_archived_idx` (`user_id`, `is_archived`)",
    ],
  },
];

async function columnExists(conn, table, column) {
  const [rows] = await conn.execute(
    `SELECT COLUMN_NAME FROM information_schema.COLUMNS
     WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,
    [table, column],
  );
  return rows.length > 0;
}

async function indexExists(conn, table, indexName) {
  const [rows] = await conn.execute(
    `SELECT INDEX_NAME FROM information_schema.STATISTICS
     WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND INDEX_NAME = ?
     LIMIT 1`,
    [table, indexName],
  );
  return rows.length > 0;
}

async function main() {
  const conn = await mysql.createConnection({ uri: process.env.DATABASE_URL });
  console.log("✅ 已连接数据库\n");

  for (const op of ALTER_OPERATIONS) {
    console.log(`${"=".repeat(60)}`);
    console.log(`表: ${op.table} — ${op.description}`);
    console.log("=".repeat(60));

    for (const sql of op.sql) {
      try {
        // 检查是否已存在（ADD COLUMN / ADD INDEX / ADD CONSTRAINT）
        const isColumn = sql.includes("ADD COLUMN");
        const isIndex = sql.includes("ADD INDEX");
        const isConstraint = sql.includes("ADD CONSTRAINT");

        if (isColumn) {
          const match = sql.match(/ADD COLUMN `(\w+)`/);
          if (match && await columnExists(conn, op.table, match[1])) {
            console.log(`  ⏭️  跳过已存在的列: ${match[1]}`);
            continue;
          }
        } else if (isIndex) {
          const match = sql.match(/ADD INDEX `(\w+)`/);
          if (match && await indexExists(conn, op.table, match[1])) {
            console.log(`  ⏭️  跳过已存在的索引: ${match[1]}`);
            continue;
          }
        }

        await conn.execute(sql);
        console.log(`  ✅ 执行成功: ${sql.slice(0, 100)}...`);
      } catch (err) {
        if (err.code === "ER_DUP_FIELDNAME" || err.code === "ER_DUP_KEYNAME" || err.errno === 1060 || err.errno === 1061) {
          console.log(`  ⏭️  已存在，跳过: ${err.message}`);
        } else {
          console.error(`  ❌ 执行失败: ${err.message}`);
          console.error(`     SQL: ${sql}`);
        }
      }
    }
    console.log("");
  }

  // 验证最终列结构
  console.log(`${"=".repeat(60)}`);
  console.log("最终验证 — 检查缺失列是否已添加");
  console.log("=".repeat(60));

  const checks = [
    ["learning_diagnostic_reports", "class_id"],
    ["announcements", "is_pinned"],
    ["messages", "is_starred"],
    ["message_notifications", "priority"],
    ["message_notifications", "is_archived"],
  ];

  let allOk = true;
  for (const [table, col] of checks) {
    const exists = await columnExists(conn, table, col);
    const status = exists ? "✅" : "❌";
    if (!exists) allOk = false;
    console.log(`  ${status} ${table}.${col}`);
  }

  console.log(allOk ? "\n✅ 所有缺失列已就绪" : "\n❌ 仍有缺失列，请检查错误");

  await conn.end();
  process.exitCode = allOk ? 0 : 1;
}

main().catch((err) => {
  console.error("致命错误:", err);
  process.exit(1);
});
