package com.fractalite.amad_ndc.convertersRS;


import com.amadeus.travelManagement.amadeus.xml._2010._06.travel_ordercancelrs_v1.AMATravelOrderCancelRS;
import com.amadeus.travelManagement.amadeus.xml._2010._06.travel_ordercancelrs_v1.ErrorType;
import com.fractalite.mercure.data.model.bo.Item;
import com.fractalite.mercure.data.model.bo.Order;
import com.fractalite.mercure.data.model.bo.OrderStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * Maps an Amadeus {@link AMATravelOrderCancelRS} to a Mercure {@link Order}.
 *
 * <p>
 * The Amadeus cancel RS is intentionally thin — it confirms cancellation or
 * returns an error. We enrich the Mercure Order locally with status=Cancelled
 * so the front-end and CRM receive a consistent Order object.
 * </p>
 */
@Component
public class AMA_TravelOrderCancelRSMapper {

    private static final Logger LOG = LoggerFactory.getLogger(AMA_TravelOrderCancelRSMapper.class);

    // =========================================================================
    // Public API
    // =========================================================================

    /**
     * Validate the Amadeus cancel RS, update the Order status to Cancelled,
     * and return the enriched Order.
     *
     * @param cancelRS the raw Amadeus cancel RS (null is treated as a hard failure)
     * @param order    the Mercure Order fetched from the CRM — its items are
     *                 updated in-place
     * @return the same {@code order} with all items set to
     *         {@link OrderStatus#Cancelled}
     * @throws IllegalStateException if the Amadeus RS is null, missing Response, or
     *                               contains errors
     */
    public Order applyCancel(AMATravelOrderCancelRS cancelRS, Order order) {

        // --- 1. Guard: null response ------------------------------------------------
        if (cancelRS == null) {
            throw new IllegalStateException("Amadeus cancel RS is null — SOAP call may have failed.");
        }

        // --- 2. Guard: explicit Amadeus-level errors --------------------------------
        if (cancelRS.getError() != null && !cancelRS.getError().isEmpty()) {
            ErrorType firstError = cancelRS.getError().get(0);
            String code = firstError.getCode() != null ? firstError.getCode() : "?";
            String desc = firstError.getDescText() != null ? firstError.getDescText() : "Unknown Amadeus error";
            LOG.error("Amadeus cancel RS error [{}]: {}", code, desc);
            throw new IllegalStateException("Cancel failed [" + code + "]: " + desc);
        }

        // --- 3. Guard: no Response element -----------------------------------------
        if (cancelRS.getResponse() == null) {
            throw new IllegalStateException(
                    "Amadeus cancel RS has no Response element and no Error — unexpected structure.");
        }

        // --- 4. Apply Cancelled status to all order items ---------------------------
        if (order.getItems() != null) {
            for (Item item : order.getItems()) {
                item.setStatus(OrderStatus.Cancelled);
            }
        }

        LOG.info("Order {} successfully cancelled (ref={})", order.getOrderId(), order.getRef());
        return order;
    }
}
