const $ = jQuery;
const { klarna_interoperability } = await import("@klarna/interoperability_token");
let configData = {};

const params = document.getElementById(
  'wp-script-module-data-@klarna/kec-one-step'
);

if (params?.textContent) {
  try { configData = JSON.parse(params.textContent); } catch { }
}

const KECOneStep = {
  params: {
    ajax: {},
    client_id: '',
    testmode: false,
    theme: 'dark',
    shape: 'default',
    locale: false,
    currency: '',
    amount: 0,
    source: 'unknown'
  },
  Klarna: null,
  isInitiating: false,
  variationId: null,

  getContainer() {
    return document.querySelector('#kec-pay-button');
  },

  isMounted() {
    const container = KECOneStep.getContainer();
    return !!(container && container.childElementCount > 0);
  },

  mountButton() {
    const container = KECOneStep.getContainer();
    if (!container || !KECOneStep.Klarna) {
      return;
    }

    if (KECOneStep.isMounted()) {
      return;
    }

    KECOneStep.Klarna.Payment
      .button( {
        theme: KECOneStep.params.theme,
        shape: KECOneStep.params.shape,
        locale: KECOneStep.params.locale,
        intents: ["PAY"],
        initiationMode: "DEVICE_BEST",
        initiate: async () => await KECOneStep.onClickPayButton()
      })
      .mount("#kec-pay-button");
  },

  onCartUpdated() {
    window.requestAnimationFrame(() => {
      KECOneStep.mountButton();
    });
  },

  /**
   * Initialize the Klarna Express Checkout script for One Step Checkout.
   *
   * @returns {Promise<void>}
   */
  init: async function (e) {
    KECOneStep.params = configData;
    KECOneStep.Klarna = klarna_interoperability.Klarna;

    KECOneStep.mountButton();

    KECOneStep.Klarna.Payment.on("shippingaddresschange", KECOneStep.onShippingAddressChange);
    KECOneStep.Klarna.Payment.on("shippingoptionselect", KECOneStep.onShippingOptionSelect);

    // Listen for the WooCommerce variation change event and set the selected variation ID.
    $(document.body).on("found_variation", KECOneStep.onFoundVariation);
    KECOneStep.hasBoundEvents = true;
    

    $(document.body).on(
      "updated_cart_totals added_to_cart removed_from_cart updated_checkout updated_wc_div wc-blocks_added_to_cart wc-blocks_removed_from_cart",
      KECOneStep.onCartUpdated
    );

  },

  /**
   * Checks if we are on a product page, and if so, if the product is a variable product.
   * If it is, it will see if the customer has selected a variation.
   *
   * @returns {boolean} True if we can continue, or if we need to wait for a variation to be set.
   */
  checkVariation() {
    const { source, is_variation } = KECOneStep.params;

    if (source === 'cart' || !is_variation) {
      return true;
    }

    return KECOneStep.variationId !== null; // Variation must be selected to continue
  },

  /**
   * Handle the found variation event.
   *
   * @param {object} event
   * @param {object} variation
   *
   * @returns {void}
   */
  onFoundVariation(event, variation) {
    KECOneStep.variationId = variation.variation_id;
  },

  /**
   * Handle the initiate request from Klarna when the customer clicks the payment button.
   *
   * @return {Promise<Object>} The payment request object.
   */
  onClickPayButton: async function () {
    if( KECOneStep.isInitiating ) {
      return;
    }
    KECOneStep.isInitiating = true;

    const { url, nonce, method } = KECOneStep.params.ajax.get_initiate_body;

    const result = await $.ajax({
      type: method,
      url: url,
      data: {
        nonce: nonce,
        source: KECOneStep.params.source,
        variation_id: KECOneStep.variationId,
      },
    });

    if (result.error) {
      console.error("Error initiating Klarna payment:", result.error);
      throw new Error(result.error);
    }

    const body = result.data || {};
    return body;
  },

  onShippingAddressChange: async function (data, shippingAddress) {
    const { url, nonce, method } = KECOneStep.params.ajax.shipping_change;

    const result = await $.ajax({
      type: method,
      url: url,
      data:{
        nonce: nonce,
        shippingAddress: shippingAddress,
        paymentRequestId: data.paymentRequestId,
        paymentToken: data.stateContext.paymentToken
      },
    });

    if (result.error) {
      throw new Error(result.error);
    }

    const body = result.data || {};

    return body
  },

  onShippingOptionSelect: async function (_, shippingOption) {
    const { url, nonce, method } = KECOneStep.params.ajax.shipping_option_change;

    const result = await $.ajax({
      type: method,
      url: url,
      data: {
        nonce: nonce,
        selectedOption: shippingOption.shippingOptionReference
      },
    });

    if (result.error) {
      console.error("Error updating selected shipping method:", result.error);
      throw new Error(result.error);
    }

    const body = result.data || {};

    return body
  },
}

window.kecOneStep = KECOneStep;

$('body').on('klarna_wc_sdk_loaded', KECOneStep.init);
