/*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 HOTEL = process.env.TRAVELPORT_HOTEL_SERVICE

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

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

    const {
      traceId,
      authorizedBy,
      hotelRulesLookup
    } = data;

    // 🧩 BUILD EXACT XML

    const xmlRequest = `
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>

      <hotel:HotelRulesReq
          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:HotelRulesLookup
             RatePlanType="${hotelRulesLookup.ratePlanType}"
             Base="${hotelRulesLookup.base}">

            <hotel:HotelProperty
                HotelChain="${hotelRulesLookup.hotelProperty.hotelChain}"
                HotelCode="${hotelRulesLookup.hotelProperty.hotelCode}"
                HotelLocation="${hotelRulesLookup.hotelProperty.hotelLocation}"
                Name="${hotelRulesLookup.hotelProperty.name}"
                ParticipationLevel="${hotelRulesLookup.hotelProperty.participationLevel}">

               <hotel:PropertyAddress>
                  <hotel:Address>${hotelRulesLookup.hotelProperty.address1}</hotel:Address>
                  <hotel:Address>${hotelRulesLookup.hotelProperty.address2}</hotel:Address>
               </hotel:PropertyAddress>

               <com:PhoneNumber Type="Business" Number="${hotelRulesLookup.hotelProperty.businessPhone}"/>
               <com:PhoneNumber Type="Fax" Number="${hotelRulesLookup.hotelProperty.faxPhone}"/>

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

            </hotel:HotelProperty>

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

            <hotel:HotelRulesModifiers
                NumberOfAdults="${hotelRulesLookup.numberOfAdults}"
                NumberOfRooms="${hotelRulesLookup.numberOfRooms}"/>

         </hotel:HotelRulesLookup>

      </hotel:HotelRulesReq>

   </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: "HotelRulesReq",
        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: HotelRulesReq - END");
    console.log("==================================================");

    return jsonResponse;

  } catch (error) {
    console.error("SERVICE ERROR: HotelRulesReq");
    console.error(error.response?.data || error.message);
    throw new Error("Travelport HotelRules 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;

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

  try {
    const { hotelRulesLookup } = data;

    const {
      // ✅ REQUIRED
      ratePlanType,
      base,
      checkin,
      checkout,
      hotelProperty,

      // ✅ OPTIONAL — Modifiers attributes
      numberOfAdults  = 1,
      numberOfRooms   = 1,
      totalOccupants,           // 1P only

      // ✅ OPTIONAL — Modifiers child elements (XSD confirmed)
      children,                 // [{ age: 5 }, { age: 10 }] — <NumberOfChildren>
      beddingType,              // "King"|"Queen"|"Double" — <HotelBedding Type="">
      numberOfBeds,             // optional — HotelBedding NumberOfBeds
      rateCategory,             // max 1 — <RateCategory>
      corporateDiscountIds,     // max 2 — <CorporateDiscountID>

    } = hotelRulesLookup;

    const {
      // ✅ REQUIRED
      hotelChain,
      hotelCode,

      // ✅ OPTIONAL — HotelProperty attributes
      hotelLocation,
      name,
      vendorLocationKey,
      participationLevel,
      reserveRequirement,
      availability,
      hotelTransportation,

      // ✅ OPTIONAL — HotelProperty child elements
      address1,
      address2,
      businessPhone,
      faxPhone,
      distance,           // { units, value, direction }
      hotelRating,        // { provider, rating }

    } = hotelProperty;

    /* ------------------------------------------------
       REQUIRED FIELD CHECKS
    ------------------------------------------------ */
    if (!ratePlanType) throw new Error("ratePlanType is required");
    if (!base)         throw new Error("base is required");
    if (!checkin)      throw new Error("checkin is required");
    if (!checkout)     throw new Error("checkout is required");
    if (!hotelChain)   throw new Error("hotelChain is required");
    if (!hotelCode)    throw new Error("hotelCode is required");

    /* ------------------------------------------------
       PARSE NUMBERS
    ------------------------------------------------ */
    const adults = parseInt(numberOfAdults, 10) || 1;
    const rooms  = parseInt(numberOfRooms,  10) || 1;

    /* ------------------------------------------------
       BUILD HotelProperty ATTRIBUTES
    ------------------------------------------------ */
    const hotelPropertyAttrs = [
      `HotelChain="${hotelChain}"`,
      `HotelCode="${hotelCode}"`,
      hotelLocation       ? `HotelLocation="${hotelLocation}"`             : null,
      name                ? `Name="${name}"`                               : null,
      vendorLocationKey   ? `VendorLocationKey="${vendorLocationKey}"`     : null,
      participationLevel  ? `ParticipationLevel="${participationLevel}"`   : null,
      reserveRequirement  ? `ReserveRequirement="${reserveRequirement}"`   : null,
      availability        ? `Availability="${availability}"`               : null,
      hotelTransportation ? `HotelTransportation="${hotelTransportation}"` : null,
    ].filter(Boolean).join("\n                ");

    /* ------------------------------------------------
       BUILD HotelRulesModifiers ATTRIBUTES
    ------------------------------------------------ */
    const modifierAttrs = [
      `NumberOfAdults="${adults}"`,
      `NumberOfRooms="${rooms}"`,
      totalOccupants ? `TotalOccupants="${totalOccupants}"` : null,
    ].filter(Boolean).join("\n                ");

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

    // 1. PropertyAddress
    let addressXML = "";
    if (address1 || address2) {
      const lines = [
        address1 ? `<hotel:Address>${address1}</hotel:Address>` : null,
        address2 ? `<hotel:Address>${address2}</hotel:Address>` : null,
      ].filter(Boolean).join("\n                  ");
      addressXML = `
               <hotel:PropertyAddress>
                  ${lines}
               </hotel:PropertyAddress>`;
    }

    // 2. Phone Numbers
    let phoneXML = "";
    if (businessPhone) phoneXML += `\n               <com:PhoneNumber Type="Business" Number="${businessPhone}"/>`;
    if (faxPhone)      phoneXML += `\n               <com:PhoneNumber Type="Fax" Number="${faxPhone}"/>`;

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

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

    // 5. ✅ NumberOfChildren — FIXED: uses <Age> not <ChildAge>
    let childrenXML = "";
    if (children && Array.isArray(children) && children.length > 0) {
      const ageEntries = children
        .map(c => `<hotel:Age>${c.age}</hotel:Age>`)  // ✅ <Age> per XSD
        .join("\n                  ");
      childrenXML = `
               <hotel:NumberOfChildren Count="${children.length}">
                  ${ageEntries}
               </hotel:NumberOfChildren>`;
    }

    // 6. ✅ HotelBedding — FIXED: replaces roomType/bedType
    const beddingXML = beddingType
      ? `\n               <hotel:HotelBedding Type="${beddingType}"${numberOfBeds ? ` NumberOfBeds="${numberOfBeds}"` : ""}/>`
      : "";

    // 7. ✅ RateCategory — max 1 per XSD
    const rateCategoryXML = rateCategory
      ? `\n               <hotel:RateCategory>${rateCategory}</hotel:RateCategory>`
      : "";

    // 8. ✅ CorporateDiscountID — max 2 per XSD
    let corporateXML = "";
    if (corporateDiscountIds && Array.isArray(corporateDiscountIds) && corporateDiscountIds.length > 0) {
      const limited = corporateDiscountIds.slice(0, 2); // ✅ max 2 per XSD
      corporateXML = limited
        .map(id => `\n               <com:CorporateDiscountID>${id}</com:CorporateDiscountID>`)
        .join("");
    } else if (typeof corporateDiscountIds === "string" && corporateDiscountIds) {
      corporateXML = `\n               <com:CorporateDiscountID>${corporateDiscountIds}</com:CorporateDiscountID>`;
    }

    /* ------------------------------------------------
       BUILD FULL SOAP BODY
    ------------------------------------------------ */
    const soapBody = `<?xml version="1.0" encoding="UTF-8"?>
<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:HotelRulesReq
          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:HotelRulesLookup
             RatePlanType="${ratePlanType}"
             Base="${base}">

            <hotel:HotelProperty
                ${hotelPropertyAttrs}>
               ${addressXML}
               ${phoneXML}
               ${distanceXML}
               ${ratingXML}
            </hotel:HotelProperty>

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

            <hotel:HotelRulesModifiers
                ${modifierAttrs}>

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

               ${childrenXML}
               ${beddingXML}
               ${rateCategoryXML}
               ${corporateXML}

            </hotel:HotelRulesModifiers>

         </hotel:HotelRulesLookup>

      </hotel:HotelRulesReq>

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

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

    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");

    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: HotelRulesReq - END");
    console.log("==================================================");

    return jsonResponse;

  } catch (error) {
    const soapFault = error.response?.data || error.message;
    console.error("❌ SERVICE ERROR: HotelRulesReq");
    console.error("HTTP Status :", error.response?.status);
    console.error("SOAP Fault  :", soapFault);
    throw new Error(typeof soapFault === "string" ? soapFault : JSON.stringify(soapFault));
  }
};