/**
 * Test Script for Special Items RM API Support
 * Tests the complete workflow: Product → GRN → BOM → Production
 */

const axios = require('axios');

const BASE_URL = process.env.API_BASE_URL || 'http://localhost:4000/api';
let authToken = null;

// Test data
let specialItemProductId = null;
let dimensionBasedProductId = null;
let fgProductId = null;
let fgVariantId = null;
let grnId = null;
let bomId = null;
let productionOrderId = null;

// Helper function to make API requests
async function apiRequest(method, endpoint, data = null, token = null) {
  try {
    const config = {
      method,
      url: `${BASE_URL}${endpoint}`,
      headers: {
        'Content-Type': 'application/json',
      },
    };

    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    if (data) {
      config.data = data;
    }

    const response = await axios(config);
    return { success: true, data: response.data, status: response.status };
  } catch (error) {
    return {
      success: false,
      error: error.response?.data || error.message,
      status: error.response?.status,
    };
  }
}

// Test 1: Login
async function testLogin() {
  console.log('\n=== Test 1: Login ===');
  const result = await apiRequest('POST', '/auth/login', {
    username: 'admin',
    password: 'admin123',
  });

  if (result.success && result.data?.data?.token) {
    authToken = result.data.data.token;
    console.log('✅ Login successful');
    return true;
  } else {
    console.log('❌ Login failed:', result.error);
    return false;
  }
}

// Test 2: Create Special Items RM Product (Zipper)
async function testCreateSpecialItemsRMProduct() {
  console.log('\n=== Test 2: Create Special Items RM Product (Zipper) ===');
  const timestamp = Date.now();
  const productData = {
    name: `Test Zipper ${timestamp}`,
    sku: `ZIP-TEST-${timestamp}`,
    product_type: 'RM',
    track_by_dimensions: false, // Special items RM
    track_inventory: true,
    description: 'Metal zipper for garments',
  };

  const result = await apiRequest('POST', '/products', productData, authToken);

  if (result.success && result.data?.data?.product?.id) {
    specialItemProductId = result.data.data.product.id;
    console.log('✅ Special items RM product created:', specialItemProductId);
    console.log('   Product:', result.data.data.product.name);
    console.log('   track_by_dimensions:', result.data.data.product.track_by_dimensions);
    return true;
  } else {
    console.log('❌ Failed to create special items RM product:', JSON.stringify(result.error, null, 2));
    return false;
  }
}

// Test 3: Create Dimension-Based RM Product (Fabric)
async function testCreateDimensionBasedRMProduct() {
  console.log('\n=== Test 3: Create Dimension-Based RM Product (Fabric) ===');
  const timestamp = Date.now();
  const productData = {
    name: `Test Cotton Fabric ${timestamp}`,
    sku: `FAB-COTTON-${timestamp}`,
    product_type: 'RM',
    track_by_dimensions: true, // Dimension-based RM
    unit_of_measure: 'm',
    track_inventory: true,
    description: 'Cotton fabric for garments',
  };

  const result = await apiRequest('POST', '/products', productData, authToken);

  if (result.success && result.data?.data?.product?.id) {
    dimensionBasedProductId = result.data.data.product.id;
    console.log('✅ Dimension-based RM product created:', dimensionBasedProductId);
    console.log('   Product:', result.data.data.product.name);
    console.log('   track_by_dimensions:', result.data.data.product.track_by_dimensions);
    console.log('   unit_of_measure:', result.data.data.product.unit_of_measure);
    return true;
  } else {
    console.log('❌ Failed to create dimension-based RM product:', JSON.stringify(result.error, null, 2));
    return false;
  }
}

// Test 4: Create Finished Good Product
async function testCreateFGProduct() {
  console.log('\n=== Test 4: Create Finished Good Product ===');
  const timestamp = Date.now();
  const productData = {
    name: `Test Garment ${timestamp}`,
    sku: `GAR-TEST-${timestamp}`,
    product_type: 'FG',
    track_inventory: true,
    selling_price: 100,
  };

  const result = await apiRequest('POST', '/products', productData, authToken);

  if (result.success && result.data?.data?.product?.id) {
    fgProductId = result.data.data.product.id;
    console.log('✅ Finished good product created:', fgProductId);

    // Create variant
    const variantData = {
      sku: `GAR-TEST-${timestamp}-S`,
      attributes: { size: 'S', color: 'Blue' },
    };

    const variantResult = await apiRequest('POST', `/products/${fgProductId}/variants`, variantData, authToken);
    if (variantResult.success && variantResult.data?.data?.variant?.id) {
      fgVariantId = variantResult.data.data.variant.id;
      console.log('✅ Variant created:', fgVariantId);
      return true;
    } else {
      console.log('❌ Failed to create variant:', JSON.stringify(variantResult.error, null, 2));
      return false;
    }
  } else {
    console.log('❌ Failed to create FG product:', JSON.stringify(result.error, null, 2));
    return false;
  }
}

// Test 5: Create GRN with Special Items RM (no dimensions)
async function testCreateGRNWithSpecialItemsRM() {
  console.log('\n=== Test 5: Create GRN with Special Items RM ===');
  const grnData = {
    received_at: new Date().toISOString(),
    items: [
      {
        product_id: specialItemProductId,
        quantity: 100, // Just quantity, no dimensions
        unit_cost: 2.5,
      },
    ],
  };

  const result = await apiRequest('POST', '/procurement/grns', grnData, authToken);

  if (result.success && result.data?.data?.id) {
    grnId = result.data.data.id;
    console.log('✅ GRN created with special items RM:', grnId);
    console.log('   Items:', result.data.data.items?.length || 0);
    return true;
  } else {
    console.log('❌ Failed to create GRN:', result.error);
    return false;
  }
}

// Test 6: Process GRN with Special Items RM
async function testProcessGRNWithSpecialItemsRM() {
  console.log('\n=== Test 6: Process GRN with Special Items RM ===');
  const result = await apiRequest('POST', `/procurement/grns/${grnId}/process`, {}, authToken);

  if (result.success) {
    console.log('✅ GRN processed successfully');
    console.log('   Processing result:', JSON.stringify(result.data, null, 2));
    return true;
  } else {
    console.log('❌ Failed to process GRN:', result.error);
    return false;
  }
}

// Test 7: Check Inventory for Special Items RM
async function testCheckSpecialItemsRMInventory() {
  console.log('\n=== Test 7: Check Inventory for Special Items RM ===');
  const result = await apiRequest('GET', `/inventory/${specialItemProductId}`, null, authToken);

  if (result.success) {
    console.log('✅ Inventory checked');
    console.log('   Inventory data:', JSON.stringify(result.data, null, 2));
    return true;
  } else {
    console.log('❌ Failed to check inventory:', result.error);
    return false;
  }
}

// Test 8: Create BOM with Special Items RM
async function testCreateBOMWithSpecialItemsRM() {
  console.log('\n=== Test 8: Create BOM with Special Items RM ===');
  const bomData = {
    fg_variant_id: fgVariantId,
    items: [
      {
        rm_product_id: specialItemProductId,
        quantity_per_unit: 1, // Quantity-based (not dimensions)
        use_dimensions: false, // Special items RM
      },
    ],
  };

  const result = await apiRequest('POST', '/production/boms', bomData, authToken);

  if (result.success && result.data?.data?.id) {
    bomId = result.data.data.id;
    console.log('✅ BOM created with special items RM:', bomId);
    console.log('   BOM items:', result.data.data.items?.length || 0);
    return true;
  } else {
    console.log('❌ Failed to create BOM:', result.error);
    console.log('   Error details:', JSON.stringify(result.error, null, 2));
    return false;
  }
}

// Test 9: Create Production Order
async function testCreateProductionOrder() {
  console.log('\n=== Test 9: Create Production Order ===');
  const poData = {
    fg_variant_id: fgVariantId,
    quantity: 10,
    notes: 'Test production order with special items RM',
  };

  const result = await apiRequest('POST', '/production/orders', poData, authToken);

  if (result.success && result.data?.data?.id) {
    productionOrderId = result.data.data.id;
    console.log('✅ Production order created:', productionOrderId);
    return true;
  } else {
    console.log('❌ Failed to create production order:', result.error);
    return false;
  }
}

// Test 10: Check Production Order Availability
async function testCheckProductionAvailability() {
  console.log('\n=== Test 10: Check Production Order Availability ===');
  const result = await apiRequest('GET', `/production/orders/${productionOrderId}/check-availability`, null, authToken);

  if (result.success) {
    console.log('✅ Availability checked');
    console.log('   Availability data:', JSON.stringify(result.data, null, 2));
    return true;
  } else {
    console.log('❌ Failed to check availability:', result.error);
    return false;
  }
}

// Test 11: Confirm Production (if materials available)
async function testConfirmProduction() {
  console.log('\n=== Test 11: Confirm Production ===');
  const result = await apiRequest('POST', `/production/orders/${productionOrderId}/confirm`, {}, authToken);

  if (result.success) {
    console.log('✅ Production confirmed');
    console.log('   Confirmation result:', JSON.stringify(result.data, null, 2));
    return true;
  } else {
    console.log('❌ Failed to confirm production:', result.error);
    console.log('   Error details:', JSON.stringify(result.error, null, 2));
    return false;
  }
}

// Main test runner
async function runTests() {
  console.log('🚀 Starting Special Items RM API Tests\n');
  console.log('Base URL:', BASE_URL);

  const tests = [
    { name: 'Login', fn: testLogin },
    { name: 'Create Special Items RM Product', fn: testCreateSpecialItemsRMProduct },
    { name: 'Create Dimension-Based RM Product', fn: testCreateDimensionBasedRMProduct },
    { name: 'Create FG Product', fn: testCreateFGProduct },
    { name: 'Create GRN with Special Items RM', fn: testCreateGRNWithSpecialItemsRM },
    { name: 'Process GRN with Special Items RM', fn: testProcessGRNWithSpecialItemsRM },
    { name: 'Check Special Items RM Inventory', fn: testCheckSpecialItemsRMInventory },
    { name: 'Create BOM with Special Items RM', fn: testCreateBOMWithSpecialItemsRM },
    { name: 'Create Production Order', fn: testCreateProductionOrder },
    { name: 'Check Production Availability', fn: testCheckProductionAvailability },
    { name: 'Confirm Production', fn: testConfirmProduction },
  ];

  let passed = 0;
  let failed = 0;

  for (const test of tests) {
    try {
      const result = await test.fn();
      if (result) {
        passed++;
      } else {
        failed++;
        console.log(`\n⚠️  Test "${test.name}" failed - continuing with remaining tests...\n`);
      }
    } catch (error) {
      failed++;
      console.log(`\n❌ Test "${test.name}" threw an error:`, error.message);
      console.log('   Stack:', error.stack);
      console.log('\n⚠️  Continuing with remaining tests...\n');
    }
  }

  console.log('\n' + '='.repeat(50));
  console.log('📊 Test Summary');
  console.log('='.repeat(50));
  console.log(`✅ Passed: ${passed}`);
  console.log(`❌ Failed: ${failed}`);
  console.log(`📈 Total: ${tests.length}`);
  console.log(`🎯 Success Rate: ${((passed / tests.length) * 100).toFixed(1)}%`);
  console.log('='.repeat(50));

  if (failed === 0) {
    console.log('\n🎉 All tests passed!');
    process.exit(0);
  } else {
    console.log('\n⚠️  Some tests failed. Please review the output above.');
    process.exit(1);
  }
}

// Run tests
if (require.main === module) {
  runTests().catch((error) => {
    console.error('❌ Test runner error:', error);
    process.exit(1);
  });
}

module.exports = { runTests };
