/**
 * CSV Rate API Test Script (Node.js)
 *
 * Usage: node test-csv-api.js
 *
 * Tests all CSV rate endpoints and verifies comparator functionality
 */

const API_URL = 'http://localhost:4000';

// Color codes for terminal output
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
};

function printTest(number, description) {
  console.log(`${colors.yellow}[TEST ${number}] ${description}${colors.reset}`);
}

function printSuccess(message) {
  console.log(`${colors.green}✓ ${message}${colors.reset}`);
}

function printError(message) {
  console.log(`${colors.red}✗ ${message}${colors.reset}`);
}

function printInfo(message) {
  console.log(`${colors.blue}→ ${message}${colors.reset}`);
}

async function authenticateUser() {
  printTest(1, 'Authenticating as regular user');

  const response = await fetch(`${API_URL}/api/v1/auth/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: 'test4@xpeditis.com',
      password: 'SecurePassword123',
    }),
  });

  const data = await response.json();

  if (data.accessToken) {
    printSuccess('Regular user authenticated');
    printInfo(`Token: ${data.accessToken.substring(0, 20)}...`);
    return data.accessToken;
  } else {
    printError('Failed to authenticate regular user');
    console.log('Response:', data);
    throw new Error('Authentication failed');
  }
}

async function testGetCompanies(token) {
  printTest(2, 'GET /rates/companies - Get available companies');

  const response = await fetch(`${API_URL}/api/v1/rates/companies`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  const data = await response.json();
  console.log(JSON.stringify(data, null, 2));

  if (data.total === 5) {
    printSuccess('Got 5 companies (including Test Maritime Express)');
    printInfo(`Companies: ${data.companies.join(', ')}`);
  } else {
    printError(`Expected 5 companies, got ${data.total}`);
  }

  console.log('');
  return data;
}

async function testGetFilterOptions(token) {
  printTest(3, 'GET /rates/filters/options - Get filter options');

  const response = await fetch(`${API_URL}/api/v1/rates/filters/options`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  const data = await response.json();
  console.log(JSON.stringify(data, null, 2));
  printSuccess('Filter options retrieved');

  console.log('');
  return data;
}

async function testBasicSearch(token) {
  printTest(4, 'POST /rates/search-csv - Basic rate search (NLRTM → USNYC)');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25.5,
      weightKG: 3500,
      palletCount: 10,
      containerType: 'LCL',
    }),
  });

  const data = await response.json();
  console.log(JSON.stringify(data, null, 2));

  printInfo(`Total results: ${data.totalResults}`);

  // Check if Test Maritime Express is in results
  const hasTestMaritime = data.results.some(r => r.companyName === 'Test Maritime Express');
  if (hasTestMaritime) {
    printSuccess('Test Maritime Express found in results');
    const testPrice = data.results.find(r => r.companyName === 'Test Maritime Express').totalPrice
      .amount;
    printInfo(`Test Maritime Express price: $${testPrice}`);
  } else {
    printError('Test Maritime Express NOT found in results');
  }

  // Count unique companies
  const uniqueCompanies = [...new Set(data.results.map(r => r.companyName))];
  printInfo(`Results from ${uniqueCompanies.length} different companies`);

  if (uniqueCompanies.length >= 3) {
    printSuccess('Multiple companies in comparator ✓');
  } else {
    printError(`Expected multiple companies, got ${uniqueCompanies.length}`);
  }

  console.log('');
  return data;
}

async function testCompanyFilter(token) {
  printTest(5, 'POST /rates/search-csv - Filter by Test Maritime Express only');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25.5,
      weightKG: 3500,
      palletCount: 10,
      containerType: 'LCL',
      filters: {
        companies: ['Test Maritime Express'],
      },
    }),
  });

  const data = await response.json();
  console.log(JSON.stringify(data.results.slice(0, 3), null, 2));

  const uniqueCompanies = [...new Set(data.results.map(r => r.companyName))];
  if (uniqueCompanies.length === 1 && uniqueCompanies[0] === 'Test Maritime Express') {
    printSuccess('Company filter working correctly');
  } else {
    printError(`Company filter not working - got: ${uniqueCompanies.join(', ')}`);
  }

  console.log('');
  return data;
}

async function testPriceFilter(token) {
  printTest(6, 'POST /rates/search-csv - Filter by price range ($900-$1200)');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25.5,
      weightKG: 3500,
      palletCount: 10,
      containerType: 'LCL',
      filters: {
        minPrice: 900,
        maxPrice: 1200,
        currency: 'USD',
      },
    }),
  });

  const data = await response.json();
  printInfo(`Results in price range $900-$1200: ${data.totalResults}`);

  const prices = data.results.map(r => r.totalPrice.amount);
  const minPrice = Math.min(...prices);
  const maxPrice = Math.max(...prices);

  if (minPrice >= 900 && maxPrice <= 1200) {
    printSuccess(`Price filter working correctly (range: $${minPrice} - $${maxPrice})`);
  } else {
    printError(`Price filter not working - got range: $${minPrice} - $${maxPrice}`);
  }

  console.log('');
  return data;
}

async function testTransitFilter(token) {
  printTest(7, 'POST /rates/search-csv - Filter by max transit days (≤23 days)');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25.5,
      weightKG: 3500,
      containerType: 'LCL',
      filters: {
        maxTransitDays: 23,
      },
    }),
  });

  const data = await response.json();
  printInfo(`Results with transit ≤23 days: ${data.totalResults}`);

  const maxTransit = Math.max(...data.results.map(r => r.transitDays));
  if (maxTransit <= 23) {
    printSuccess(`Transit filter working correctly (max: ${maxTransit} days)`);
  } else {
    printError(`Transit filter not working - max transit: ${maxTransit} days`);
  }

  console.log('');
  return data;
}

async function testSurchargeFilter(token) {
  printTest(8, 'POST /rates/search-csv - Filter for rates without surcharges (all-in prices)');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25.5,
      weightKG: 3500,
      containerType: 'LCL',
      filters: {
        withoutSurcharges: true,
      },
    }),
  });

  const data = await response.json();
  printInfo(`Results without surcharges: ${data.totalResults}`);

  const withSurcharges = data.results.filter(r => r.hasSurcharges).length;
  if (withSurcharges === 0) {
    printSuccess('Surcharge filter working correctly');
  } else {
    printError(`Surcharge filter not working - found ${withSurcharges} results with surcharges`);
  }

  console.log('');
  return data;
}

async function testComparator(token) {
  printTest(9, 'COMPARATOR TEST - Show all 5 companies for NLRTM → USNYC');

  const response = await fetch(`${API_URL}/api/v1/rates/search-csv`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      origin: 'NLRTM',
      destination: 'USNYC',
      volumeCBM: 25,
      weightKG: 3500,
      palletCount: 10,
      containerType: 'LCL',
    }),
  });

  const data = await response.json();

  console.log('\nCompany Comparison Table:');
  console.log('=========================');

  data.results.slice(0, 10).forEach(result => {
    console.log(
      `${result.companyName}: $${result.totalPrice.amount} ${result.totalPrice.currency} - ${result.transitDays} days - Match: ${result.matchScore}%`
    );
  });

  const uniqueCompanies = [...new Set(data.results.map(r => r.companyName))];
  printInfo('Companies in results:');
  uniqueCompanies.forEach(company => console.log(`  - ${company}`));

  // Check if Test Maritime Express has lowest price
  const sortedByPrice = [...data.results].sort((a, b) => a.totalPrice.amount - b.totalPrice.amount);
  const lowestPriceCompany = sortedByPrice[0].companyName;
  const lowestPrice = sortedByPrice[0].totalPrice.amount;

  if (lowestPriceCompany === 'Test Maritime Express') {
    printSuccess('Test Maritime Express has the lowest price ✓');
    printInfo(`Lowest price: $${lowestPrice} (Test Maritime Express)`);
  } else {
    printError(
      `Expected Test Maritime Express to have lowest price, but got: ${lowestPriceCompany}`
    );
  }

  console.log('');
  return data;
}

async function runTests() {
  console.log(`${colors.blue}========================================${colors.reset}`);
  console.log(`${colors.blue}CSV Rate API Test Script${colors.reset}`);
  console.log(`${colors.blue}========================================${colors.reset}`);
  console.log('');

  try {
    // Authenticate
    const token = await authenticateUser();
    console.log('');

    // Run all tests
    await testGetCompanies(token);
    await testGetFilterOptions(token);
    await testBasicSearch(token);
    await testCompanyFilter(token);
    await testPriceFilter(token);
    await testTransitFilter(token);
    await testSurchargeFilter(token);
    await testComparator(token);

    console.log(`${colors.blue}========================================${colors.reset}`);
    console.log(`${colors.green}✓ All public endpoint tests completed!${colors.reset}`);
    console.log(`${colors.blue}========================================${colors.reset}`);
    console.log('');
    console.log('Next steps:');
    console.log('1. Run admin tests with an admin account');
    console.log('2. Test CSV upload functionality');
    console.log('3. Test CSV validation endpoint');
  } catch (error) {
    printError(`Test failed: ${error.message}`);
    console.error(error);
    process.exit(1);
  }
}

// Run tests
runTests();
