/**
 * Data Validation Utilities
 * Validates integrity of genres, instruments, and game data
 */

import { genres } from '../data/genres';
import { instruments, materials } from '../data/instruments';

export class DataValidator {
  /**
   * Validate all genres have required properties
   */
  static validateGenres() {
    const errors = [];
    const warnings = [];

    genres.forEach((genre, index) => {
      // Required fields
      if (!genre.id) errors.push(`Genre at index ${index} missing id`);
      if (!genre.name) errors.push(`Genre ${genre.id} missing name`);
      if (!genre.category) errors.push(`Genre ${genre.id} missing category`);
      if (!genre.icon) warnings.push(`Genre ${genre.id} missing icon`);
      if (!genre.description) warnings.push(`Genre ${genre.id} missing description`);
      
      // Level benefits
      if (!genre.levelBenefits) {
        errors.push(`Genre ${genre.id} missing levelBenefits`);
      } else {
        // Check at least some level benefits exist
        const benefitLevels = Object.keys(genre.levelBenefits);
        if (benefitLevels.length === 0) {
          warnings.push(`Genre ${genre.id} has no level benefits`);
        }
      }

      // Skill tree validation
      if (!genre.skillTree || !Array.isArray(genre.skillTree)) {
        errors.push(`Genre ${genre.id} missing or invalid skillTree`);
      } else {
        genre.skillTree.forEach(skill => {
          if (!skill.id) errors.push(`Skill in ${genre.id} missing id`);
          if (!skill.name) errors.push(`Skill ${skill.id} in ${genre.id} missing name`);
          if (typeof skill.level !== 'number') {
            errors.push(`Skill ${skill.id} in ${genre.id} has invalid level`);
          }

          // Validate prerequisite exists
          if (skill.prerequisite) {
            const prereqExists = genre.skillTree.some(s => s.id === skill.prerequisite);
            if (!prereqExists) {
              errors.push(`Skill ${skill.id} in ${genre.id} has invalid prerequisite: ${skill.prerequisite}`);
            }
          }
        });
      }

      // XP requirements
      if (!genre.xpRequirements || genre.xpRequirements.length !== 10) {
        errors.push(`Genre ${genre.id} missing or invalid xpRequirements (should be length 10)`);
      }

      // Check for duplicate IDs
      const duplicates = genres.filter(g => g.id === genre.id);
      if (duplicates.length > 1) {
        errors.push(`Duplicate genre ID: ${genre.id}`);
      }
    });

    return { errors, warnings, valid: errors.length === 0 };
  }

  /**
   * Validate all instruments have required properties
   */
  static validateInstruments() {
    const errors = [];
    const warnings = [];

    instruments.forEach((instrument, index) => {
      // Required fields
      if (!instrument.id) errors.push(`Instrument at index ${index} missing id`);
      if (!instrument.name) errors.push(`Instrument ${instrument.id} missing name`);
      if (!instrument.type) errors.push(`Instrument ${instrument.id} missing type`);
      if (!instrument.rarity) errors.push(`Instrument ${instrument.id} missing rarity`);
      if (!instrument.stats) errors.push(`Instrument ${instrument.id} missing stats`);
      if (typeof instrument.requiredLevel !== 'number') {
        errors.push(`Instrument ${instrument.id} has invalid requiredLevel`);
      }

      // Validate crafting materials exist
      if (instrument.craftingMaterials) {
        instrument.craftingMaterials.forEach(material => {
          if (!materials[material.item]) {
            errors.push(`Instrument ${instrument.id} references unknown material: ${material.item}`);
          }
          if (typeof material.quantity !== 'number' || material.quantity <= 0) {
            errors.push(`Instrument ${instrument.id} has invalid material quantity`);
          }
        });
      }

      // Check for duplicate IDs
      const duplicates = instruments.filter(i => i.id === instrument.id);
      if (duplicates.length > 1) {
        errors.push(`Duplicate instrument ID: ${instrument.id}`);
      }

      // Validate stats object
      if (instrument.stats) {
        Object.entries(instrument.stats).forEach(([key, value]) => {
          if (typeof value !== 'number') {
            errors.push(`Instrument ${instrument.id} has non-numeric stat: ${key}`);
          }
        });
      }
    });

    return { errors, warnings, valid: errors.length === 0 };
  }

  /**
   * Validate all data
   */
  static validateAll() {
    const genreValidation = this.validateGenres();
    const instrumentValidation = this.validateInstruments();

    return {
      genres: genreValidation,
      instruments: instrumentValidation,
      allValid: genreValidation.valid && instrumentValidation.valid,
      totalErrors: genreValidation.errors.length + instrumentValidation.errors.length,
      totalWarnings: genreValidation.warnings.length + instrumentValidation.warnings.length
    };
  }

  /**
   * Print validation report
   */
  static printReport() {
    const results = this.validateAll();
    
    console.log('=== Data Validation Report ===\n');
    
    console.log(`📊 Genres: ${genres.length} total`);
    if (results.genres.errors.length > 0) {
      console.error('❌ Errors:', results.genres.errors);
    }
    if (results.genres.warnings.length > 0) {
      console.warn('⚠️  Warnings:', results.genres.warnings);
    }
    if (results.genres.valid) {
      console.log('✅ All genre validations passed');
    }
    
    console.log(`\n📊 Instruments: ${instruments.length} total`);
    if (results.instruments.errors.length > 0) {
      console.error('❌ Errors:', results.instruments.errors);
    }
    if (results.instruments.warnings.length > 0) {
      console.warn('⚠️  Warnings:', results.instruments.warnings);
    }
    if (results.instruments.valid) {
      console.log('✅ All instrument validations passed');
    }
    
    console.log(`\n📈 Summary:`);
    console.log(`   Total Errors: ${results.totalErrors}`);
    console.log(`   Total Warnings: ${results.totalWarnings}`);
    console.log(`   Overall Status: ${results.allValid ? '✅ PASS' : '❌ FAIL'}`);
    
    return results;
  }
}

