'use strict';

/**
 * Contract: key revoke
 *
 * Revoke (comment out) API key dari file .env. Mendukung interactive selection
 * (default jika --file tidak di-specify) atau langsung target file via `--file`.
 * Flag `--yes` bypass prompt konfirmasi.
 *
 * Inline migration v4.0.0: business logic asli dari `keyrevoke.js`
 * di-inline langsung ke handler. Adapter `process.argv` override dihapus.
 * `process.exit()` di legacy dikonversi menjadi early return (untuk kondisi
 * normal seperti "cancelled") atau `throw new Error(...)` (untuk error).
 */

const path = require('node:path');
const readline = require('node:readline');
const { findEnvFiles, getEnvValue, removeEnvKey, backupEnvFile } = require('../../lib/utils/env-manager');
const { maskApiKey } = require('../../lib/utils/key-generator');
const { validatePathWithinBase } = require('../../lib/utils/path-validator');

function createReadlineInterface() {
    return readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
}

function askQuestion(rl, question) {
    return new Promise((resolve) => {
        rl.question(question, (answer) => {
            resolve(answer.trim().toLowerCase());
        });
    });
}

async function selectFileInteractive(envFiles, baseDir) {
    const filesWithKey = [];

    for (const filePath of envFiles) {
        const key = getEnvValue(filePath, 'KEY');
        if (key) {
            const relativePath = path.relative(baseDir, filePath);
            filesWithKey.push({
                path: filePath,
                relativePath: relativePath,
                key: key
            });
        }
    }

    if (filesWithKey.length === 0) {
        console.log('No API keys found in project.');
        console.log('');
        console.log('Nothing to revoke.');
        console.log('');
        return null;
    }

    console.log('Select .env file to revoke API key:');
    console.log('');

    for (let i = 0; i < filesWithKey.length; i++) {
        const item = filesWithKey[i];
        console.log(`  ${i + 1}. ${item.relativePath}`);
        console.log(`     Key: ${maskApiKey(item.key)}`);
        console.log('');
    }

    const rl = createReadlineInterface();

    try {
        const answer = await askQuestion(rl, `Choose (1-${filesWithKey.length}), or 'cancel' to abort: `);

        if (answer === 'cancel' || answer === 'c' || answer === 'q') {
            console.log('');
            console.log('Operation cancelled.');
            console.log('');
            return null;
        }

        const choice = parseInt(answer, 10);

        if (isNaN(choice) || choice < 1 || choice > filesWithKey.length) {
            console.log('');
            console.log(`Error: Invalid choice. Must be 1-${filesWithKey.length}`);
            console.log('');
            return null;
        }

        return filesWithKey[choice - 1];
    } finally {
        rl.close();
    }
}

async function confirmRevoke(file, autoConfirm) {
    if (autoConfirm) {
        return true;
    }

    console.log('');
    console.log('⚠ WARNING: This will disable API authentication!');
    console.log('');
    console.log(`File: ${file.relativePath}`);
    console.log(`Key:  ${maskApiKey(file.key)}`);
    console.log('');
    console.log('After revoke:');
    console.log('  - Server will run in public mode (no authentication)');
    console.log('  - All API endpoints will be publicly accessible');
    console.log('  - You can regenerate key with: npx restforge key generate');
    console.log('');

    const rl = createReadlineInterface();

    try {
        const answer = await askQuestion(rl, 'Are you sure you want to revoke this key? (yes/no): ');
        return answer === 'yes' || answer === 'y';
    } finally {
        rl.close();
    }
}

module.exports = {
    resource: 'key',
    verb: 'revoke',
    description: 'Revoke (cabut) API key dari file .env',
    category: 'management',
    flags: {
        file: {
            type: 'string',
            required: false,
            default: null,
            description: 'Path file .env yang berisi key untuk di-revoke (default: prompt interaktif)'
        },
        yes: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Lewati prompt konfirmasi'
        }
    },
    examples: [
        'npx restforge key revoke',
        'npx restforge key revoke --file=.env --yes'
    ],
    async handler(args) {
        const baseDir = process.cwd();
        const autoConfirm = args.yes === true;

        console.log('');
        console.log('RestForge API Key Revoke');
        console.log('========================');
        console.log('');

        let selectedFile = null;

        if (args.file) {
            const filePath = validatePathWithinBase(args.file, baseDir);
            const relativePath = path.relative(baseDir, filePath);

            const key = getEnvValue(filePath, 'KEY');

            if (!key) {
                console.error(`Error: No KEY found in ${relativePath}`);
                console.error('');
                console.error('Nothing to revoke.');
                console.error('');
                throw new Error(`No KEY found in ${relativePath}`);
            }

            selectedFile = {
                path: filePath,
                relativePath: relativePath,
                key: key
            };
        } else {
            const envFiles = findEnvFiles(baseDir);

            if (envFiles.length === 0) {
                console.log('No .env files found in project.');
                console.log('');
                return;
            }

            selectedFile = await selectFileInteractive(envFiles, baseDir);

            if (!selectedFile) return;
        }

        const confirmed = await confirmRevoke(selectedFile, autoConfirm);

        if (!confirmed) {
            console.log('');
            console.log('Operation cancelled.');
            console.log('');
            return;
        }

        console.log('');
        console.log('Revoking API key...');

        let backupPath = null;
        try {
            backupPath = backupEnvFile(selectedFile.path);
            const backupRelative = path.relative(baseDir, backupPath);
            console.log(`✓ Backup created: ${backupRelative}`);
        } catch (err) {
            console.error(`⚠ Warning: Failed to create backup: ${err.message}`);
        }

        try {
            removeEnvKey(selectedFile.path, 'KEY', true);
        } catch (err) {
            console.error('');
            console.error(`Error: Failed to revoke key: ${err.message}`);
            console.error('');
            throw new Error(`Failed to revoke key: ${err.message}`);
        }

        console.log(`✓ API Key revoked in ${selectedFile.relativePath}`);
        console.log('');
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        console.log('');
        console.log('✓ API Key has been revoked');
        console.log('');
        if (backupPath) {
            console.log(`Backup saved to: ${path.relative(baseDir, backupPath)}`);
        }
        console.log('');
        console.log('The KEY line has been commented out in the .env file.');
        console.log('You can undo by editing the file manually.');
        console.log('');
        console.log('⚠ IMPORTANT:');
        console.log('');
        console.log('  - Server will now run in PUBLIC MODE (no authentication)');
        console.log('  - All API endpoints are publicly accessible');
        console.log('  - Restart server for changes to take effect');
        console.log('');
        console.log('Next Steps:');
        console.log('');
        console.log('  1. To generate new key:');
        console.log(`     npx restforge key generate --output=${selectedFile.relativePath}`);
        console.log('');
        console.log('  2. To restore from backup:');
        if (backupPath) {
            console.log(`     cp ${path.relative(baseDir, backupPath)} ${selectedFile.relativePath}`);
        }
        console.log('');
        console.log('  3. List remaining keys:');
        console.log('     npx restforge key list');
        console.log('');
    }
};
