/**
 * Scaffold a new migration file under `scripts/migrations/`.
 *
 *   Usage: npm run migrate:create -- <snake_case_description>
 *   e.g.:  npm run migrate:create -- add_finance_kyc_column
 *
 * The file is named `<YYYYMMDDHHMMSS>_<description>.ts` (UTC timestamp).
 * Author then edits `up()` to implement the schema change.
 */

import { promises as fs } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const SCRIPTS_DIR = path.dirname(fileURLToPath(import.meta.url));
const MIGRATIONS_DIR = path.join(SCRIPTS_DIR, 'migrations');

function pad(n: number, width = 2): string {
    return String(n).padStart(width, '0');
}

function utcTimestamp(): string {
    const d = new Date();
    return (
        d.getUTCFullYear().toString() +
        pad(d.getUTCMonth() + 1) +
        pad(d.getUTCDate()) +
        pad(d.getUTCHours()) +
        pad(d.getUTCMinutes()) +
        pad(d.getUTCSeconds())
    );
}

function sanitizeName(input: string): string {
    const cleaned = input
        .trim()
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '_')
        .replace(/^_+|_+$/g, '');
    if (!cleaned) {
        throw new Error('Migration name is empty after sanitisation.');
    }
    if (cleaned.length > 80) {
        throw new Error(
            `Migration name "${cleaned}" is too long (${cleaned.length}). Keep it under 80 chars.`
        );
    }
    return cleaned;
}

async function main(): Promise<void> {
    const rawName = process.argv.slice(2).join('_');
    if (!rawName) {
        console.error('Missing migration name.');
        console.error('Usage: npm run migrate:create -- <snake_case_description>');
        process.exit(1);
    }

    const name = sanitizeName(rawName);
    const ts = utcTimestamp();
    const filename = `${ts}_${name}.ts`;
    const target = path.join(MIGRATIONS_DIR, filename);

    const body = `/**
 * Migration: ${name.replace(/_/g, ' ')}
 *
 * Generated at ${new Date().toISOString()}.
 * Implement up() with idempotent DDL where possible.
 */

import type { QueryInterface, Sequelize, Transaction } from 'sequelize';

export interface MigrationContext {
    queryInterface: QueryInterface;
    sequelize: Sequelize;
    transaction: Transaction;
}

const migration = {
    async up({ sequelize, transaction }: MigrationContext): Promise<void> {
        // TODO: implement the schema change.
        // Example:
        // await sequelize.query(\`
        //   ALTER TABLE "applications"
        //   ADD COLUMN IF NOT EXISTS "kycReviewedAt" TIMESTAMPTZ NULL;
        // \`, { transaction });
        throw new Error('Migration ${filename} has no up() implementation yet.');
    }
};

export default migration;
`;

    await fs.mkdir(MIGRATIONS_DIR, { recursive: true });
    await fs.writeFile(target, body, { flag: 'wx' });
    console.log(`Created ${path.relative(process.cwd(), target)}`);
    console.log('Next:');
    console.log('  1. Edit the file and implement up().');
    console.log('  2. Update the matching Sequelize model.');
    console.log('  3. Run: npm run migrate:up');
}

main().catch((err) => {
    console.error('create-migration failed:', err?.message || err);
    process.exit(1);
});
