require("dotenv").config();
const path = require("path");
const fs = require("fs");
const {execSync} = require("child_process");
const connectDB = require("../config/database");
const migrationHelper = require("../utils/migrationHelper");

/**
 * Tự động phát hiện tất cả các file script trong thư mục scripts
 * Loại trừ các file quản lý migration và file không phải .js
 */
function discoverMigrations() {
  const scriptsDir = __dirname;
  const files = fs.readdirSync(scriptsDir);

  // Danh sách các file quản lý migration cần loại trừ
  const excludeFiles = [
    "migrate-all.js",
    "migrate-status.js",
    "migrate-rollback.js",
    "migrate-fresh.js",
    "make-migration.js",
  ];

  const migrations = files
    .filter((file) => {
      // Lấy tất cả file .js, trừ các file quản lý
      return file.endsWith(".js") && !excludeFiles.includes(file);
    })
    .map((file) => {
      // Tạo tên migration từ tên file (bỏ .js)
      const name = file.replace(".js", "");
      return {
        name: name,
        script: file,
      };
    })
    .sort((a, b) => {
      // Sắp xếp theo tên để đảm bảo thứ tự nhất quán
      return a.name.localeCompare(b.name);
    });

  return migrations;
}

// Tự động phát hiện migrations
const migrations = discoverMigrations();

/**
 * Chạy migration script (suppress output)
 * Sử dụng child_process để chạy script độc lập vì các script tự quản lý DB connection
 * Output từ script sẽ bị suppress để chỉ hiển thị status
 */
async function runMigrationScript(migration) {
  return new Promise((resolve, reject) => {
    try {
      // Chạy script bằng child_process với stdio: 'pipe' để suppress output
      // Nhưng vẫn capture stderr để có thể hiển thị lỗi nếu cần
      const result = execSync(`node scripts/${migration.script}`, {
        stdio: ["ignore", "pipe", "pipe"], // stdin: ignore, stdout: pipe, stderr: pipe
        cwd: path.join(__dirname, ".."),
        encoding: "utf8",
      });
      resolve();
    } catch (error) {
      // Attach stderr vào error để có thể hiển thị sau
      if (error.stderr) {
        error.stderr = error.stderr;
      }
      reject(error);
    }
  });
}

/**
 * Hàm chính để chạy tất cả migrations với tracking
 */
async function runAllMigrations() {
  const mongoose = require("mongoose");
  let ownConn = false;
  
  try {
    const wasConnected = mongoose.connection.readyState === 1;
    await connectDB();
    if (!wasConnected) ownConn = true;

    const batch = (await migrationHelper.getLastBatch()) + 1;
    const results = [];

    // Kiểm tra và chạy từng migration
    for (let i = 0; i < migrations.length; i++) {
      const migration = migrations[i];

      try {
        // Kiểm tra xem migration đã chạy chưa
        const hasRun = await migrationHelper.hasRun(migration.name);

        if (hasRun) {
          results.push({name: migration.name, status: "SKIPPED"});
          continue;
        }

        // Chạy migration script (output bị suppress)
        await runMigrationScript(migration);

        if (mongoose.connection.readyState !== 1) {
          await connectDB();
        }
        await migrationHelper.markAsRun(migration.name, batch);

        results.push({name: migration.name, status: "DONE"});
      } catch (error) {
        results.push({
          name: migration.name,
          status: "FAIL",
          error: error.message,
        });
        // Hiển thị bảng kết quả trước khi exit
        displayResults(results);
        console.error(
          `\n❌ Migration "${migration.name}" failed: ${error.message}`
        );
        if (error.stderr) {
          console.error(error.stderr.toString());
        }
        if (ownConn && mongoose.connection.readyState === 1) {
          await mongoose.disconnect();
        }
        process.exit(1);
      }
    }

    // Hiển thị bảng kết quả
    displayResults(results);

    if (ownConn && mongoose.connection.readyState === 1) {
      await mongoose.disconnect();
    }

    process.exit(0);
  } catch (error) {
    console.error("\n❌ Error:", error.message);
    if (ownConn && mongoose.connection.readyState === 1) {
      await mongoose.disconnect();
    }
    process.exit(1);
  }
}

/**
 * Hiển thị bảng kết quả migration đơn giản
 */
function displayResults(results) {
  console.log("\nRunning migrations...\n");

  // Tìm độ dài tên migration dài nhất để format bảng
  const maxNameLength = Math.max(...results.map((r) => r.name.length), 20);
  const statusWidth = 10;
  const totalWidth = maxNameLength + statusWidth + 7; // 7 = spaces and separators

  // Header
  console.log("=".repeat(totalWidth));
  console.log(
    `${"Migration".padEnd(maxNameLength)} | ${"Status".padEnd(statusWidth)}`
  );
  console.log("=".repeat(totalWidth));

  // Rows
  results.forEach((result) => {
    let statusText = "";
    if (result.status === "DONE") {
      statusText = "DONE".padEnd(statusWidth);
    } else if (result.status === "SKIPPED") {
      statusText = "SKIPPED".padEnd(statusWidth);
    } else if (result.status === "FAIL") {
      statusText = "FAIL".padEnd(statusWidth);
    }

    console.log(`${result.name.padEnd(maxNameLength)} | ${statusText}`);
  });

  // Footer
  console.log("=".repeat(totalWidth));

  // Summary
  const doneCount = results.filter((r) => r.status === "DONE").length;
  const skippedCount = results.filter((r) => r.status === "SKIPPED").length;
  const failCount = results.filter((r) => r.status === "FAIL").length;

  console.log("");
  if (doneCount > 0) {
    console.log(`${doneCount} migration(s) completed`);
  }
  if (skippedCount > 0) {
    console.log(`${skippedCount} migration(s) skipped`);
  }
  if (failCount > 0) {
    console.log(`${failCount} migration(s) failed`);
  }
  console.log("");
}

// Chạy hàm chính
runAllMigrations();
