#!/usr/bin/env node

/**
 * Generate migration by comparing entity definitions with database schema
 *
 * This script uses TypeORM to automatically detect schema changes
 *
 * Usage:
 *   pnpm migration:generate <version> <description>
 *
 * Example:
 *   pnpm migration:generate 25.0.1 add-extension-identifier
 *
 * Prerequisites:
 *   1. Database must be running
 *   2. Entity changes must be defined in src/entities
 *   3. Database connection configured in .env
 */

import { execSync } from "child_process";
import fs from "fs-extra";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Get arguments
const args = process.argv.slice(2);
const version = args[0];
const description = args[1];

// Validate arguments
if (!version || !description) {
    console.error("❌ Error: Missing required arguments");
    console.log("");
    console.log("Usage:");
    console.log("  pnpm migration:generate <version> <description>");
    console.log("");
    console.log("Example:");
    console.log("  pnpm migration:generate 25.0.1 add-extension-identifier");
    console.log("");
    console.log("This will:");
    console.log("  1. Compare your entity definitions with current database schema");
    console.log("  2. Generate migration SQL automatically");
    console.log("  3. Create a timestamped migration file");
    process.exit(1);
}

// Validate version format (semver)
const semverRegex = /^\d+\.\d+\.\d+$/;
if (!semverRegex.test(version)) {
    console.error("❌ Error: Invalid version format. Must be semver (e.g., 25.0.1)");
    process.exit(1);
}

// Validate description (kebab-case)
const descriptionRegex = /^[a-z0-9]+(-[a-z0-9]+)*$/;
if (!descriptionRegex.test(description)) {
    console.error("❌ Error: Invalid description format. Must be kebab-case (e.g., add-new-field)");
    process.exit(1);
}

console.log("🔍 Analyzing database schema changes...");
console.log("");

// Generate timestamp
const timestamp = Date.now();

// Migrations directory
const migrationsDir = path.join(__dirname, "../src/migrations");
await fs.ensureDir(migrationsDir);

try {
    // Run TypeORM migration:generate
    // Only use description as the name to avoid class name starting with number
    const command = `npx typeorm-ts-node-commonjs migration:generate ./src/migrations/${description} -d ./src/datasources/data-source.ts`;

    console.log("Running TypeORM schema comparison...");
    execSync(command, {
        cwd: path.join(__dirname, ".."),
        stdio: "inherit",
    });

    // Find the generated file (TypeORM adds timestamp prefix)
    const files = await fs.readdir(migrationsDir);
    const generatedFile = files.find(
        (f) => f.includes(description) && f.endsWith(".ts") && f !== ".gitkeep",
    );

    if (!generatedFile) {
        throw new Error("Generated migration file not found");
    }

    const generatedPath = path.join(migrationsDir, generatedFile);
    const finalFilename = `${timestamp}-${version}-${description}.ts`;
    const finalPath = path.join(migrationsDir, finalFilename);

    // Read the generated file
    let content = await fs.readFile(generatedPath, "utf-8");

    // Extract the auto-generated class name (format: DescriptionTimestamp)
    const classNameMatch = content.match(/export class (\w+) implements MigrationInterface/);
    if (!classNameMatch) {
        throw new Error("Could not find class name in generated migration");
    }
    const oldClassName = classNameMatch[1];
    const newClassName = `Migration${timestamp}`;

    content = content.replace(new RegExp(oldClassName, "g"), newClassName);

    // Add version comment
    const versionComment = `/**
 * Migration: ${description}
 * Version: ${version}
 * Generated: ${new Date().toISOString()}
 * 
 * This migration was automatically generated by TypeORM
 * based on entity definition changes.
 */

`;
    content = versionComment + content;

    // Write to final location
    await fs.writeFile(finalPath, content);

    // Remove temporary file if different from final file
    if (generatedPath !== finalPath) {
        await fs.remove(generatedPath);
    }

    console.log("");
    console.log("✅ Migration file generated successfully!");
    console.log("");
    console.log("📄 File:", finalFilename);
    console.log("📁 Path:", finalPath);
    console.log("🔢 Version:", version);
    console.log("📝 Description:", description);
    console.log("");
    console.log("Next steps:");
    console.log("1. Review the generated SQL in the migration file");
    console.log("2. Make any necessary adjustments");
    console.log("3. Build the package: pnpm build");
    console.log("4. Restart the application to run the migration");
} catch (error) {
    console.error("");
    console.error("❌ Migration generation failed");
    console.error("");
    console.error("Common issues:");
    console.error("  1. Database is not running");
    console.error("  2. Database connection failed (check .env)");
    console.error("  3. No schema changes detected");
    console.error("");
    console.error("Error details:", error.message);
    console.error(error);
    process.exit(1);
}
