/*const hotelRulesService = require("../services/hotelRulesService");

exports.getHotelRules = async (req, res) => {
  console.log("==================================================");
  console.log("CONTROLLER: HotelRulesReq - START");

  try {
    console.log("➡️ Request Body:");
    console.log(JSON.stringify(req.body, null, 2));

    const result = await hotelRulesService.getHotelRules(req.body);

    console.log("✅ CONTROLLER: HotelRulesReq - SUCCESS");
    console.log("==================================================");

    return res.status(200).json({
      success: true,
      message: "Hotel rules fetched successfully",
      data: result,
    });

  } catch (error) {
    console.error("❌ CONTROLLER ERROR: HotelRulesReq");
    console.error(error.message);
    console.log("==================================================");

    return res.status(500).json({
      success: false,
      message: "Hotel rules request failed",
      error: error.message,
    });
  }
};*/

const hotelRulesService = require("../services/newHotelRulesService");

exports.getHotelRules = async (req, res) => {
  console.log("==================================================");
  console.log("CONTROLLER: HotelRulesReq - START");
  console.log("➡️ Request Body:");
  console.log(JSON.stringify(req.body, null, 2));

  try {
    const { hotelRulesLookup } = req.body;

    /* ------------------------------------------------
       LEVEL 1 — Validate top-level object
    ------------------------------------------------ */
    if (!hotelRulesLookup) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup is required",
      });
    }

    /* ------------------------------------------------
       LEVEL 2 — Validate required fields in hotelRulesLookup
       XSD: RatePlanType and Base are required attributes
             on HotelRulesLookup element
    ------------------------------------------------ */
    if (!hotelRulesLookup.ratePlanType) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.ratePlanType is required",
      });
    }

    if (!hotelRulesLookup.base) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.base is required",
      });
    }

    if (!hotelRulesLookup.checkin) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.checkin is required (HotelStay > CheckinDate)",
      });
    }

    if (!hotelRulesLookup.checkout) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.checkout is required (HotelStay > CheckoutDate)",
      });
    }

    /* ------------------------------------------------
       LEVEL 3 — Validate date format YYYY-MM-DD
       XSD: typeDate restricts to xs:date without timezone
    ------------------------------------------------ */
    const dateRegex = /^\d{4}-\d{2}-\d{2}$/;

    if (!dateRegex.test(hotelRulesLookup.checkin)) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.checkin must be in YYYY-MM-DD format",
      });
    }

    if (!dateRegex.test(hotelRulesLookup.checkout)) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.checkout must be in YYYY-MM-DD format",
      });
    }

    /* ------------------------------------------------
       LEVEL 4 — Validate checkin is before checkout
    ------------------------------------------------ */
    if (new Date(hotelRulesLookup.checkin) >= new Date(hotelRulesLookup.checkout)) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.checkin must be before checkout",
      });
    }

    /* ------------------------------------------------
       LEVEL 5 — Validate hotelProperty object exists
    ------------------------------------------------ */
    if (!hotelRulesLookup.hotelProperty) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty is required",
      });
    }

    const { hotelProperty } = hotelRulesLookup;

    /* ------------------------------------------------
       LEVEL 6 — Validate required HotelProperty attributes
       XSD: HotelChain use="required", HotelCode use="required"
    ------------------------------------------------ */
    if (!hotelProperty.hotelChain) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.hotelChain is required",
      });
    }

    if (!hotelProperty.hotelCode) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.hotelCode is required",
      });
    }

    /* ------------------------------------------------
       LEVEL 7 — Validate HotelChain format
       XSD: typeHotelChainCode — 2 character code
    ------------------------------------------------ */
    if (hotelProperty.hotelChain.length !== 2) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.hotelChain must be a 2-letter code (e.g. 'LC', 'WI')",
      });
    }

    /* ------------------------------------------------
       LEVEL 8 — Validate HotelLocation format if provided
       XSD: typeHotelLocationCode — minLength=3, maxLength=6
    ------------------------------------------------ */
    if (hotelProperty.hotelLocation) {
      const locLen = hotelProperty.hotelLocation.length;
      if (locLen < 3 || locLen > 6) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.hotelProperty.hotelLocation must be 3-6 characters (IATA code, e.g. 'HYD')",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 9 — Validate Availability enum if provided
       XSD: typeHotelAvailability enumeration values
    ------------------------------------------------ */
    const validAvailability = [
      "Available",
      "NotAvailable",
      "AvailableForOtherRates",
      "OnRequest",
      "Unknown",
    ];

    if (hotelProperty.availability && !validAvailability.includes(hotelProperty.availability)) {
      return res.status(400).json({
        success: false,
        message: `hotelRulesLookup.hotelProperty.availability must be one of: ${validAvailability.join(", ")}`,
      });
    }

    /* ------------------------------------------------
       LEVEL 10 — Validate ParticipationLevel if provided
       XSD: StringLength1 — "2" or "4"
       2 = Best Available Rate (1G, 1V)
       4 = Lowest Possible Rate (1G, 1V, 1P)
    ------------------------------------------------ */
    const validParticipationLevels = ["2", "4"];

    if (
      hotelProperty.participationLevel &&
      !validParticipationLevels.includes(String(hotelProperty.participationLevel))
    ) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.participationLevel must be '2' (Best Available Rate) or '4' (Lowest Possible Rate)",
      });
    }

    /* ------------------------------------------------
       LEVEL 11 — Validate address lines if provided
       XSD: typeUnstructuredAddress — max 6 Address lines,
            each max 50 characters
    ------------------------------------------------ */
    if (hotelProperty.address1 && hotelProperty.address1.length > 50) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.address1 must not exceed 50 characters",
      });
    }

    if (hotelProperty.address2 && hotelProperty.address2.length > 50) {
      return res.status(400).json({
        success: false,
        message: "hotelRulesLookup.hotelProperty.address2 must not exceed 50 characters",
      });
    }

    /* ------------------------------------------------
       LEVEL 12 — Validate distance object if provided
       XSD: common:Distance — Units, Value, Direction
    ------------------------------------------------ */
    if (hotelProperty.distance) {
      const { distance } = hotelProperty;

      if (!distance.value) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.hotelProperty.distance.value is required when distance is provided",
        });
      }

      if (!distance.direction) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.hotelProperty.distance.direction is required when distance is provided",
        });
      }

      const validDirections = ["N", "S", "E", "W", "NE", "NW", "SE", "SW"];
      if (!validDirections.includes(distance.direction.toUpperCase())) {
        return res.status(400).json({
          success: false,
          message: `hotelRulesLookup.hotelProperty.distance.direction must be one of: ${validDirections.join(", ")}`,
        });
      }

      const validUnits = ["MI", "KM"];
      if (distance.units && !validUnits.includes(distance.units.toUpperCase())) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.hotelProperty.distance.units must be 'MI' or 'KM'",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 13 — Validate numberOfAdults if provided
       XSD: NumberOfAdults type="xs:int" — must be positive integer
    ------------------------------------------------ */
    if (hotelRulesLookup.numberOfAdults !== undefined) {
      const adults = parseInt(hotelRulesLookup.numberOfAdults, 10);
      if (isNaN(adults) || adults < 1) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.numberOfAdults must be a positive integer (minimum 1)",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 14 — Validate numberOfRooms if provided
       XSD: NumberOfRooms type="xs:int" default="1"
    ------------------------------------------------ */
    if (hotelRulesLookup.numberOfRooms !== undefined) {
      const rooms = parseInt(hotelRulesLookup.numberOfRooms, 10);
      if (isNaN(rooms) || rooms < 1) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.numberOfRooms must be a positive integer (minimum 1)",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 15 — Validate totalOccupants if provided
       XSD: TotalOccupants type="xs:int" — 1P only
    ------------------------------------------------ */
    if (hotelRulesLookup.totalOccupants !== undefined) {
      const occupants = parseInt(hotelRulesLookup.totalOccupants, 10);
      if (isNaN(occupants) || occupants < 1) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.totalOccupants must be a positive integer",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 16 — Validate children array if provided
       XSD: NumberOfChildren > Age type="xs:int"
            Age typically 1-17. Count is required attribute.
    ------------------------------------------------ */
    if (hotelRulesLookup.children !== undefined) {
      if (!Array.isArray(hotelRulesLookup.children)) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.children must be an array e.g. [{ age: 5 }, { age: 10 }]",
        });
      }

      for (let i = 0; i < hotelRulesLookup.children.length; i++) {
        const child = hotelRulesLookup.children[i];

        if (child.age === undefined || child.age === null) {
          return res.status(400).json({
            success: false,
            message: `hotelRulesLookup.children[${i}].age is required`,
          });
        }

        const age = parseInt(child.age, 10);
        if (isNaN(age) || age < 1 || age > 17) {
          return res.status(400).json({
            success: false,
            message: `hotelRulesLookup.children[${i}].age must be between 1 and 17`,
          });
        }
      }
    }

    /* ------------------------------------------------
       LEVEL 17 — Validate beddingType if provided
       XSD: HotelBedding Type="typeBedding" — maxLength 15
    ------------------------------------------------ */
    if (hotelRulesLookup.beddingType !== undefined) {
      const validBeddingTypes = ["King", "Queen", "Double", "Twin", "Single", "Full"];

      if (!validBeddingTypes.includes(hotelRulesLookup.beddingType)) {
        return res.status(400).json({
          success: false,
          message: `hotelRulesLookup.beddingType must be one of: ${validBeddingTypes.join(", ")}`,
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 18 — Validate numberOfBeds if provided
       XSD: HotelBedding NumberOfBeds type="xs:int"
    ------------------------------------------------ */
    if (hotelRulesLookup.numberOfBeds !== undefined) {
      if (!hotelRulesLookup.beddingType) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.beddingType is required when numberOfBeds is provided",
        });
      }

      const beds = parseInt(hotelRulesLookup.numberOfBeds, 10);
      if (isNaN(beds) || beds < 0) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.numberOfBeds must be a non-negative integer",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 19 — Validate corporateDiscountIds if provided
       XSD: CorporateDiscountID maxOccurs="2" — max 2 allowed
    ------------------------------------------------ */
    if (hotelRulesLookup.corporateDiscountIds !== undefined) {
      const ids = hotelRulesLookup.corporateDiscountIds;

      if (!Array.isArray(ids) && typeof ids !== "string") {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.corporateDiscountIds must be a string or array of strings",
        });
      }

      if (Array.isArray(ids) && ids.length > 2) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.corporateDiscountIds allows maximum 2 IDs per Travelport XSD",
        });
      }
    }

    /* ------------------------------------------------
       LEVEL 20 — Validate hotelRating if provided
       XSD: HotelRating — RatingProvider required,
            Rating is xs:integer
    ------------------------------------------------ */
    if (hotelProperty.hotelRating) {
      const { hotelRating } = hotelProperty;

      if (!hotelRating.provider) {
        return res.status(400).json({
          success: false,
          message: "hotelRulesLookup.hotelProperty.hotelRating.provider is required when hotelRating is provided (e.g. 'AAA', 'NTM')",
        });
      }

      if (hotelRating.rating !== undefined) {
        const rating = parseInt(hotelRating.rating, 10);
        if (isNaN(rating) || rating < 0 || rating > 5) {
          return res.status(400).json({
            success: false,
            message: "hotelRulesLookup.hotelProperty.hotelRating.rating must be an integer between 0 and 5",
          });
        }
      }
    }

    /* ------------------------------------------------
       PASS TO SERVICE
    ------------------------------------------------ */
    const result = await hotelRulesService.getHotelRules(req.body);

    console.log("✅ CONTROLLER: HotelRulesReq - SUCCESS");

    return res.status(200).json({
      success: true,
      message: "Hotel rules fetched successfully",
      data: result,
    });

  } catch (error) {
    console.error("❌ CONTROLLER ERROR: HotelRulesReq");
    console.error(error.message);

    return res.status(500).json({
      success: false,
      message: "Hotel rules request failed",
      error: error.message,
    });

  } finally {
    console.log("CONTROLLER: HotelRulesReq - END");
    console.log("==================================================");
  }
};