const axios = require("axios");
const xml2js = require("xml2js");
const { logInfo, logError } = require("../utils/logger");

exports.fetchOptionalServices = async (params) => {
  try {
    const {
      pnr,
      providerCode,
      carrierCode,
      traveler,
      segment,
      carrierLocatorCode,
      providerLocatorCode
    } = params;

    /* ===============================
       1️⃣ VALIDATIONS
    =============================== */
    if (!carrierLocatorCode) {
      throw new Error("carrierLocatorCode is required from UniversalRecord");
    }

    if (!providerLocatorCode) {
      throw new Error("providerLocatorCode is required from UniversalRecord");
    }

    if (!traveler.bookingTravelerRef) {
      throw new Error("bookingTravelerRef is required");
    }

    /* ===============================
       2️⃣ FORMAT TIMES
    =============================== */
    const formatTime = (t) =>
      t && !t.includes(".000")
        ? t.replace(/(\+\d{2}:\d{2})$/, ".000$1")
        : t;

    const departureTime = formatTime(segment.departureTime);
    const arrivalTime = formatTime(segment.arrivalTime);

    const fareCode = segment.fareBasisCode || "";

    /* ===============================
       3️⃣ BUILD TRAVELPORT XML BODY
    =============================== */
    const bodyXML = `
<AirMerchandisingOfferAvailabilityReq xmlns="http://www.travelport.com/schema/air_v52_0"
    TraceId="${Date.now()}"
    TargetBranch="P7248477">

    <BillingPointOfSaleInfo xmlns="http://www.travelport.com/schema/common_v52_0"
        OriginApplication="uAPI" />

    <AirSolution>

        <SearchTraveler
            Code="${traveler.code}"
            Age="${traveler.age || 40}"
            DOB="${traveler.dob}"
            Gender="${traveler.gender}"
            BookingTravelerRef="${traveler.bookingTravelerRef}"
            Key="${traveler.bookingTravelerRef}">

            <Name xmlns="http://www.travelport.com/schema/common_v52_0"
                Prefix="${traveler.prefix || "Mr"}"
                First="${traveler.firstName}"
                Last="${traveler.lastName}" />
        </SearchTraveler>

        <AirSegment
            Key="${segment.key}"
            Status="HK"
            AvailabilitySource="S"
            Group="0"
            Carrier="${carrierCode}"
            FlightNumber="${segment.flightNumber}"
            Origin="${segment.origin}"
            Destination="${segment.destination}"
            DepartureTime="${departureTime}"
            ArrivalTime="${arrivalTime}"
            ProviderCode="${providerCode}"
            ClassOfService="${segment.classOfService}"
            ${segment.travelTime ? `TravelTime="${segment.travelTime}"` : ""}
            ${segment.distance ? `Distance="${segment.distance}"` : ""}
        />

        ${fareCode ? `<FareBasis Code="${fareCode}" />` : ""}

    </AirSolution>

    <HostReservation
        Carrier="${carrierCode}"
        CarrierLocatorCode="${carrierLocatorCode}"
        ProviderCode="${providerCode}"
        ProviderLocatorCode="${providerLocatorCode}"
        UniversalLocatorCode="${pnr}" />

</AirMerchandisingOfferAvailabilityReq>
`;

    /* ===============================
       4️⃣ BUILD SOAP ENVELOPE
    =============================== */
    const soapEnvelope = `
<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">

   <soapenv:Header>
      <wsse:Security>
         <wsse:UsernameToken>
            <wsse:Username>${process.env.TRAVELPORT_USERNAME}</wsse:Username>
            <wsse:Password>${process.env.TRAVELPORT_PASSWORD}</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>

   <soapenv:Body>
      ${bodyXML}
   </soapenv:Body>

</soapenv:Envelope>
`;

    /* ===============================
       5️⃣ CALL SOAP SERVICE
    =============================== */
    logInfo("Sending SOAP Request");

    const response = await axios.post(
      process.env.TRAVELPORT_AIR_SERVICE,
      soapEnvelope,
      {
        headers: {
          "Content-Type": "text/xml; charset=UTF-8",
          SOAPAction: '""',
        },
        timeout: 120000,
      }
    );

    logInfo("SOAP Response Received");

    /* ===============================
       6️⃣ PARSE XML RESPONSE
    =============================== */
    const parsed = await xml2js.parseStringPromise(response.data, {
      explicitArray: false,
      ignoreAttrs: false,
      tagNameProcessors: [xml2js.processors.stripPrefix],
    });

    return parsed;

  } catch (error) {
    logError("Fetch Optional Services Error", error.response?.data || error.message);
    throw error;
  }
};