/**
 * Validator untuk argument command line
 */
class ArgumentValidator {

   /**
    * Daftar argument yang valid beserta aliasnya
    */
   static get validArguments() {
     return {
       project: {
         aliases: ['project'],
         required: true,
         description: 'Nama project yang akan dibuat',
         example: '--project=user-management'
       },
       endpoint: {
         aliases: ['endpoint'],
         required: false,
         description: 'Nama endpoint yang akan dibuat',
         example: '--endpoint=user-profile'
       },
       payload: {
         aliases: ['payload'],
         required: false,
         description: 'Nama file payload (tanpa ekstensi .json)',
         example: '--payload=user-profile-payload'
       },
       database: {
         aliases: ['database', 'db'],
         required: false,
         default: 'postgres',
         validValues: ['postgres', 'oracle', 'mysql', 'sqlite'],
         description: 'Tipe database yang akan digunakan',
         example: '--database=postgres, --database=oracle, --database=mysql, atau --database=sqlite'
       },
       force: {
         aliases: ['force'],
         required: false,
         default: false,
         validValues: ['true', 'false'],
         description: 'Menimpa file yang sudah ada',
         example: '--force=true atau --force=false'
       },
       createExamples: {
         aliases: ['create-examples', 'examples'],
         required: false,
         default: true,
         validValues: ['true', 'false'],
         description: 'Membuat file examples (curl, postman, insomnia) untuk testing endpoint',
         example: '--create-examples=true atau --create-examples=false'
       },
       skipSqlValidation: {
         aliases: ['skip-sql-validation', 'no-sql-check'],
         required: false,
         default: false,
         validValues: ['true', 'false'],
         description: 'Melewati validasi SQL keywords (untuk generator)',
         example: '--skip-sql-validation=true atau --no-sql-check=true'
       },
       noAuditMigration: {
         aliases: ['no-audit-migration'],
         required: false,
         default: false,
         validValues: ['true', 'false'],
         description: 'Skip eksekusi audit table migration saat payload ada auditRequired:true (file SQL tetap ditulis)',
         example: '--no-audit-migration=true'
       },
       name: {
         aliases: ['name'],
         required: false,
         description: 'Nama dashboard (dipakai oleh subcommand dashboard untuk emit dash-{name}.js)',
         example: '--name=sales'
       },
       verbose: {
         aliases: ['verbose'],
         required: false,
         default: false,
         validValues: ['true', 'false'],
         description: 'Tampilkan output detail per step (default: false, output ringkas)',
         example: '--verbose=true'
       }
     };
   }
 
   /**
    * Parse arguments dari command line
    * @param {Array<string>} args - Array argument dari process.argv.slice(2)
    * @returns {Object} Parsed arguments object
    */
   static parseArguments(args) {     const parsed = {
       project: null,
       endpoint: null,
       payload: null,
       name: null,
       database: 'postgres',
       force: false,
       createExamples: true,
       skipSqlValidation: false,
       noAuditMigration: false,
       verbose: false,
       validateOnly: false,
       help: false,
       version: false
     };
 
     // Handle case ketika tidak ada arguments
     if (!args || args.length === 0) {
       parsed.help = true;
       return parsed;
     }
 
     for (const arg of args) {
       // Handle help flags
       if (arg === '--help' || arg === '-h') {
         parsed.help = true;
         continue;
       }
 
       // Handle version flags
       if (arg === '--version' || arg === '-v') {
         parsed.version = true;
         continue;
       }
 
       // Parse key=value arguments
       if (arg.includes('=')) {
         const [key, ...valueParts] = arg.split('=');
         const value = valueParts.join('='); // Handle values with = in them
         const cleanKey = key.replace(/^--/, '');
 
         switch (cleanKey) {
           case 'project':
             parsed.project = this.validateProjectName(value);
             break;
 
           case 'endpoint':
             parsed.endpoint = this.validateEndpointName(value);
             break;
 
           case 'payload':
             parsed.payload = this.validatePayloadName(value);
             break;
 
           case 'database':
           case 'db':
             parsed.database = this.validateDatabaseType(value);
             break;
 
                      case 'force':
             parsed.force = this.validateBooleanValue(value, 'force');
             break;
           case 'create-examples':
           case 'examples':
             parsed.createExamples = this.validateBooleanValue(value, 'create-examples');
             break;

           case 'skip-sql-validation':
           case 'no-sql-check':
             parsed.skipSqlValidation = this.validateBooleanValue(value, 'skip-sql-validation');
             break;

           case 'no-audit-migration':
             parsed.noAuditMigration = this.validateBooleanValue(value, 'no-audit-migration');
             break;

           case 'name':
             parsed.name = typeof value === 'string' ? value.trim() : value;
             break;

           case 'verbose':
             parsed.verbose = this.validateBooleanValue(value, 'verbose');
             break;

           case 'validate-only':
             parsed.validateOnly = this.validateBooleanValue(value, 'validate-only');
             break;

           default:
             console.warn(`Warning: Unknown argument '${cleanKey}' will be ignored`);
             break;
         }
       } else {
         console.warn(`Warning: Invalid argument format '${arg}' - expected --key=value format`);
       }
     }
 
     return parsed;
   }
 
   /**
    * Validasi nama project
    * @param {string} projectName - Nama project
    * @returns {string} Validated project name
    * @throws {Error} Jika nama project tidak valid
    */
   static validateProjectName(projectName) {
     if (!projectName || typeof projectName !== 'string') {
       throw new Error('Project name cannot be empty');
     }

     const trimmed = projectName.trim();

     if (trimmed.length === 0) {
       throw new Error('Project name cannot be empty');
     }

     if (trimmed.length > 50) {
       throw new Error('Project name cannot exceed 50 characters');
     }

     // Validasi format nama project (alphanumeric, dash, underscore)
     const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
     if (!validPattern.test(trimmed)) {
       throw new Error('Project name can only contain letters, numbers, dash (-), and underscore (_), and must start with a letter or number');
     }

     // Tidak boleh dimulai atau diakhiri dengan dash atau underscore
     if (trimmed.startsWith('-') || trimmed.startsWith('_') ||
         trimmed.endsWith('-') || trimmed.endsWith('_')) {
       throw new Error('Project name cannot start or end with dash (-) or underscore (_)');
     }

     // Reserved names
     const reservedNames = ['src', 'lib', 'node_modules', 'config', 'utils', 'models', 'controllers', 'middleware', 'routes'];
     if (reservedNames.includes(trimmed.toLowerCase())) {
       throw new Error(`Project name '${trimmed}' is a reserved word and cannot be used`);
     }

     return trimmed.toLowerCase();
   }
 
   /**
    * Validasi nama endpoint
    * @param {string} endpointName - Nama endpoint
    * @returns {string} Validated endpoint name
    * @throws {Error} Jika nama endpoint tidak valid
    */
   static validateEndpointName(endpointName) {
     if (!endpointName || typeof endpointName !== 'string') {
       throw new Error('Endpoint name cannot be empty');
     }
 
     const trimmed = endpointName.trim();
     
     if (trimmed.length === 0) {
       throw new Error('Endpoint name cannot be empty');
     }
 
     if (trimmed.length > 50) {
       throw new Error('Endpoint name cannot exceed 50 characters');
     }
 
     // Validasi format nama endpoint (alphanumeric, dash, underscore)
     const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
     if (!validPattern.test(trimmed)) {
       throw new Error('Endpoint name can only contain letters, numbers, dash (-), and underscore (_), and must start with a letter or number');
     }
 
     // Tidak boleh dimulai atau diakhiri dengan dash atau underscore
     if (trimmed.startsWith('-') || trimmed.startsWith('_') || 
         trimmed.endsWith('-') || trimmed.endsWith('_')) {
       throw new Error('Endpoint name cannot start or end with dash (-) or underscore (_)');
     }
 
     // Reserved endpoint names
     const reservedNames = ['health', 'status', 'admin', 'api', 'auth', 'login', 'logout', 'register'];
     if (reservedNames.includes(trimmed.toLowerCase())) {
       throw new Error(`Endpoint name '${trimmed}' is a reserved word and cannot be used`);
     }
 
     return trimmed.toLowerCase();
   }
 
   /**
    * Validasi nama payload
    * @param {string} payloadName - Nama file payload
    * @returns {string} Validated payload name (dengan .json extension)
    * @throws {Error} Jika nama payload tidak valid
    */
   static validatePayloadName(payloadName) {
     if (!payloadName || typeof payloadName !== 'string') {
       throw new Error('Payload name cannot be empty');
     }
 
     let trimmed = payloadName.trim();
     
     if (trimmed.length === 0) {
       throw new Error('Payload name cannot be empty');
     }
 
     // Hapus .json extension jika ada, akan ditambahkan kembali nanti
     if (trimmed.endsWith('.json')) {
       trimmed = trimmed.slice(0, -5);
     }
 
     if (trimmed.length === 0) {
       throw new Error('Payload name cannot be just .json');
     }
 
     if (trimmed.length > 50) {
       throw new Error('Payload name cannot exceed 50 characters');
     }
 
     // Validasi format nama payload (alphanumeric, dash, underscore)
     const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
     if (!validPattern.test(trimmed)) {
       throw new Error('Payload name can only contain letters, numbers, dash (-), and underscore (_), and must start with a letter or number');
     }
 
     // Tidak boleh dimulai atau diakhiri dengan dash atau underscore
     if (trimmed.startsWith('-') || trimmed.startsWith('_') || 
         trimmed.endsWith('-') || trimmed.endsWith('_')) {
       throw new Error('Payload name cannot start or end with dash (-) or underscore (_)');
     }
 
     // Tambahkan .json extension
     return trimmed.toLowerCase() + '.json';
   }
 
   /**
    * Validasi tipe database
    * @param {string} databaseType - Tipe database
    * @returns {string} Validated database type
    * @throws {Error} Jika tipe database tidak valid
    */
   static validateDatabaseType(databaseType) {
     if (!databaseType || typeof databaseType !== 'string') {
       throw new Error('Database type cannot be empty');
     }
 
     const trimmed = databaseType.trim().toLowerCase();
     const validTypes = ['postgres', 'oracle', 'mysql', 'sqlite'];
 
     if (!validTypes.includes(trimmed)) {
       throw new Error(`Database type '${databaseType}' is invalid. Valid options: ${validTypes.join(', ')}`);
     }
 
     return trimmed;
   }
 
   /**
    * Validasi boolean value
    * @param {string} value - String value yang akan dikonversi ke boolean
    * @param {string} fieldName - Nama field untuk error message
    * @returns {boolean} Parsed boolean value
    * @throws {Error} Jika value tidak bisa diparse sebagai boolean
    */
   static validateBooleanValue(value, fieldName) {
     if (typeof value === 'boolean') {
       return value;
     }
 
     if (!value || typeof value !== 'string') {
       throw new Error(`${fieldName} value cannot be empty`);
     }
 
     const trimmed = value.trim().toLowerCase();
     const validTrue = ['true', '1', 'yes', 'y'];
     const validFalse = ['false', '0', 'no', 'n'];
 
     if (validTrue.includes(trimmed)) {
       return true;
     }
 
     if (validFalse.includes(trimmed)) {
       return false;
     }
 
     throw new Error(`${fieldName} value '${value}' is invalid. Valid options: true, false, 1, 0, yes, no, y, n`);
   }
 
   /**
    * Validasi arguments yang sudah diparse
    * @param {Object} args - Parsed arguments object
    * @throws {Error} Jika validasi gagal
    */
   static validateArguments(args) {
     // Handle help request
     if (args.help) {
       this.showHelp();
       process.exit(0);
     }
 
     // Handle version request
     if (args.version) {
       this.showVersion();
       process.exit(0);
     }
 
     // Validasi project name (required)
     if (!args.project) {
       throw new Error('Parameter --project must be specified');
     }
 
     // Validasi kombinasi endpoint dan payload
     if (args.endpoint && !args.payload) {
       throw new Error('If --endpoint is specified, then --payload must also be specified');
     }
 
     if (args.payload && !args.endpoint) {
       throw new Error('If --payload is specified, then --endpoint must also be specified');
     }
 
     // Log parsed arguments untuk debugging (exclude sensitive)
     console.log('Arguments to be processed:');
     console.log(`   Project: ${args.project}`);
     if (args.endpoint) {
       console.log(`   Endpoint: ${args.endpoint}`);
     }
     if (args.payload) {
       console.log(`   Payload: ${args.payload}`);
     }
     console.log(`   Database: ${args.database}`);
     console.log(`   Force overwrite: ${args.force}`);
     console.log('');
   }
 
   /**
    * Show help message
    */
   static showHelp() {
     console.log(`
 Create Module Tool - Help

 DESCRIPTION:
   Script to create new projects and endpoints automatically.
   Supports PostgreSQL, Oracle, and MySQL databases.

 USAGE:
   npx restforge endpoint create [OPTIONS]

 OPTIONS:
   --project=<name>      Project name to create (REQUIRED)

   --endpoint=<name>     Endpoint name to create (OPTIONAL)
   --payload=<file>      Payload file name without .json (OPTIONAL)

   --database=<type>     Database type: postgres|oracle|mysql|sqlite (DEFAULT: postgres)
   --force=<bool>        Overwrite existing files (skip confirmation): true|false (DEFAULT: false)
   --create-examples=<bool>  Create example files for testing: true|false (DEFAULT: true)
   --skip-sql-validation=<bool>  Skip SQL keywords validation: true|false (DEFAULT: false)
   --no-audit-migration=<bool>   Skip audit table migration when payload fieldPolicy strategies include 'audit' (DEFAULT: false)

   --help, -h           Show this help message
   --version, -v        Show version information

 EXAMPLES:
   # Create a new project only
   npx restforge endpoint create --project=user-management

   # Create a project with endpoint
   npx restforge endpoint create --project=user-management --name=user-profile --payload=user-profile-payload

   # Using Oracle database
   npx restforge endpoint create --project=inventory --name=products --payload=products-payload --database=oracle

   # Force overwrite existing files
   npx restforge endpoint create --project=user-management --name=user-profile --payload=user-profile-payload --force=true

 NOTES:
   - Payload file must exist in the payload/ directory
   - Endpoint and payload must be specified together
   - Project name and endpoint name may only contain letters, numbers, dashes, underscores
   - Reserved names cannot be used (src, lib, config, etc.)

 SUPPORT:
   If you encounter issues, make sure:
   1. Payload file is available in the payload/ directory
   2. Project directory structure is correct
 `);
   }
 
   /**
    * Show version information
    */
   static showVersion() {
     console.log(`
 Create Module Tool
 Version: 2.0.0
 Build: 2024-12-15
 Environment: ${process.env.NODE_ENV || 'development'}
 
 Features:
   PostgreSQL & Oracle Support
   Auto Module Generation
   Endpoint Creation
   Payload Validation
   Metadata Management
   PKG Executable Support
 
 Copyright (c) 2024 - Module Generator Team
 `);
   }
 
   /**
    * Validasi keseluruhan workflow
    * @param {Object} args - Parsed arguments
    * @returns {Object} Validation summary
    */
   static validateWorkflow(args) {
     const summary = {
       isValid: true,
       warnings: [],
       recommendations: [],
       workflow: 'unknown'
     };
 
     // Tentukan workflow berdasarkan arguments
     if (args.project && !args.endpoint && !args.payload) {
       summary.workflow = 'project-only';
       summary.recommendations.push('Gunakan --endpoint dan --payload untuk menambahkan endpoint setelah project dibuat');
     } else if (args.project && args.endpoint && args.payload) {
       summary.workflow = 'full-generation';
     } else {
       summary.workflow = 'invalid';
       summary.isValid = false;
     }
 
     // Warning untuk force overwrite
     if (args.force) {
       summary.warnings.push('Mode force overwrite aktif - file yang sudah ada akan ditimpa tanpa konfirmasi');
     }
 
     // Warning untuk Oracle database
     if (args.database === 'oracle') {
       summary.warnings.push('Menggunakan Oracle database - pastikan utils/oracle.js tersedia');
     }
 
     return summary;
   }
 
   /**
    * Menampilkan summary validasi
    * @param {Object} validationSummary - Hasil validasi workflow
    */
   static showValidationSummary(validationSummary) {
     if (!validationSummary.isValid) {
       console.error('Invalid workflow');
       return;
     }
 
     console.log(`🎯 Workflow: ${validationSummary.workflow}`);
 
     if (validationSummary.warnings.length > 0) {
       console.log('Warnings:');
       validationSummary.warnings.forEach(warning => {
         console.log(`   - ${warning}`);
       });
     }
 
     if (validationSummary.recommendations.length > 0) {
       console.log('💡 Recommendations:');
       validationSummary.recommendations.forEach(rec => {
         console.log(`   - ${rec}`);
       });
     }
 
     console.log('');
   }
 }
 
 module.exports = ArgumentValidator;