'use strict';

/**
 * Contract: project delete
 *
 * Menghapus project beserta seluruh endpoint, processor, dashboard, dan
 * consumer di dalamnya. Mendukung skip prompt konfirmasi via flag `--yes/-y`.
 *
 * Inline migration v4.0.0: business logic asli dari `drop-module.js`
 * (function `main`) di-inline langsung di handler. Adapter `process.argv`
 * override dihapus karena handler langsung pakai `args.project` dan
 * `args.yes`. `process.exit()` di legacy dikonversi menjadi
 * `throw new Error(...)` agar `cli-entry.js` yang handle exit code.
 */

const fs = require('node:fs');
const path = require('node:path');
const readline = require('node:readline');
const { validateSafeName } = require('../../lib/utils/path-validator');

const isBun = typeof Bun !== 'undefined';

function detectBunCompiled() {
    if (!isBun) return false;

    const hasVirtualFS = process.argv[1] && process.argv[1].includes('$bunfs');
    const execPathLower = process.execPath.toLowerCase();
    const isBunStandardPath = execPathLower.includes('bun') &&
                              (execPathLower.endsWith('bun') || execPathLower.endsWith('bun.exe'));
    const isRestforgeBinary = execPathLower.includes('restforge');

    return hasVirtualFS || isRestforgeBinary || !isBunStandardPath;
}

const isBunCompiled = detectBunCompiled();
const isCompiledBinary = isBunCompiled;
const isScript = !isCompiledBinary;

function getWorkingDirectory() {
    if (isCompiledBinary) {
        const exeDir = path.dirname(process.execPath);
        if (exeDir.includes('node_modules')) {
            return process.cwd();
        }
        return exeDir;
    }
    return process.cwd();
}

function checkIfModuleExists(workingDir, moduleName) {
    const modulePath = path.join(workingDir, 'src', 'modules', `${moduleName}.js`);
    const subModulesDir = path.join(workingDir, 'src', 'modules', moduleName);
    const modelsDir = path.join(workingDir, 'src', 'models', moduleName);

    const moduleExists = fs.existsSync(modulePath);
    const subModulesDirExists = fs.existsSync(subModulesDir);
    const modelsDirExists = fs.existsSync(modelsDir);

    if (process.env.NODE_ENV !== 'production' && isScript) {
        console.log(`Checking paths:`);
        console.log(`- Module file: ${modulePath} (exists: ${moduleExists})`);
        console.log(`- Submodules dir: ${subModulesDir} (exists: ${subModulesDirExists})`);
        console.log(`- Models dir: ${modelsDir} (exists: ${modelsDirExists})`);
    }

    return {
        moduleExists,
        subModulesDirExists,
        modelsDirExists,
        modulePath,
        subModulesDir,
        modelsDir
    };
}

function getSubmodulesList(subModulesDir) {
    if (!fs.existsSync(subModulesDir)) return [];
    try {
        return fs.readdirSync(subModulesDir)
            .filter(file => file.endsWith('.js'))
            .map(file => file.replace('.js', ''));
    } catch (error) {
        console.error(`Error saat membaca daftar submodul: ${error.message}`);
        return [];
    }
}

function getModelsList(modelsDir) {
    if (!fs.existsSync(modelsDir)) return [];
    try {
        return fs.readdirSync(modelsDir)
            .filter(file => file.endsWith('.js'))
            .map(file => file.replace('.js', ''));
    } catch (error) {
        console.error(`Error saat membaca daftar model: ${error.message}`);
        return [];
    }
}

function deleteFileOrDirectory(targetPath) {
    try {
        if (fs.existsSync(targetPath)) {
            if (fs.lstatSync(targetPath).isDirectory()) {
                fs.readdirSync(targetPath).forEach(file => {
                    const currentPath = path.join(targetPath, file);
                    if (fs.lstatSync(currentPath).isDirectory()) {
                        deleteFileOrDirectory(currentPath);
                    } else {
                        fs.unlinkSync(currentPath);
                        console.log(`File ${currentPath} deleted successfully`);
                    }
                });
                fs.rmdirSync(targetPath);
                console.log(`Directory ${targetPath} deleted successfully`);
            } else {
                fs.unlinkSync(targetPath);
                console.log(`File ${targetPath} deleted successfully`);
            }
            return true;
        }
        console.log(`Path ${targetPath} not found, no deletion needed`);
        return false;
    } catch (error) {
        console.error(`Error deleting ${targetPath}: ${error.message}`);
        return false;
    }
}

function showConfirmation(message) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    return new Promise((resolve) => {
        rl.question(message, (answer) => {
            rl.close();
            resolve(answer.toLowerCase());
        });
    });
}

function deleteModuleMetadata(workingDir, moduleName) {
    const metadataPath = path.join(workingDir, 'metadata', `${moduleName}.json`);
    const metadataExists = fs.existsSync(metadataPath);

    if (process.env.NODE_ENV !== 'production' && isScript) {
        console.log(`- Metadata file: ${metadataPath} (exists: ${metadataExists})`);
    }

    if (metadataExists) {
        try {
            fs.unlinkSync(metadataPath);
            console.log(`Metadata ${metadataPath} deleted successfully`);
            return true;
        } catch (error) {
            console.error(`Error deleting metadata: ${error.message}`);
            return false;
        }
    }
    console.log('No metadata file to delete');
    return false;
}

function displayModuleSummary(workingDir, moduleName, moduleInfo, submodules, models, metadataExists) {
    console.log('==========================================');
    console.log(`MODULE: ${moduleName}`);
    console.log('==========================================');

    console.log(`Environment: ${isCompiledBinary ? 'Bun Binary' : (isBun ? 'Bun Script' : 'Node.js Script')}`);
    console.log(`Working Directory: ${workingDir}`);
    console.log('');

    console.log('Submodules to be deleted:');
    if (submodules.length === 0) {
        console.log('- No submodules');
    } else {
        submodules.forEach(submodule => {
            console.log(`- ${submodule}`);
        });
    }

    console.log('\nModels to be deleted:');
    if (models.length === 0) {
        console.log('- No models');
    } else {
        models.forEach(model => {
            console.log(`- ${model}`);
        });
    }

    console.log('\nMain module file:');
    if (moduleInfo.moduleExists) {
        console.log(`- ${moduleInfo.modulePath}`);
    } else {
        console.log('- No main module file');
    }

    console.log('\nMetadata file:');
    if (metadataExists) {
        console.log(`- ${path.join(workingDir, 'metadata', `${moduleName}.json`)}`);
    } else {
        console.log('- No metadata file');
    }

    console.log('==========================================');
}

module.exports = {
    resource: 'project',
    verb: 'delete',
    description: 'Menghapus project beserta seluruh endpoint, processor, dashboard, dan consumer di dalamnya',
    category: 'management',
    flags: {
        project: {
            type: 'string',
            required: true,
            description: 'Nama project yang akan dihapus'
        },
        yes: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Lewati prompt konfirmasi'
        }
    },
    examples: [
        'npx restforge project delete --project=my-app',
        'npx restforge project delete --project=my-app --yes'
    ],
    async handler(args) {
        const moduleName = validateSafeName(args.project, 'project');
        const autoConfirm = args.yes === true;
        const workingDir = getWorkingDirectory();

        console.log(`Looking for module: ${moduleName}`);

        const moduleInfo = checkIfModuleExists(workingDir, moduleName);

        const metadataPath = path.join(workingDir, 'metadata', `${moduleName}.json`);
        const metadataExists = fs.existsSync(metadataPath);

        if (!moduleInfo.moduleExists && !moduleInfo.subModulesDirExists &&
            !moduleInfo.modelsDirExists && !metadataExists) {
            console.error(`Error: Module ${moduleName} not found`);
            console.error(`Make sure module ${moduleName} exists in the correct directory.`);
            console.error(`Working directory: ${workingDir}`);
            throw new Error(`Module ${moduleName} not found`);
        }

        const submodules = getSubmodulesList(moduleInfo.subModulesDir);
        const models = getModelsList(moduleInfo.modelsDir);

        displayModuleSummary(workingDir, moduleName, moduleInfo, submodules, models, metadataExists);

        const answer = autoConfirm
            ? 'y'
            : await showConfirmation('Are you sure you want to delete this module? (Y/n): ');

        if (answer === 'yes' || answer === 'y' || answer === '') {
            console.log('\nDeleting module...');

            let deletedCount = 0;
            let totalCount = 0;

            if (moduleInfo.moduleExists) {
                totalCount++;
                if (deleteFileOrDirectory(moduleInfo.modulePath)) deletedCount++;
            }

            if (moduleInfo.subModulesDirExists) {
                totalCount++;
                if (deleteFileOrDirectory(moduleInfo.subModulesDir)) deletedCount++;
            }

            if (moduleInfo.modelsDirExists) {
                totalCount++;
                if (deleteFileOrDirectory(moduleInfo.modelsDir)) deletedCount++;
            }

            if (metadataExists) {
                totalCount++;
                if (deleteModuleMetadata(workingDir, moduleName)) deletedCount++;
            }

            console.log('');
            console.log('==========================================');
            console.log('DELETION RESULT');
            console.log('==========================================');
            console.log(`Module: ${moduleName}`);
            console.log(`Deleted: ${deletedCount}/${totalCount} items`);

            if (deletedCount === totalCount) {
                console.log(`\nModule ${moduleName} deleted completely!`);
            } else {
                console.log(`\nModule ${moduleName} partially deleted. Check error logs above.`);
            }
            console.log('==========================================');
        } else {
            console.log('\nOperation cancelled. No files were deleted.');
        }
    }
};
