'use strict';
const { searchFlights } = require('../services/unifiedFlightService');

const VALID_TRIP_TYPES = ['oneWay', 'roundTrip', 'multiCity'];
const VALID_PASSENGER_TYPES = ['ADT', 'CNN', 'INF'];
const VALID_CABIN_CLASSES = ['Economy', 'PremiumEconomy', 'Business'];

const validateRequest = (body) => {
  const errors = [];
  if (!body) return { valid: false, errors: ['Request body is missing'] };

  if (!body.tripType || !VALID_TRIP_TYPES.includes(body.tripType)) {
    errors.push(`tripType must be one of: ${VALID_TRIP_TYPES.join(', ')}`);
  }

  if (!body.legs || !Array.isArray(body.legs) || body.legs.length === 0) {
    errors.push('legs must be a non-empty array');
  } else {
    body.legs.forEach((leg, i) => {
      if (!leg.origin || leg.origin.trim().length !== 3) errors.push(`legs[${i}].origin must be a 3-letter IATA code`);
      if (!leg.destination || leg.destination.trim().length !== 3) errors.push(`legs[${i}].destination must be a 3-letter IATA code`);
      if (leg.origin && leg.destination && leg.origin.toUpperCase() === leg.destination.toUpperCase()) errors.push(`legs[${i}].origin and destination cannot be the same`);
      if (!leg.departureDate || !/^\d{4}-\d{2}-\d{2}$/.test(leg.departureDate)) errors.push(`legs[${i}].departureDate must be in YYYY-MM-DD format`);
    });
    if (body.tripType === 'roundTrip' && body.legs.length !== 2) errors.push('roundTrip must have exactly 2 legs');
    if (body.tripType === 'oneWay' && body.legs.length !== 1) errors.push('oneWay must have exactly 1 leg');
    if (body.tripType === 'multiCity' && body.legs.length < 2) errors.push('multiCity must have at least 2 legs');
  }

  if (!body.passengers || !Array.isArray(body.passengers) || body.passengers.length === 0) {
    errors.push('passengers must be a non-empty array');
  } else {
    let totalAdults = 0, totalInfants = 0;
    body.passengers.forEach((p, i) => {
      if (!p.type || !VALID_PASSENGER_TYPES.includes(p.type)) errors.push(`passengers[${i}].type must be one of: ${VALID_PASSENGER_TYPES.join(', ')}`);
      if (!p.count || typeof p.count !== 'number' || p.count < 1) errors.push(`passengers[${i}].count must be a positive number`);
      if (p.type === 'ADT') totalAdults += (p.count || 0);
      if (p.type === 'INF') totalInfants += (p.count || 0);
    });
    if (totalAdults === 0) errors.push('At least 1 adult passenger (ADT) is required');
    if (totalInfants > totalAdults) errors.push('Number of infants (INF) cannot exceed number of adults (ADT)');
  }

  // cabinClass is OPTIONAL. age is NO LONGER accepted from the frontend (set server-side).
  if (body.cabinClass != null && body.cabinClass !== '' && !VALID_CABIN_CLASSES.includes(body.cabinClass)) {
    errors.push(`cabinClass must be one of: ${VALID_CABIN_CLASSES.join(', ')}`);
  }

  if (errors.length > 0) return { valid: false, errors };

  return {
    valid: true,
    params: {
      tripType: body.tripType,
      legs: body.legs.map((leg) => ({ origin: leg.origin.trim().toUpperCase(), destination: leg.destination.trim().toUpperCase(), departureDate: leg.departureDate })),
      passengers: body.passengers.map((p) => ({ type: p.type, count: p.count })), // age dropped on purpose
      cabinClass: (body.cabinClass && body.cabinClass.trim()) || null,
    },
  };
};

const search = async (req, res) => {
  const { valid, errors, params } = validateRequest(req.body);
  if (!valid) return res.status(400).json({ success: false, error: 'Invalid request', details: errors });

  try {
    const result = await searchFlights(params);
    return res.status(200).json(result);
  } catch (err) {
    const ts = new Date().toISOString();
    console.error(`[unifiedFlightController] [${ts}] error: ${err.message}`);
    console.error(`[unifiedFlightController] [${ts}] stack: ${err.stack}`);

    if (err.code === 'TICKETING_TABLE_FETCH_FAILED') {
      return res.status(503).json({ success: false, error: 'Ticketing authority table fetch failed', details: err.message });
    }
    if (err.message.includes('API call failed')) {
      return res.status(502).json({ success: false, error: 'Upstream API error', details: err.message });
    }
    return res.status(500).json({ success: false, error: 'Internal server error' });
  }
};

module.exports = { search };