/**
 * API Endpoints Integration Test
 * Tests the new dimension-based API endpoints
 */

const { RMInventoryPiece, Product, BOM, BOMItem, ProductionOrder, ProductVariant } = require('./models');
const inventoryCalculationService = require('./services/inventoryCalculationService');
const materialUtilizationService = require('./services/materialUtilizationService');
const productionOrderService = require('./modules/production/services/productionOrders');
const bomDimensionService = require('./services/bomDimensionService');

/**
 * Test RM Inventory API endpoints functionality
 */
async function testRMInventoryAPIs() {
  console.log('\n=== Testing RM Inventory API Endpoints ===');
  
  try {
    // Test 1: Create test RM product
    const rmProduct = await Product.create({
      name: 'Cotton Fabric Test',
      sku: 'CF-TEST-001',
      product_type: 'RM',
      track_by_dimensions: true,
      unit_of_measure: 'm',
      sell_on_pos: false
    });
    
    console.log('✓ Created test RM product:', rmProduct.id);
    
    // Test 2: Create test RM inventory pieces
    const testPieces = [
      {
        product_id: rmProduct.id,
        piece_number: 1,
        length: 6.0,
        width: 4.0,
        unit: 'm',
        status: 'FULL',
        cost_per_area: 15.50
        // FULL pieces should not have usable dimensions set
      },
      {
        product_id: rmProduct.id,
        piece_number: 2,
        length: 3.0,
        width: 2.0,
        unit: 'm',
        status: 'USABLE',
        usable_length: 2.5,
        usable_width: 1.8,
        cost_per_area: 15.50
      },
      {
        product_id: rmProduct.id,
        piece_number: 3,
        length: 1.5,
        width: 1.0,
        unit: 'm',
        status: 'WASTE',
        usable_length: 1.5,
        usable_width: 1.0,
        cost_per_area: 15.50
      }
    ];
    
    const createdPieces = [];
    for (const pieceData of testPieces) {
      const piece = await RMInventoryPiece.create(pieceData);
      createdPieces.push(piece);
    }
    
    console.log('✓ Created test RM inventory pieces:', createdPieces.length);
    
    // Test 3: Test inventory calculation service
    const summaryResult = inventoryCalculationService.calculateInventorySummary(createdPieces, {
      targetUnit: 'm',
      groupByStatus: true,
      includeUtilizationMetrics: true
    });
    
    if (summaryResult.isValid) {
      console.log('✓ Inventory summary calculation successful');
      console.log('  - Total pieces:', summaryResult.summary.totalPieces);
      console.log('  - Total area:', summaryResult.summary.totalArea.toFixed(2), 'm²');
      console.log('  - Status breakdown:', Object.keys(summaryResult.summary.statusBreakdown));
    } else {
      console.log('✗ Inventory summary calculation failed:', summaryResult.error);
    }
    
    // Test 4: Test material utilization service
    const utilizationResult = materialUtilizationService.calculateUtilizationStatistics(createdPieces, {
      timeRange: { days: 30 },
      includeWasteAnalysis: true
    });
    
    if (utilizationResult.isValid) {
      console.log('✓ Material utilization calculation successful');
      console.log('  - Efficiency score:', utilizationResult.statistics.efficiencyScore?.toFixed(2) || 'N/A');
    } else {
      console.log('✗ Material utilization calculation failed:', utilizationResult.error);
    }
    
    // Test 5: Test piece filtering (simulating API query filters)
    const fullPieces = createdPieces.filter(p => p.status === 'FULL');
    const wastePieces = createdPieces.filter(p => p.status === 'WASTE');
    
    console.log('✓ Piece filtering works:');
    console.log('  - FULL pieces:', fullPieces.length);
    console.log('  - WASTE pieces:', wastePieces.length);
    
    return {
      success: true,
      rmProduct: rmProduct,
      pieces: createdPieces
    };
    
  } catch (error) {
    console.log('✗ RM Inventory API test failed:', error.message);
    return { success: false, error: error.message };
  }
}

/**
 * Test Production Order API endpoints functionality
 */
async function testProductionOrderAPIs() {
  console.log('\n=== Testing Production Order API Endpoints ===');
  
  try {
    // Test 1: Create test FG product and variant
    const fgProduct = await Product.create({
      name: 'Test Shirt',
      sku: 'SHIRT-TEST-001',
      product_type: 'FG',
      track_inventory: true,
      sell_on_pos: true
    });
    
    const fgVariant = await ProductVariant.create({
      product_id: fgProduct.id,
      name: 'Medium Blue',
      sku: 'SHIRT-TEST-001-M-BLUE',
      attributes: {} // Add empty attributes object to satisfy notNull constraint
    });
    
    console.log('✓ Created test FG product and variant:', fgProduct.id, fgVariant.id);
    
    // Test 2: Create test RM product for BOM
    const rmProduct = await Product.create({
      name: 'Cotton Fabric BOM Test',
      sku: 'CF-BOM-TEST-001',
      product_type: 'RM',
      track_by_dimensions: true,
      unit_of_measure: 'm',
      sell_on_pos: false
    });
    
    // Test 3: Create BOM with dimension requirements
    const bom = await BOM.create({
      fg_variant_id: fgVariant.id
    });
    
    const bomItem = await BOMItem.create({
      bom_id: bom.id,
      rm_product_id: rmProduct.id,
      use_dimensions: true,
      required_length: 2.0,
      required_width: 1.5,
      dimension_unit: 'm'
    });
    
    console.log('✓ Created test BOM with dimension requirements:', bom.id);
    
    // Test 4: Create production order
    const productionOrder = await ProductionOrder.create({
      fg_variant_id: fgVariant.id,
      quantity: 5,
      status: 'DRAFT'
    });
    
    console.log('✓ Created test production order:', productionOrder.id);
    
    // Test 5: Test BOM dimension validation
    const dimensionValidation = bomDimensionService.validateBOMItemDimensions(bomItem, rmProduct);
    
    if (dimensionValidation.isValid) {
      console.log('✓ BOM dimension validation successful');
      console.log('  - Uses dimensions:', dimensionValidation.useDimensions);
      console.log('  - Required dimensions:', dimensionValidation.dimensions);
    } else {
      console.log('✗ BOM dimension validation failed:', dimensionValidation.error);
    }
    
    // Test 6: Test dimension requirements calculation
    const dimensionReq = bomDimensionService.calculateDimensionRequirements(bomItem, productionOrder.quantity);
    
    if (dimensionReq.isValid) {
      console.log('✓ Dimension requirements calculation successful');
      console.log('  - Area per unit:', dimensionReq.areaPerUnit, 'm²');
      console.log('  - Total area required:', dimensionReq.totalAreaRequired, 'm²');
    } else {
      console.log('✗ Dimension requirements calculation failed:', dimensionReq.error);
    }
    
    // Test 7: Test production optimization suggestions (mock)
    try {
      const suggestions = await productionOrderService.getProductionOptimizationSuggestions(productionOrder.id, {
        maxSuggestions: 3,
        includeWasteAnalysis: true
      });
      
      console.log('✓ Production optimization suggestions successful');
      console.log('  - Current quantity:', suggestions.current_quantity);
      console.log('  - Suggestions count:', suggestions.suggestions.length);
      console.log('  - Best efficiency score:', suggestions.analysis.bestEfficiencyScore?.toFixed(2) || 'N/A');
    } catch (error) {
      console.log('✗ Production optimization suggestions failed:', error.message);
    }
    
    // Test 8: Test waste piece suggestions (mock)
    try {
      const wasteSuggestions = await productionOrderService.getWastePieceSuggestions(productionOrder.id);
      
      console.log('✓ Waste piece suggestions successful');
      console.log('  - Production quantity:', wasteSuggestions.production_quantity);
      console.log('  - Suggestions count:', wasteSuggestions.suggestions.length);
      console.log('  - Total waste pieces available:', wasteSuggestions.summary.total_waste_pieces_available);
    } catch (error) {
      console.log('✗ Waste piece suggestions failed:', error.message);
    }
    
    return {
      success: true,
      productionOrder: productionOrder,
      bom: bom,
      bomItem: bomItem
    };
    
  } catch (error) {
    console.log('✗ Production Order API test failed:', error.message);
    return { success: false, error: error.message };
  }
}

/**
 * Test API endpoint validation logic
 */
async function testAPIValidation() {
  console.log('\n=== Testing API Validation Logic ===');
  
  try {
    // Test 1: Validate dimension fields
    const validDimensions = {
      piece_length: 2.5,
      piece_width: 1.8,
      dimension_unit: 'm',
      pieces_count: 3
    };
    
    // Simulate validation logic
    const isValidLength = validDimensions.piece_length > 0;
    const isValidWidth = validDimensions.piece_width > 0;
    const isValidUnit = ['inch', 'cm', 'm'].includes(validDimensions.dimension_unit);
    const isValidCount = validDimensions.pieces_count > 0;
    
    if (isValidLength && isValidWidth && isValidUnit && isValidCount) {
      console.log('✓ Dimension validation logic works correctly');
    } else {
      console.log('✗ Dimension validation logic failed');
    }
    
    // Test 2: Validate BOM dimension requirements
    const validBOMItem = {
      rm_product_id: 1,
      use_dimensions: true,
      required_length: 2.0,
      required_width: 1.5,
      dimension_unit: 'm'
    };
    
    const hasRequiredFields = validBOMItem.rm_product_id && 
                             validBOMItem.required_length && 
                             validBOMItem.required_width && 
                             validBOMItem.dimension_unit;
    
    if (hasRequiredFields) {
      console.log('✓ BOM dimension validation logic works correctly');
    } else {
      console.log('✗ BOM dimension validation logic failed');
    }
    
    // Test 3: Validate write-off request
    const validWriteOffRequest = {
      piece_ids: [1, 2, 3],
      reason: 'Damaged during handling',
      notes: 'Material became unusable due to water damage'
    };
    
    const hasValidPieceIds = Array.isArray(validWriteOffRequest.piece_ids) && 
                            validWriteOffRequest.piece_ids.length > 0;
    const hasValidReason = validWriteOffRequest.reason && 
                          validWriteOffRequest.reason.length >= 3;
    
    if (hasValidPieceIds && hasValidReason) {
      console.log('✓ Write-off validation logic works correctly');
    } else {
      console.log('✗ Write-off validation logic failed');
    }
    
    return { success: true };
    
  } catch (error) {
    console.log('✗ API validation test failed:', error.message);
    return { success: false, error: error.message };
  }
}

/**
 * Main test runner
 */
async function runAPIEndpointsTest() {
  console.log('🚀 Starting API Endpoints Integration Test');
  console.log('Testing new dimension-based API endpoints and validation logic...\n');
  
  const results = {
    rmInventoryAPIs: await testRMInventoryAPIs(),
    productionOrderAPIs: await testProductionOrderAPIs(),
    apiValidation: await testAPIValidation()
  };
  
  // Summary
  console.log('\n=== Test Summary ===');
  const totalTests = Object.keys(results).length;
  const passedTests = Object.values(results).filter(r => r.success).length;
  
  console.log(`Total test suites: ${totalTests}`);
  console.log(`Passed: ${passedTests}`);
  console.log(`Failed: ${totalTests - passedTests}`);
  
  if (passedTests === totalTests) {
    console.log('🎉 All API endpoint tests passed!');
  } else {
    console.log('❌ Some API endpoint tests failed');
    
    // Show failed tests
    Object.entries(results).forEach(([testName, result]) => {
      if (!result.success) {
        console.log(`  - ${testName}: ${result.error}`);
      }
    });
  }
  
  return results;
}

// Run the test if this file is executed directly
if (require.main === module) {
  runAPIEndpointsTest()
    .then(() => {
      console.log('\n✅ API Endpoints Integration Test completed');
      process.exit(0);
    })
    .catch((error) => {
      console.error('\n❌ API Endpoints Integration Test failed:', error);
      process.exit(1);
    });
}

module.exports = {
  runAPIEndpointsTest,
  testRMInventoryAPIs,
  testProductionOrderAPIs,
  testAPIValidation
};