// const LOW_FARE_URL = process.env.TRAVELPORT_AIR_SERVICE;

// console.log("👉 LOW_FARE_URL:", LOW_FARE_URL);

// const lowFareSearchModel = require("../models/lowFareSearchModel");
// // const redisClient = require("../config/redis");

// const {
//   getFilterableFlights,
//   applyFiltersToKeys,
//   buildFilterMetadata,
//   reconstructFilteredResponse
// } = require("../utils/flightUtils");


// //const CACHE_TTL = 300; // 5 mins

// // function generateCacheKey(query) {
// //   return `FLIGHTS:${JSON.stringify(query)}`;
// // }

// // Retry logic
// async function fetchWithRetry(fn, retries = 2) {
//   try {
//     return await fn();
//   } catch (err) {
//     if (retries === 0) throw err;
//     return fetchWithRetry(fn, retries - 1);
//   }
// }

// exports.searchFlights = async (query) => {

//   const { source, destination, doj } = query;

//   if (!source || !destination || !doj) {
//     throw new Error('source, destination, doj required');
//   }

//   //   const cacheKey = generateCacheKey(query);

//   //   // 🔥 1. CHECK CACHE
//   //   const cached = await redisClient.get(cacheKey);
//   //   if (cached) {
//   //     return JSON.parse(cached);
//   //   }

//   // 🔥 2. FETCH WITH RETRY
//   const rawData = await fetchWithRetry(() =>
//     lowFareSearchModel.fetchLowFareSearch(
//       source.toUpperCase(),
//       destination.toUpperCase(),
//       doj,
//       query
//     )
//   );

//   if (!rawData || !rawData.success) {
//     throw new Error('Travelport API failed');
//   }

//   // 🔥 3. ANALYZE (Get IDs and Metadata)
//   const filterable = getFilterableFlights(rawData.data || rawData);
//   const metadata = buildFilterMetadata(filterable);

//   // 🔥 4. APPLY FILTERS (Get matching keys)
//   const matchingKeys = applyFiltersToKeys(filterable, query);

//   // 🔥 6. PAGINATION (Apply to keys)
//   const page = parseInt(query.page || 1);
//   const limit = parseInt(query.limit || 200);
//   const start = (page - 1) * limit;
//   const paginatedKeys = matchingKeys.slice(start, start + limit);

//   // If no results match, return a clear validation state
//   if (matchingKeys.length === 0) {
//     return {
//       success: true,
//       message: "No flights match your criteria. Please try different filters.",
//       totalResults: 0,
//       page,
//       limit,
//       filterMetadata: metadata,
//       results: [] // Explicitly clear results
//     };
//   }

//   // 🔥 7. RECONSTRUCT (Build raw response with only matching keys)
//   const reconstructed = reconstructFilteredResponse(rawData.data || rawData, paginatedKeys);

//   return {
//     success: true,
//     message: "Flights search successful",
//     totalResults: matchingKeys.length,
//     page,
//     limit,
//     filterMetadata: metadata,
//     ...reconstructed
//   };
// };



"use strict";

const lowFareSearchModel = require("../models/lowFareSearchModel");

const {
  getFilterableFlights,
  applyFiltersToKeys,
  buildFilterMetadata,
  reconstructFilteredResponse,
} = require("../utils/flightUtils");

// DEBUG HOOK — uncomment both lines to see filter breakdown in terminal
// const { debugFilterable } = require("./debugFilter");

async function fetchWithRetry(fn, retries = 2) {
  try {
    return await fn();
  } catch (err) {
    if (retries === 0) throw err;
    return fetchWithRetry(fn, retries - 1);
  }
}

exports.searchFlights = async (query) => {
  const { source, destination, doj } = query;

  if (!source || !destination || !doj) {
    throw new Error("source, destination, and doj are required");
  }

  // 1. Fetch from Travelport
  const rawData = await fetchWithRetry(() =>
    lowFareSearchModel.fetchLowFareSearch(
      source.toUpperCase(),
      destination.toUpperCase(),
      doj,
      query
    )
  );

  if (!rawData || !rawData.success) {
    throw new Error("Travelport API failed");
  }

  // rawData = { success: true, data: { SOAP:Envelope: {...} } }
  // getFilterableFlights handles both the wrapped and unwrapped form
  const responseData = rawData.data || rawData;

  // 2. Build filter index
  const filterable = getFilterableFlights(responseData);

  // DEBUG: uncomment to print filterable to terminal
  // debugFilterable(filterable, query);

  const metadata = buildFilterMetadata(filterable);

  // 3. Apply filters
  const matchingKeys  = applyFiltersToKeys(filterable, query);

  // 4. Paginate
  const page          = parseInt(query.page  || 1,   10);
  const limit         = parseInt(query.limit || 200, 10);
  const paginatedKeys = matchingKeys.slice((page - 1) * limit, page * limit);

  // 5. No results
  if (matchingKeys.length === 0) {
    return {
      success:        true,
      message:        "No flights match your criteria. Please try different filters.",
      totalResults:   0,
      page,
      limit,
      filterMetadata: metadata,
      results:        [],
    };
  }

  // 6. Reconstruct — only matched solutions
  const reconstructed = reconstructFilteredResponse(responseData, paginatedKeys);

  return {
    success:        true,
    // message:        "Flights search successful",
    // totalResults:   matchingKeys.length,
    // page,
    // limit,
    // filterMetadata: metadata,
    data:           reconstructed,
  };
};

