/*const axios = require("axios");
const xml2js = require("xml2js");
const crypto = require("crypto");

const URL = process.env.TRAVELPORT_SYSTEM_SERVICE;
const USERNAME=process.env.TRAVELPORT_USERNAME;
const authorizedBy = process.env.TRAVELPORT_USERNAME.replace(/[^a-zA-Z0-9]/g, "");
const PASSWORD = process.env.TRAVELPORT_PASSWORD;
const BRANCH = process.env.TARGET_BRANCH;
const HOTEL = process.env.TRAVELPORT_HOTEL_SERVICE;

exports.getHotelDetails = async (data) => {
  console.log("==================================================");
  console.log("SERVICE: HotelDetailsReq - START");

  try {

    // 🔹 Generate TraceId internally
    const traceId = crypto.randomUUID();

    console.log("Generated TraceId:", traceId);

    console.log("➡️ Incoming Payload:");
    console.log(JSON.stringify(data, null, 2));

    const {
      hotelProperty,
      detailsModifiers,
    } = data;

    // 🧩 XML BUILD
    const xmlRequest = `
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:common_v54_0="http://www.travelport.com/schema/common_v54_0">
  <soapenv:Body>

    <hotel:HotelDetailsReq
        AuthorizedBy="${authorizedBy}"
        TargetBranch="${BRANCH}"
        TraceId="${traceId}"
        xmlns:hotel="http://www.travelport.com/schema/hotel_v54_0"
        xmlns:com="http://www.travelport.com/schema/common_v54_0">

      <com:BillingPointOfSaleInfo OriginApplication="UAPI"/>

      <hotel:HotelProperty
          HotelChain="${hotelProperty.hotelChain}"
          HotelCode="${hotelProperty.hotelCode}"
          HotelLocation="${hotelProperty.hotelLocation}"
          Name="${hotelProperty.name}"
          VendorLocationKey="${hotelProperty.vendorLocationKey}"
         
          ReserveRequirement="${hotelProperty.reserveRequirement}"
          ParticipationLevel="${hotelProperty.participationLevel}"
          Availability="${hotelProperty.availability}">

        <hotel:PropertyAddress>
          <hotel:Address>${hotelProperty.address}</hotel:Address>
        </hotel:PropertyAddress>

        <common_v54_0:Distance
            Units="${hotelProperty.distance.units}"
            Value="${hotelProperty.distance.value}"
            Direction="${hotelProperty.distance.direction}"/>

        <hotel:HotelRating RatingProvider="${hotelProperty.hotelRating.provider}">
          <hotel:Rating>${hotelProperty.hotelRating.rating}</hotel:Rating>
        </hotel:HotelRating>

      </hotel:HotelProperty>

      <hotel:HotelDetailsModifiers
          RateRuleDetail="${detailsModifiers.rateRuleDetail}"
          NumberOfAdults="${detailsModifiers.numberOfAdults}"
          NumberOfRooms="${detailsModifiers.numberOfRooms}">

        <com:PermittedProviders>
          <com:Provider Code="${detailsModifiers.providerCode}"/>
        </com:PermittedProviders>

        <hotel:HotelStay>
          <hotel:CheckinDate>${detailsModifiers.checkin}</hotel:CheckinDate>
          <hotel:CheckoutDate>${detailsModifiers.checkout}</hotel:CheckoutDate>
        </hotel:HotelStay>

      </hotel:HotelDetailsModifiers>

    </hotel:HotelDetailsReq>

  </soapenv:Body>
</soapenv:Envelope>`;

    console.log("📤 SOAP XML Request:");
    console.log(xmlRequest);

    // 🌐 SOAP CALL
    const response = await axios.post(HOTEL, xmlRequest, {
      headers: {
        "Content-Type": "text/xml;charset=UTF-8",
        SOAPAction: "HotelDetailsReq",
        Authorization:
          "Basic " +
          Buffer.from(USERNAME + ":" + PASSWORD).toString("base64"),
      },
      timeout: 60000,
    });

    console.log("📥 RAW SOAP RESPONSE RECEIVED");

    // 🔄 XML → JSON
    const parser = new xml2js.Parser({
      explicitArray: false,
      ignoreAttrs: false,
    });

    const jsonResponse = await parser.parseStringPromise(response.data);

    console.log("✅ XML → JSON conversion done");
    console.log("SERVICE: HotelDetailsReq - END");
    console.log("==================================================");

    return jsonResponse;

  } catch (error) {
    console.error("❌ SERVICE ERROR: HotelDetailsReq");
    console.error(error.response?.data || error.message);
    throw new Error("Travelport HotelDetails API failed");
  }
};*/


const axios  = require("axios");
const xml2js = require("xml2js");

const HOTEL_URL    = process.env.TRAVELPORT_HOTEL_SERVICE;
const USERNAME     = process.env.TRAVELPORT_USERNAME;
const PASSWORD     = process.env.TRAVELPORT_PASSWORD;
const BRANCH       = process.env.TARGET_BRANCH;
const PROVIDER     = process.env.PROVIDER_CODE || "1G";
const AUTHORIZED_BY = process.env.AUTHORIZED_BY; // ✅ use as-is, no stripping

exports.getHotelDetails = async (data) => {
  console.log("==================================================");
  console.log("SERVICE: HotelDetailsReq - START");
  console.log("INPUT DATA:", JSON.stringify(data, null, 2));
  console.log("==================================================");

  try {

    /* ------------------------------------------------
       DESTRUCTURE
    ------------------------------------------------ */
    const {
      // Required
      hotelChain,
      hotelCode,
      hotelLocation,
      hotelName,
      vendorLocationKey,
      checkinDate,
      checkoutDate,

      // Optional — Hotel Property
      reserveRequirement,
      participationLevel,
      availability,
      address,
      distance,
      hotelRating,
      hotelTransportation,

      // Optional — Modifiers
      numberOfAdults    = 1,
      numberOfRooms     = 1,
      rateRuleDetail    = "Complete",
      children,
      rateCategory,
      amenities,
      corporateDiscountId,
      promoCode,
      minRate,
      maxRate,
      currency,
      roomType,
      bedType,
    } = data;

    /* ------------------------------------------------
       REQUIRED FIELD CHECKS
    ------------------------------------------------ */
    if (!hotelChain)        throw new Error("hotelChain is required");
    if (!hotelCode)         throw new Error("hotelCode is required");
    if (!hotelLocation)     throw new Error("hotelLocation is required");
    if (!hotelName)         throw new Error("hotelName is required");
    if (!vendorLocationKey) throw new Error("vendorLocationKey is required");
    if (!checkinDate)       throw new Error("checkinDate is required");
    if (!checkoutDate)      throw new Error("checkoutDate is required");

    /* ------------------------------------------------
       BUILD OPTIONAL XML BLOCKS
    ------------------------------------------------ */

    // 1. Distance — correct namespace: common_v54_0
    const distanceXML = distance && distance.value && distance.direction
      ? `<common_v54_0:Distance
            Units="${distance.units || "MI"}"
            Value="${distance.value}"
            Direction="${distance.direction}"/>`
      : "";

    // 2. Hotel Rating
    const ratingXML = hotelRating
      ? `<hotel:HotelRating RatingProvider="${hotelRating.provider || "AAA"}">
           <hotel:Rating>${hotelRating.rating || 0}</hotel:Rating>
         </hotel:HotelRating>`
      : "";

    // 3. HotelProperty optional attributes
    const reserveReqAttr     = reserveRequirement  ? `ReserveRequirement="${reserveRequirement}"`   : "";
    const availabilityAttr   = availability        ? `Availability="${availability}"`               : "";
    const participationAttr  = participationLevel  ? `ParticipationLevel="${participationLevel}"`   : "";
    const transportationAttr = hotelTransportation ? `HotelTransportation="${hotelTransportation}"` : "";

    // 4. Children
    let childrenXML = "";
    if (children && Array.isArray(children) && children.length > 0) {
      const ageEntries = children
        .map(c => `<hotel:ChildAge Age="${c.age}"/>`)
        .join("\n            ");
      childrenXML = `
        <hotel:NumberOfChildren Count="${children.length}">
          ${ageEntries}
        </hotel:NumberOfChildren>`;
    }

    // 5. Rate Category
    const rateCategoryXML = rateCategory
      ? `<hotel:RateCategory>${rateCategory}</hotel:RateCategory>`
      : "";

    // 6. Amenities
    let amenitiesXML = "";
    if (amenities && Array.isArray(amenities) && amenities.length > 0) {
      amenitiesXML = `
        <hotel:Amenities>
          ${amenities.map(a => `<hotel:Amenity AmenityType="${a}"/>`).join("\n          ")}
        </hotel:Amenities>`;
    }

    // 7. Corporate Discount
    const corporateXML = corporateDiscountId
      ? `<hotel:CorporateDiscountID>${corporateDiscountId}</hotel:CorporateDiscountID>`
      : "";

    // 8. Promo Code
    const promoXML = promoCode
      ? `<hotel:PromotionCode>${promoCode}</hotel:PromotionCode>`
      : "";

    // 9. Rate Range — no empty attributes
    let rateRangeXML = "";
    if (minRate || maxRate) {
      const minAttr      = minRate  ? `MinAmount="${minRate}"`     : "";
      const maxAttr      = maxRate  ? `MaxAmount="${maxRate}"`     : "";
      const currencyAttr = currency ? `CurrencyCode="${currency}"` : "";
      rateRangeXML = `<hotel:RateRange ${minAttr} ${maxAttr} ${currencyAttr}/>`;
    }

    // 10. Room Type
    const roomTypeXML = roomType
      ? `<hotel:RoomType RoomCategory="${roomType}"${bedType ? ` BedType="${bedType}"` : ""}/>`
      : "";

    // 11. Currency on Modifiers
    const currencyAttr = currency ? `CurrencyCode="${currency}"` : "";

    /* ------------------------------------------------
       BUILD SOAP XML
    ------------------------------------------------ */
    const soapBody = `
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:common_v54_0="http://www.travelport.com/schema/common_v54_0">

  <soapenv:Header/>
  <soapenv:Body>

    <hotel:HotelDetailsReq
        AuthorizedBy="${AUTHORIZED_BY}"
        TargetBranch="${BRANCH}"
        TraceId="TRACE_${Date.now()}"
        xmlns:hotel="http://www.travelport.com/schema/hotel_v54_0"
        xmlns:com="http://www.travelport.com/schema/common_v54_0">

      <com:BillingPointOfSaleInfo OriginApplication="UAPI"/>

      <hotel:HotelProperty
          HotelChain="${hotelChain}"
          HotelCode="${hotelCode}"
          HotelLocation="${hotelLocation}"
          Name="${hotelName}"
          VendorLocationKey="${vendorLocationKey}"
          ${reserveReqAttr}
          ${availabilityAttr}
          ${participationAttr}
          ${transportationAttr}>

        <hotel:PropertyAddress>
          <hotel:Address>${address || ""}</hotel:Address>
        </hotel:PropertyAddress>

        ${distanceXML}
        ${ratingXML}

      </hotel:HotelProperty>

      <hotel:HotelDetailsModifiers
          RateRuleDetail="${rateRuleDetail}"
          NumberOfAdults="${Number(numberOfAdults)}"
          NumberOfRooms="${Number(numberOfRooms)}"
          ${currencyAttr}>

        <com:PermittedProviders>
          <com:Provider Code="${PROVIDER}"/>
        </com:PermittedProviders>

        ${childrenXML}
        ${rateCategoryXML}
        ${amenitiesXML}
        ${corporateXML}
        ${promoXML}
        ${rateRangeXML}
        ${roomTypeXML}

        <hotel:HotelStay>
          <hotel:CheckinDate>${checkinDate}</hotel:CheckinDate>
          <hotel:CheckoutDate>${checkoutDate}</hotel:CheckoutDate>
        </hotel:HotelStay>

      </hotel:HotelDetailsModifiers>

    </hotel:HotelDetailsReq>

  </soapenv:Body>
</soapenv:Envelope>`;

    console.log("📤 SOAP REQUEST XML:");
    console.log(soapBody);

    /* ------------------------------------------------
       SOAP CALL
    ------------------------------------------------ */
    const response = await axios.post(HOTEL_URL, soapBody, {
      headers: { "Content-Type": "text/xml;charset=UTF-8" },
      auth:    { username: USERNAME, password: PASSWORD },
      timeout: 60000,
      maxBodyLength:    Infinity,
      maxContentLength: Infinity,
    });

    console.log("📥 RAW SOAP RESPONSE RECEIVED");

    /* ------------------------------------------------
       PARSE XML → JSON
    ------------------------------------------------ */
    const parser = new xml2js.Parser({
      explicitArray: false,
      ignoreAttrs:   false,
    });

    const jsonResponse = await parser.parseStringPromise(response.data);

    console.log("✅ XML → JSON conversion done");
    console.log("SERVICE: HotelDetailsReq - END");
    console.log("==================================================");

    return jsonResponse;

  } catch (error) {
    console.error("❌ SERVICE ERROR: HotelDetailsReq");
    console.error("Status  :", error.response?.status);
    console.error("Detail  :", error.response?.data || error.message);
    throw new Error(`HotelDetails failed: ${error.response?.data || error.message}`);
  }
};