const fs = require('fs');
const path = require('path');
const readline = require('readline');
const ConfigReader = require('../config/config-reader');
const MetadataManager = require('./metadata-manager');
const FileUtils = require('./file-utils');

/**
 * Checker untuk konflik file dan endpoint
 */
class ConflictChecker {

  /**
   * Check konflik endpoint dan minta konfirmasi jika perlu
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Promise<boolean>} True jika boleh lanjut, false jika dibatalkan
   */
  static async checkEndpointConflict(moduleName, endpointName) {
    if (!endpointName) {
      // Jika hanya module name, tidak ada konflik endpoint
      return true;
    }

    console.log(`Checking for conflicts: ${moduleName}/${endpointName}`);

    const conflicts = this.detectConflicts(moduleName, endpointName);

    if (conflicts.hasConflicts) {
      return await this.handleConflicts(moduleName, endpointName, conflicts);
    }

    console.log(`No conflicts detected for ${endpointName}`);
    return true;
  }

  /**
   * Deteksi konflik khusus untuk module files (submodule + model)
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Object} payload - Payload object untuk cek SQL files
   * @returns {Object} Conflict information
   */
  static detectModuleConflicts(moduleName, endpointName, payload) {
    const workingDir = ConfigReader.getWorkingDirectory();
    
    const conflicts = {
      hasConflicts: false,
      fileConflicts: [],
      metadataConflicts: [],
      systemConflicts: [],
      details: {}
    };

    // 1. Check submodule file conflict
    const submoduleFilePath = path.join(workingDir, 'src', 'modules', moduleName, `${endpointName}.js`);
    if (fs.existsSync(submoduleFilePath)) {
      const fileInfo = FileUtils.getFileInfo(submoduleFilePath);
      conflicts.fileConflicts.push({
        type: 'submoduleFile',
        path: submoduleFilePath,
        relativePath: path.relative(workingDir, submoduleFilePath),
        fileInfo: fileInfo
      });
      conflicts.hasConflicts = true;
    }

    // 2. Check model file conflict
    const modelFilePath = path.join(workingDir, 'src', 'models', moduleName, `${endpointName}.js`);
    if (fs.existsSync(modelFilePath)) {
      const fileInfo = FileUtils.getFileInfo(modelFilePath);
      conflicts.fileConflicts.push({
        type: 'modelFile',
        path: modelFilePath,
        relativePath: path.relative(workingDir, modelFilePath),
        fileInfo: fileInfo
      });
      conflicts.hasConflicts = true;
    }

    // 3. Check system-level conflicts
    const systemConflict = this.checkSystemConflicts(moduleName, endpointName);
    if (systemConflict) {
      conflicts.systemConflicts.push(systemConflict);
      conflicts.hasConflicts = true;
    }

    // 5. Add summary details
    conflicts.details = {
      moduleName: moduleName,
      endpointName: endpointName,
      totalConflicts: conflicts.fileConflicts.length + conflicts.systemConflicts.length,
      totalFiles: conflicts.fileConflicts.length,
      submoduleFiles: conflicts.fileConflicts.filter(f => f.type === 'submoduleFile').length,
      modelFiles: conflicts.fileConflicts.filter(f => f.type === 'modelFile').length,
      queryDirs: conflicts.fileConflicts.filter(f => f.type === 'queryDir').length,
      systemIssues: conflicts.systemConflicts.length,
      riskLevel: this.assessRiskLevel(conflicts)
    };

    return conflicts;
  }

  /**
   * Helper function untuk cek apakah payload memiliki SQL files
   * @param {Object} payload - Payload object
   * @returns {boolean} True jika ada SQL files
   */
  static hasQueryFiles(payload) {
    if (!payload) return false;
    
    // Check for advanced queries
    if (payload.advancedQueries && Object.keys(payload.advancedQueries).length > 0) {
      return true;
    }
    
    // Check for nested queries
    if (payload.nestedQueries && Array.isArray(payload.nestedQueries) && payload.nestedQueries.length > 0) {
      return true;
    }
    
    // Check for custom datatables query
    if (payload.datatablesQuery && typeof payload.datatablesQuery === 'string' && payload.datatablesQuery.startsWith('file:')) {
      return true;
    }
    
    return false;
  }

  /**
   * Handle konflik khusus untuk module dengan user interaction
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Object} payload - Payload object untuk cek SQL files
   * @returns {Promise<boolean>} True jika boleh lanjut, false jika dibatalkan
   */
  static async handleModuleConflicts(moduleName, endpointName, payload) {
    console.log(`Checking for module conflicts: ${moduleName}/${endpointName}`);

    const conflicts = this.detectModuleConflicts(moduleName, endpointName, payload);

    if (!conflicts.hasConflicts) {
      console.log(`No module conflicts detected for ${endpointName}`);
      return true;
    }

    return await this.handleConflicts(moduleName, endpointName, conflicts);
  }

  /**
   * Create archive files khusus untuk module conflicts menggunakan numbering berdasarkan timesGenerated
   * @param {Object} conflicts - Conflicts object dari detectModuleConflicts
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Array} Array archive files yang dibuat
   */
  static createModuleArchiveFiles(conflicts, moduleName, endpointName) {
    const archiveFiles = [];

    if (!conflicts || !conflicts.hasConflicts) {
      return archiveFiles;
    }

    
    console.log(`Creating archive files for conflicting module files...`);

    // Get current timesGenerated dari metadata
    const currentGeneration = MetadataManager.getEndpointGeneration(moduleName, endpointName);
    const archiveNumber = String(currentGeneration).padStart(3, '0');

    for (const fileConflict of conflicts.fileConflicts) {
      try {
        // Skip directory conflicts untuk sekarang
        if (fs.statSync(fileConflict.path).isDirectory()) {
          console.log(`Skipping directory archive: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} (directory)`);
          continue;
        }

        const fileExt = path.extname(fileConflict.path);
        const baseName = path.basename(fileConflict.path, fileExt);
        const dirName = path.dirname(fileConflict.path);
        
        // Format: filename.archive.001, filename.archive.002, etc.
        const archivePath = path.join(dirName, `${baseName}${fileExt}.archive.${archiveNumber}`);
        
        fs.copyFileSync(fileConflict.path, archivePath);
        
        archiveFiles.push({
          original: fileConflict.path,
          archive: archivePath,
          type: fileConflict.type,
          generation: currentGeneration
        });

        console.log(`Archived: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} -> ${path.relative(ConfigReader.getWorkingDirectory(), archivePath)}`);
        
      } catch (error) {
        console.error(`Error creating archive for ${fileConflict.path}:`, error.message);
      }
    }

    console.log(`Created ${archiveFiles.length} module archive file(s) for generation ${archiveNumber}`);
    return archiveFiles;
  }

  /**
   * Deteksi konflik khusus untuk processor files
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Array} processors - Array processor names dari payload
   * @returns {Object} Conflict information
   */
  static detectProcessorConflicts(moduleName, endpointName, processors) {
    const workingDir = ConfigReader.getWorkingDirectory();
    
    const conflicts = {
      hasConflicts: false,
      fileConflicts: [],
      metadataConflicts: [],
      systemConflicts: [],
      details: {}
    };

    // 1. Check endpoint file conflict
    const endpointFilePath = path.join(workingDir, 'src', 'modules', moduleName, `${endpointName}.js`);
    if (fs.existsSync(endpointFilePath)) {
      const fileInfo = FileUtils.getFileInfo(endpointFilePath);
      conflicts.fileConflicts.push({
        type: 'endpointFile',
        path: endpointFilePath,
        relativePath: path.relative(workingDir, endpointFilePath),
        fileInfo: fileInfo
      });
      conflicts.hasConflicts = true;
    }

    // 2. Check processor files conflicts
    const processorDir = path.join(workingDir, 'src', 'modules', moduleName, 'processor', endpointName);
    
    for (const processor of processors) {
      const processorFilePath = path.join(processorDir, `${processor.name}.js`);
      if (fs.existsSync(processorFilePath)) {
        const fileInfo = FileUtils.getFileInfo(processorFilePath);
        conflicts.fileConflicts.push({
          type: 'processorFile',
          path: processorFilePath,
          relativePath: path.relative(workingDir, processorFilePath),
          fileInfo: fileInfo,
          processorName: processor.name
        });
        conflicts.hasConflicts = true;
      }
    }

    // 3. Check system-level conflicts
    const systemConflict = this.checkSystemConflicts(moduleName, endpointName);
    if (systemConflict) {
      conflicts.systemConflicts.push(systemConflict);
      conflicts.hasConflicts = true;
    }

    // 4. Add summary details
    conflicts.details = {
      moduleName: moduleName,
      endpointName: endpointName,
      totalConflicts: conflicts.fileConflicts.length + conflicts.systemConflicts.length,
      totalFiles: conflicts.fileConflicts.length,
      endpointFiles: conflicts.fileConflicts.filter(f => f.type === 'endpointFile').length,
      processorFiles: conflicts.fileConflicts.filter(f => f.type === 'processorFile').length,
      systemIssues: conflicts.systemConflicts.length,
      riskLevel: this.assessRiskLevel(conflicts)
    };

    return conflicts;
  }

  /**
   * Deteksi semua jenis konflik yang mungkin
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Object} Conflict information
   */
  static detectConflicts(moduleName, endpointName) {
    const workingDir = ConfigReader.getWorkingDirectory();
    
    const conflicts = {
      hasConflicts: false,
      fileConflicts: [],
      metadataConflicts: [],
      systemConflicts: [],
      details: {}
    };

    // 1. Check file conflicts
    const filePaths = this.getEndpointFilePaths(moduleName, endpointName);
    
    for (const [fileType, filePath] of Object.entries(filePaths)) {
      if (fs.existsSync(filePath)) {
        const fileInfo = FileUtils.getFileInfo(filePath);
        conflicts.fileConflicts.push({
          type: fileType,
          path: filePath,
          relativePath: path.relative(workingDir, filePath),
          fileInfo: fileInfo
        });
        conflicts.hasConflicts = true;
      }
    }

    // 2. Check system conflicts (reserved names, etc)
    const systemConflict = this.checkSystemConflicts(moduleName, endpointName);
    if (systemConflict) {
      conflicts.systemConflicts.push(systemConflict);
      conflicts.hasConflicts = true;
    }

    // 3. Collect detailed information
    conflicts.details = {
      moduleName: moduleName,
      endpointName: endpointName,
      totalConflicts: conflicts.fileConflicts.length + conflicts.systemConflicts.length,
      riskLevel: this.assessRiskLevel(conflicts)
    };

    return conflicts;
  }

  /**
   * Get semua file paths untuk endpoint
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Object} Object dengan file paths
   */
  static getEndpointFilePaths(moduleName, endpointName) {
    const workingDir = ConfigReader.getWorkingDirectory();
    
    return {
      moduleFile: path.join(workingDir, 'src', 'modules', moduleName, `${endpointName}.js`),
      modelFile: path.join(workingDir, 'src', 'models', moduleName, `${endpointName}.js`),
      queryDir: path.join(workingDir, 'src', 'models', moduleName, 'query'),
      metadataFile: MetadataManager.getMetadataPath(moduleName)
    };
  }

  /**
   * Check system-level conflicts
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Object|null} System conflict info atau null
   */
  static checkSystemConflicts(moduleName, endpointName) {
    const reservedEndpointNames = [
      'health', 'status', 'admin', 'api', 'auth', 'login', 'logout', 
      'register', 'index', 'main', 'app', 'config', 'test'
    ];

    if (reservedEndpointNames.includes(endpointName.toLowerCase())) {
      return {
        type: 'reserved_name',
        message: `Endpoint name '${endpointName}' is reserved and should not be used`,
        severity: 'high',
        recommendation: 'Choose a different endpoint name'
      };
    }

    // Check for naming conflicts with module name
    if (endpointName.toLowerCase() === moduleName.toLowerCase()) {
      return {
        type: 'name_collision',
        message: `Endpoint name '${endpointName}' is the same as module name '${moduleName}'`,
        severity: 'medium',
        recommendation: 'Use a different endpoint name to avoid confusion'
      };
    }

    return null;
  }

  /**
   * Assess risk level dari conflicts
   * @param {Object} conflicts - Conflict information
   * @returns {string} Risk level: low, medium, high
   */
  static assessRiskLevel(conflicts) {
    let riskScore = 0;

    // File conflicts
    riskScore += conflicts.fileConflicts.length * 2;

    // Metadata conflicts
    riskScore += conflicts.metadataConflicts.length * 1;

    // System conflicts
    for (const systemConflict of conflicts.systemConflicts) {
      switch (systemConflict.severity) {
        case 'high':
          riskScore += 5;
          break;
        case 'medium':
          riskScore += 3;
          break;
        case 'low':
          riskScore += 1;
          break;
      }
    }

    if (riskScore >= 7) return 'high';
    if (riskScore >= 3) return 'medium';
    return 'low';
  }

  /**
   * Handle conflicts dengan user interaction
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Object} conflicts - Conflict information
   * @returns {Promise<boolean>} True jika user memilih untuk lanjut
   */
  static async handleConflicts(moduleName, endpointName, conflicts) {
    // Show conflict summary
    this.showConflictSummary(conflicts);

    // Selalu tampilkan dialog konfirmasi ke user (konsisten di semua environment)
    return await this.askUserConfirmation(conflicts);
  }

  /**
   * Show detailed conflict summary
   * @param {Object} conflicts - Conflict information
   */
  static showConflictSummary(conflicts) {
    const { details, fileConflicts, metadataConflicts, systemConflicts } = conflicts;

    console.log(`\nCONFLICTS DETECTED for ${details.endpointName}`);
    console.log(`Risk Level: ${details.riskLevel.toUpperCase()}`);
    console.log(`Total Conflicts: ${details.totalConflicts}`);

    // File conflicts
    if (fileConflicts.length > 0) {
      console.log(`\nFile Conflicts (${fileConflicts.length}):`);
      fileConflicts.forEach(conflict => {
        console.log(`   - ${conflict.type}: ${conflict.relativePath}`);
        if (conflict.fileInfo) {
          console.log(`     Size: ${conflict.fileInfo.sizeHuman}, Modified: ${conflict.fileInfo.modified.toLocaleDateString()}`);
        }
      });
    }

    // Metadata conflicts
    if (metadataConflicts.length > 0) {
      console.log(`\nMetadata Conflicts (${metadataConflicts.length}):`);
      metadataConflicts.forEach(conflict => {
        console.log(`   - ${conflict.type}: ${conflict.endpointName}`);
        if (conflict.metadata) {
          const actions = Object.entries(conflict.metadata.actions || {})
            .filter(([, enabled]) => enabled)
            .map(([action]) => action);
          console.log(`     Table: ${conflict.metadata.tableName}, Actions: ${actions.join(', ')}`);
          console.log(`     Last Updated: ${new Date(conflict.metadata.updatedAt).toLocaleDateString()}`);
        }
      });
    }

    // System conflicts
    if (systemConflicts.length > 0) {
      console.log(`\n⚙️  System Conflicts (${systemConflicts.length}):`);
      systemConflicts.forEach(conflict => {
        console.log(`   - ${conflict.type} (${conflict.severity}): ${conflict.message}`);
        console.log(`     Recommendation: ${conflict.recommendation}`);
      });
    }
  }

  /**
   * Handle konflik khusus untuk processor dengan user interaction
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Array} processors - Array processor names dari payload
   * @returns {Promise<boolean>} True jika boleh lanjut, false jika dibatalkan
   */
  static async handleProcessorConflicts(moduleName, endpointName, processors) {
    console.log(`Checking for processor conflicts: ${moduleName}/${endpointName}`);

    const conflicts = this.detectProcessorConflicts(moduleName, endpointName, processors);

    if (!conflicts.hasConflicts) {
      console.log(`No processor conflicts detected for ${endpointName}`);
      return true;
    }

    return await this.handleConflicts(moduleName, endpointName, conflicts);
  }

  /**
   * Create archive files khusus untuk processor conflicts menggunakan numbering berdasarkan timesGenerated
   * @param {Object} conflicts - Conflicts object dari detectProcessorConflicts
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Array} Array archive files yang dibuat
   */
  static createProcessorArchiveFiles(conflicts, moduleName, endpointName) {
    const archiveFiles = [];

    if (!conflicts || !conflicts.hasConflicts) {
      return archiveFiles;
    }

    console.log(`Creating archive files for conflicting processor files...`);

    // Get current timesGenerated dari metadata
    const currentGeneration = MetadataManager.getEndpointGeneration(moduleName, endpointName);
    const archiveNumber = String(currentGeneration).padStart(3, '0');

    for (const fileConflict of conflicts.fileConflicts) {
      try {
        // Skip directory conflicts untuk sekarang
        if (fs.statSync(fileConflict.path).isDirectory()) {
          console.log(`Skipping directory archive: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} (directory)`);
          continue;
        }

        const fileExt = path.extname(fileConflict.path);
        const baseName = path.basename(fileConflict.path, fileExt);
        const dirName = path.dirname(fileConflict.path);
        
        // Format: filename.archive.001, filename.archive.002, etc.
        const archivePath = path.join(dirName, `${baseName}${fileExt}.archive.${archiveNumber}`);
        
        fs.copyFileSync(fileConflict.path, archivePath);
        
        archiveFiles.push({
          original: fileConflict.path,
          archive: archivePath,
          type: fileConflict.type,
          generation: currentGeneration,
          processorName: fileConflict.processorName || null
        });

        console.log(`Archived: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} -> ${path.relative(ConfigReader.getWorkingDirectory(), archivePath)}`);
        
      } catch (error) {
        console.error(`Error creating archive for ${fileConflict.path}:`, error.message);
      }
    }

    console.log(`Created ${archiveFiles.length} processor archive file(s) for generation ${archiveNumber}`);
    return archiveFiles;
  }

  /**
   * Ask user confirmation sebelum overwrite file yang sudah ada
   * @param {Object} conflicts - Conflict information
   * @returns {Promise<boolean>} True jika user memilih untuk lanjut
   */
  static async askUserConfirmation(conflicts) {
    
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });

    return new Promise((resolve) => {
      const { details, systemConflicts } = conflicts;

      // Warning untuk high severity system conflicts
      const hasHighSeverityConflicts = systemConflicts.some(c => c.severity === 'high');
      
      if (hasHighSeverityConflicts) {
        console.log(`\n🚨 HIGH SEVERITY CONFLICTS DETECTED!`);
        console.log(`   These conflicts may cause serious issues.`);
        console.log(`   Strong recommendation: Choose a different endpoint name.`);
      }

      const riskMessage = this.getRiskMessage(details.riskLevel);
      console.log(`\n${riskMessage}`);

      const question = hasHighSeverityConflicts 
        ? '\nDo you REALLY want to proceed despite high severity conflicts? (y/N): '
        : '\nDo you want to proceed and overwrite existing files? (y/N): ';

      rl.question(question, (answer) => {
        rl.close();
        
        const shouldProceed = answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
        
        if (shouldProceed) {
          console.log(`User confirmed: Proceeding with ${details.endpointName} generation`);
          if (conflicts.fileConflicts.length > 0) {
            console.log(`Backups will be created for existing files`);
          }
        } else {
          console.log(`User cancelled: Operation aborted for ${details.endpointName}`);
          console.log(`💡 Suggestion: Try a different endpoint name or use --force=true to skip confirmation`);
        }
        
        resolve(shouldProceed);
      });
    });
  }

  /**
   * Get risk message berdasarkan risk level
   * @param {string} riskLevel - Risk level (low, medium, high)
   * @returns {string} Risk message
   */
  static getRiskMessage(riskLevel) {
    switch (riskLevel) {
      case 'low':
        return 'LOW RISK: Minor conflicts detected. Safe to proceed.';
      
      case 'medium':
        return 'MEDIUM RISK: Some conflicts detected. Proceed with caution.';
      
      case 'high':
        return '💥 HIGH RISK: Significant conflicts detected. Consider alternative approach.';
      
      default:
        return 'UNKNOWN RISK: Unable to assess conflict severity.';
    }
  }

  /**
   * Create archive files menggunakan numbering berdasarkan timesGenerated
   * @param {Object} conflicts - Conflicts object dari detectConflicts
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Array} Array archive files yang dibuat
   */
  static createArchiveFiles(conflicts, moduleName, endpointName) {
    const archiveFiles = [];

    if (!conflicts || !conflicts.hasConflicts) {
      return archiveFiles;
    }

    console.log(`Creating archive files for conflicting files...`);

    // Get current timesGenerated dari metadata
    const currentGeneration = MetadataManager.getEndpointGeneration(moduleName, endpointName);
    const archiveNumber = String(currentGeneration).padStart(3, '0');

    for (const fileConflict of conflicts.fileConflicts) {
      try {
        // Skip directory conflicts untuk sekarang
        if (fs.statSync(fileConflict.path).isDirectory()) {
          console.log(`Skipping directory archive: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} (directory)`);
          continue;
        }

        // Skip metadata files dari archive system
        const relativePath = path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path);
        if (relativePath.startsWith('metadata' + path.sep) || fileConflict.type === 'metadataFile') {
          console.log(`Skipping metadata archive: ${relativePath} (metadata files are not archived)`);
          continue;
        }

        const fileExt = path.extname(fileConflict.path);
        const baseName = path.basename(fileConflict.path, fileExt);
        const dirName = path.dirname(fileConflict.path);
        
        // Format: filename.archive.001, filename.archive.002, etc.
        const archivePath = path.join(dirName, `${baseName}${fileExt}.archive.${archiveNumber}`);
        
        fs.copyFileSync(fileConflict.path, archivePath);
        
        archiveFiles.push({
          original: fileConflict.path,
          archive: archivePath,
          type: fileConflict.type,
          generation: currentGeneration
        });

        console.log(`Archived: ${path.relative(ConfigReader.getWorkingDirectory(), fileConflict.path)} -> ${path.relative(ConfigReader.getWorkingDirectory(), archivePath)}`);
        
      } catch (error) {
        console.error(`Error creating archive for ${fileConflict.path}:`, error.message);
      }
    }

    console.log(`Created ${archiveFiles.length} archive file(s) for generation ${archiveNumber}`);
    return archiveFiles;
  }

  /**
   * Create backup untuk files yang akan di-overwrite
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Array} Array backup files yang dibuat
   */
  static createConflictBackups(moduleName, endpointName) {
    const conflicts = this.detectConflicts(moduleName, endpointName);
    const backupFiles = [];

    if (!conflicts.hasConflicts) {
      return backupFiles;
    }

    console.log(`Creating backups for conflicting files...`);

    for (const fileConflict of conflicts.fileConflicts) {
      try {
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const backupPath = `${fileConflict.path}.backup.${timestamp}`;
        
        fs.copyFileSync(fileConflict.path, backupPath);
        
        backupFiles.push({
          original: fileConflict.path,
          backup: backupPath,
          type: fileConflict.type
        });
        
        console.log(`Backup created: ${path.basename(backupPath)}`);
      } catch (error) {
        console.warn(`Warning: Failed to create backup for ${fileConflict.relativePath}:`, error.message);
      }
    }

    if (backupFiles.length > 0) {
      console.log(`Total ${backupFiles.length} backup files created`);
    }

    return backupFiles;
  }

  /**
   * Validate apakah nama module aman untuk digunakan
   * @param {string} moduleName - Nama module
   * @returns {Object} Validation result
   */
  static validateModuleName(moduleName) {
    const result = {
      isValid: true,
      warnings: [],
      errors: [],
      recommendations: []
    };

    // Check reserved names
    const reservedModuleNames = [
      'src', 'lib', 'node_modules', 'config', 'utils', 'models', 
      'controllers', 'middleware', 'routes', 'public', 'views',
      'test', 'tests', 'spec', 'specs', 'docs', 'dist', 'build'
    ];

    if (reservedModuleNames.includes(moduleName.toLowerCase())) {
      result.isValid = false;
      result.errors.push(`Module name '${moduleName}' is reserved and cannot be used`);
      result.recommendations.push('Choose a different module name');
    }

    // Check for existing module
    const workingDir = ConfigReader.getWorkingDirectory();
    const moduleDir = path.join(workingDir, 'src', 'modules', moduleName);
    
    if (fs.existsSync(moduleDir)) {
      result.warnings.push(`Module directory already exists: ${moduleName}`);
      result.recommendations.push('Existing module will be extended with new endpoints');
    }

    // Check naming conventions
    if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(moduleName)) {
      result.isValid = false;
      result.errors.push('Module name must start with letter/number and contain only letters, numbers, dashes, and underscores');
    }

    if (moduleName.length > 50) {
      result.isValid = false;
      result.errors.push('Module name too long (max 50 characters)');
    }

    if (moduleName.length < 2) {
      result.isValid = false;
      result.errors.push('Module name too short (min 2 characters)');
    }

    return result;
  }

  /**
   * Validate apakah nama endpoint aman untuk digunakan
   * @param {string} endpointName - Nama endpoint
   * @returns {Object} Validation result
   */
  static validateEndpointName(endpointName) {
    const result = {
      isValid: true,
      warnings: [],
      errors: [],
      recommendations: []
    };

    // Check reserved names
    const reservedEndpointNames = [
      'health', 'status', 'admin', 'api', 'auth', 'login', 'logout', 
      'register', 'index', 'main', 'app', 'config', 'test', 'docs',
      'swagger', 'graphql', 'websocket', 'socket'
    ];

    if (reservedEndpointNames.includes(endpointName.toLowerCase())) {
      result.isValid = false;
      result.errors.push(`Endpoint name '${endpointName}' is reserved and cannot be used`);
      result.recommendations.push('Choose a different endpoint name');
    }

    // Check naming conventions
    if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(endpointName)) {
      result.isValid = false;
      result.errors.push('Endpoint name must start with letter/number and contain only letters, numbers, dashes, and underscores');
    }

    if (endpointName.length > 50) {
      result.isValid = false;
      result.errors.push('Endpoint name too long (max 50 characters)');
    }

    if (endpointName.length < 2) {
      result.isValid = false;
      result.errors.push('Endpoint name too short (min 2 characters)');
    }

    // Check for potentially problematic names
    const problematicPatterns = [
      /^(get|post|put|delete|patch)$/i,  // HTTP methods
      /^(create|read|update|delete|crud)$/i,  // CRUD operations
      /^(list|show|edit|new)$/i,  // Common actions
    ];

    for (const pattern of problematicPatterns) {
      if (pattern.test(endpointName)) {
        result.warnings.push(`Endpoint name '${endpointName}' might be confusing as it matches common HTTP/CRUD terms`);
        result.recommendations.push('Consider adding more context to the endpoint name');
        break;
      }
    }

    return result;
  }

  /**
   * Check untuk potential conflicts dalam payload
   * @param {Object} payload - Payload object
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @returns {Object} Conflict check result
   */
  static checkPayloadConflicts(payload, moduleName, endpointName) {
    const result = {
      hasConflicts: false,
      warnings: [],
      errors: [],
      recommendations: []
    };

    // Check table name conflicts
    if (payload.tableName) {
      const tableNameLower = payload.tableName.toLowerCase();
      
      // Check for reserved table names
      const reservedTableNames = [
        'user', 'users', 'admin', 'admins', 'config', 'configs',
        'system', 'sys', 'information_schema', 'pg_catalog'
      ];

      if (reservedTableNames.includes(tableNameLower)) {
        result.warnings.push(`Table name '${payload.tableName}' might conflict with system tables`);
        result.recommendations.push('Consider using a more specific table name prefix');
      }

      // Check if table name matches module or endpoint name
      if (tableNameLower === moduleName.toLowerCase()) {
        result.warnings.push(`Table name matches module name: ${payload.tableName}`);
      }

      if (tableNameLower === endpointName.toLowerCase()) {
        result.warnings.push(`Table name matches endpoint name: ${payload.tableName}`);
      }
    }

    // Check field name conflicts
    if (payload.fieldName && Array.isArray(payload.fieldName)) {
      const reservedFieldNames = [
        'password', 'secret', 'token', 'key', 'private',
        'admin', 'root', 'system', 'internal'
      ];

      const sensitiveFields = payload.fieldName.filter(field => 
        reservedFieldNames.some(reserved => 
          field.toLowerCase().includes(reserved.toLowerCase())
        )
      );

      if (sensitiveFields.length > 0) {
        result.warnings.push(`Potentially sensitive field names detected: ${sensitiveFields.join(', ')}`);
        result.recommendations.push('Ensure sensitive fields have proper security measures');
      }

      // Check for duplicate field names (case insensitive)
      const fieldNamesLower = payload.fieldName.map(f => f.toLowerCase());
      const duplicates = fieldNamesLower.filter((field, index) => 
        fieldNamesLower.indexOf(field) !== index
      );

      if (duplicates.length > 0) {
        result.hasConflicts = true;
        result.errors.push(`Duplicate field names detected: ${duplicates.join(', ')}`);
      }
    }

    // Check action conflicts
    if (payload.action) {
      const enabledActions = Object.entries(payload.action)
        .filter(([, enabled]) => enabled)
        .map(([action]) => action);

      if (enabledActions.length === 0) {
        result.warnings.push('No actions are enabled in the payload');
        result.recommendations.push('Consider enabling at least one action (datatables, add, update, delete, first, lookup, list)');
      }

      // Check for potentially dangerous combinations
      if (enabledActions.includes('delete') && !enabledActions.includes('first')) {
        result.warnings.push('Delete action enabled without first action');
        result.recommendations.push('Consider enabling first action for safer delete operations');
      }
    }

    return result;
  }

  /**
   * Comprehensive conflict check untuk semua aspek
   * @param {string} moduleName - Nama module
   * @param {string} endpointName - Nama endpoint
   * @param {Object} payload - Payload object (optional)
   * @returns {Object} Comprehensive conflict report
   */
  static comprehensiveConflictCheck(moduleName, endpointName, payload = null) {
    const report = {
      overall: {
        hasConflicts: false,
        riskLevel: 'low',
        canProceed: true
      },
      module: this.validateModuleName(moduleName),
      endpoint: endpointName ? this.validateEndpointName(endpointName) : null,
      files: endpointName ? this.detectConflicts(moduleName, endpointName) : null,
      payload: payload ? this.checkPayloadConflicts(payload, moduleName, endpointName) : null,
      recommendations: []
    };

    // Assess overall risk
    let riskScore = 0;
    let hasBlockingErrors = false;

    // Module validation
    if (!report.module.isValid) {
      hasBlockingErrors = true;
      riskScore += 10;
    } else if (report.module.warnings.length > 0) {
      riskScore += 2;
    }

    // Endpoint validation
    if (report.endpoint && !report.endpoint.isValid) {
      hasBlockingErrors = true;
      riskScore += 10;
    } else if (report.endpoint && report.endpoint.warnings.length > 0) {
      riskScore += 2;
    }

    // File conflicts
    if (report.files && report.files.hasConflicts) {
      riskScore += report.files.fileConflicts.length * 2;
      riskScore += report.files.systemConflicts.length * 3;
    }

    // Payload conflicts
    if (report.payload && report.payload.hasConflicts) {
      hasBlockingErrors = true;
      riskScore += 5;
    } else if (report.payload && report.payload.warnings.length > 0) {
      riskScore += 1;
    }

    // Determine overall status
    report.overall.hasConflicts = riskScore > 0;
    report.overall.canProceed = !hasBlockingErrors;

    if (riskScore >= 10 || hasBlockingErrors) {
      report.overall.riskLevel = 'high';
    } else if (riskScore >= 5) {
      report.overall.riskLevel = 'medium';
    } else {
      report.overall.riskLevel = 'low';
    }

    // Collect all recommendations
    if (report.module.recommendations) {
      report.recommendations.push(...report.module.recommendations);
    }
    if (report.endpoint && report.endpoint.recommendations) {
      report.recommendations.push(...report.endpoint.recommendations);
    }
    if (report.payload && report.payload.recommendations) {
      report.recommendations.push(...report.payload.recommendations);
    }

    return report;
  }

  /**
   * Show comprehensive conflict report
   * @param {Object} report - Comprehensive conflict report
   */
  static showComprehensiveReport(report) {
    const { overall, module, endpoint, files, payload } = report;

    console.log(`\nCOMPREHENSIVE CONFLICT CHECK REPORT`);
    console.log(`Overall Risk Level: ${overall.riskLevel.toUpperCase()}`);
    console.log(`Can Proceed: ${overall.canProceed ? 'YES' : 'NO'}`);

    // Module validation
    console.log(`\nModule Validation:`);
    if (module.isValid) {
      console.log(`   Module name is valid`);
    } else {
      console.log(`   Module validation failed:`);
      module.errors.forEach(error => console.log(`      - ${error}`));
    }
    
    if (module.warnings.length > 0) {
      console.log(`   Warnings:`);
      module.warnings.forEach(warning => console.log(`      - ${warning}`));
    }

    // Endpoint validation
    if (endpoint) {
      console.log(`\nEndpoint Validation:`);
      if (endpoint.isValid) {
        console.log(`   Endpoint name is valid`);
      } else {
        console.log(`   Endpoint validation failed:`);
        endpoint.errors.forEach(error => console.log(`      - ${error}`));
      }
      
      if (endpoint.warnings.length > 0) {
        console.log(`   Warnings:`);
        endpoint.warnings.forEach(warning => console.log(`      - ${warning}`));
      }
    }

    // File conflicts
    if (files && files.hasConflicts) {
      console.log(`\nFile Conflicts:`);
      console.log(`   Found ${files.fileConflicts.length} file conflicts`);
      console.log(`   Found ${files.systemConflicts.length} system conflicts`);
    }

    // Payload conflicts
    if (payload) {
      console.log(`\nPayload Validation:`);
      if (payload.hasConflicts) {
        console.log(`   Payload validation failed:`);
        payload.errors.forEach(error => console.log(`      - ${error}`));
      } else {
        console.log(`   Payload validation passed`);
      }
      
      if (payload.warnings.length > 0) {
        console.log(`   Warnings:`);
        payload.warnings.forEach(warning => console.log(`      - ${warning}`));
      }
    }

    // Recommendations
    if (report.recommendations.length > 0) {
      console.log(`\n💡 Recommendations:`);
      report.recommendations.forEach(rec => console.log(`   - ${rec}`));
    }

    console.log(''); // Empty line for spacing
  }
}

module.exports = ConflictChecker;