/* eslint-disable */
(function (wp, window) {
  "use strict";

  const { createElement, useEffect, useRef, useState } = wp.element || {};
  const { __ } = wp.i18n || {};
  const registerPaymentMethod =
    window.wc?.wcBlocksRegistry?.registerPaymentMethod ||
    window.wc?.blocks?.registerPaymentMethod ||
    null;

  function getNmiSettings() {
    const settings = window.wc?.wcSettings?.getSetting(
      "peachpay_nmi_card_data",
      null
    );
    if (!settings) {
      return {};
    }
    return settings;
  }

  const settings = getNmiSettings();

  // Determine payment mode - check multiple ways
  const isDirectPost = settings.isDirectPost === true || settings.isDirectPost === "true" || settings.isDirectPost === 1;

  // Validate tokenization key (only for Collect.js mode)
  const publicTokenizationKey =
    typeof settings.publicTokenizationKey === "string"
      ? settings.publicTokenizationKey.trim()
      : "";
  const hasValidKey = !isDirectPost && publicTokenizationKey.length >= 10;

  // Store the last error for better debugging
  let lastTransactionError = null;

  async function createTransactionIfNeeded() {
    if (window.peachpayTransactionId) return window.peachpayTransactionId;

    const ajaxConfig =
      window.peachpay_nmi_card_ajax || settings.ajax_config || {};
    const url =
      ajaxConfig.create_transaction_url ||
      ajaxConfig.ajax_url ||
      window.ajaxurl;

    if (!url) {
      lastTransactionError = "AJAX configuration not found";
      throw new Error(lastTransactionError);
    }

    const formData = new FormData();
    formData.append("gateway_id", "peachpay_nmi_card");
    formData.append("checkout_location", "checkout-blocks");

    if (!ajaxConfig.create_transaction_url?.includes("admin-ajax.php")) {
      // Use centralized PeachPay endpoint
    } else {
      formData.append("action", "pp-create-transaction");
      if (ajaxConfig.nonce) formData.append("nonce", ajaxConfig.nonce);
    }

    try {
      const response = await fetch(url, {
        method: "POST",
        body: formData,
        credentials: "same-origin",
      });

      if (!response.ok) {
        lastTransactionError = `Server error: HTTP ${response.status}`;
        console.error("NMI Blocks: Transaction creation failed -", lastTransactionError);
        throw new Error(lastTransactionError);
      }

      const responseText = await response.text();

      let json;
      try {
        json = JSON.parse(responseText);
      } catch (parseError) {
        lastTransactionError = "Invalid server response (not JSON)";
        console.error("NMI Blocks: Transaction creation failed -", lastTransactionError, responseText);
        throw new Error(lastTransactionError);
      }

      // Check for error message in response
      if (!json.success) {
        lastTransactionError = json.message || json.data?.message || "Transaction creation failed";
        console.error("NMI Blocks: Transaction creation failed -", lastTransactionError);
        throw new Error(lastTransactionError);
      }

      if (json.success && json.data?.transaction_id) {
        window.peachpayTransactionId = String(json.data.transaction_id);
        lastTransactionError = null;
        return window.peachpayTransactionId;
      }

      lastTransactionError = "No transaction ID in response";
      throw new Error(lastTransactionError);
    } catch (error) {
      lastTransactionError = error.message || "Unknown error creating transaction";
      console.error("NMI Blocks: Transaction creation error -", lastTransactionError);
      throw error;
    }
  }

  function getLastTransactionError() {
    return lastTransactionError;
  }

  // =====================================================
  // DIRECT POST CONTENT COMPONENT
  // =====================================================
  function DirectPostContent(props) {
    const { eventRegistration, emitResponse } = props || {};
    const [cardNumber, setCardNumber] = useState("");
    const [cardExp, setCardExp] = useState("");
    const [cardCvv, setCardCvv] = useState("");
    const [error, setError] = useState("");
    const isProcessing = useRef(false);

    // Format card number with spaces
    const formatCardNumber = (value) => {
      const digits = value.replace(/\D/g, "").substring(0, 16);
      const groups = digits.match(/.{1,4}/g);
      return groups ? groups.join(" ") : digits;
    };

    // Format expiration date MM/YY
    const formatExpDate = (value) => {
      const digits = value.replace(/\D/g, "").substring(0, 4);
      if (digits.length >= 2) {
        return digits.substring(0, 2) + "/" + digits.substring(2);
      }
      return digits;
    };

    // Payment handler for Direct Post
    useEffect(() => {
      if (!eventRegistration?.onPaymentSetup) return;

      const unsubscribe = eventRegistration.onPaymentSetup(async () => {
        if (isProcessing.current) return;
        isProcessing.current = true;

        try {
          // Validate card fields
          const cleanCardNumber = cardNumber.replace(/\s/g, "");
          if (!cleanCardNumber || cleanCardNumber.length < 13) {
            setError(__("Please enter a valid card number.", "peachpay"));
            isProcessing.current = false;
            return {
              type: emitResponse.responseTypes.ERROR,
              message: __("Please enter a valid card number.", "peachpay"),
            };
          }

          if (!cardExp || cardExp.length < 5) {
            setError(__("Please enter a valid expiration date (MM/YY).", "peachpay"));
            isProcessing.current = false;
            return {
              type: emitResponse.responseTypes.ERROR,
              message: __("Please enter a valid expiration date.", "peachpay"),
            };
          }

          if (!cardCvv || cardCvv.length < 3) {
            setError(__("Please enter a valid CVV.", "peachpay"));
            isProcessing.current = false;
            return {
              type: emitResponse.responseTypes.ERROR,
              message: __("Please enter a valid CVV.", "peachpay"),
            };
          }

          // Create transaction ID if needed (backend will create fallback if this fails)
          if (!window.peachpayTransactionId) {
            try {
              await createTransactionIfNeeded();
            } catch (e) {
              // Backend will handle fallback transaction creation
            }
          }

          // Generate a client-side fallback if still no transaction ID
          const transactionId = window.peachpayTransactionId || "nmi_blocks_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);

          setError("");
          isProcessing.current = false;

          // Send card data to server via paymentMethodData
          // The PHP process_payment will handle this
          return {
            type: emitResponse.responseTypes.SUCCESS,
            meta: {
              paymentMethodData: {
                nmi_cc_number: cleanCardNumber,
                nmi_cc_exp: cardExp,
                nmi_cc_cvv: cardCvv,
                peachpay_transaction_id: transactionId,
                is_direct_post: "1",
              },
            },
          };
        } catch (err) {
          isProcessing.current = false;
          setError(err.message);
          return {
            type: emitResponse.responseTypes.ERROR,
            message: err.message,
          };
        }
      });

      return () => unsubscribe();
    }, [eventRegistration, emitResponse, cardNumber, cardExp, cardCvv]);

    const inputStyle = {
      width: "100%",
      padding: "10px 12px",
      fontSize: "16px",
      border: "1px solid #d1d5db",
      borderRadius: "4px",
      boxSizing: "border-box",
    };

    const labelStyle = {
      display: "block",
      marginBottom: "4px",
      fontWeight: "500",
      fontSize: "14px",
    };

    return createElement(
      "div",
      { className: "nmi-direct-post-fields", style: { padding: "10px 0" } },
      settings.description && createElement(
        "p",
        { style: { margin: "0 0 15px", fontSize: "14px", color: "#666" } },
        settings.description
      ),
      // Card Number
      createElement(
        "div",
        { style: { marginBottom: "15px" } },
        createElement("label", { style: labelStyle }, __("Card Number", "peachpay") + " *"),
        createElement("input", {
          type: "text",
          value: cardNumber,
          onChange: (e) => setCardNumber(formatCardNumber(e.target.value)),
          placeholder: "•••• •••• •••• ••••",
          maxLength: 19,
          autoComplete: "cc-number",
          style: inputStyle,
        })
      ),
      // Exp + CVV row
      createElement(
        "div",
        { style: { display: "flex", gap: "15px" } },
        // Expiration
        createElement(
          "div",
          { style: { flex: 1 } },
          createElement("label", { style: labelStyle }, __("Expiry (MM/YY)", "peachpay") + " *"),
          createElement("input", {
            type: "text",
            value: cardExp,
            onChange: (e) => setCardExp(formatExpDate(e.target.value)),
            placeholder: "MM / YY",
            maxLength: 5,
            autoComplete: "cc-exp",
            style: inputStyle,
          })
        ),
        // CVV
        createElement(
          "div",
          { style: { flex: 1 } },
          createElement("label", { style: labelStyle }, __("CVV", "peachpay") + " *"),
          createElement("input", {
            type: "text",
            value: cardCvv,
            onChange: (e) => setCardCvv(e.target.value.replace(/\D/g, "").substring(0, 4)),
            placeholder: "CVV",
            maxLength: 4,
            autoComplete: "cc-csc",
            style: inputStyle,
          })
        )
      ),
      // Error message
      error &&
        createElement(
          "div",
          { style: { color: "#dc2626", marginTop: "10px", fontSize: "14px" } },
          error
        )
    );
  }

  // =====================================================
  // COLLECT.JS CONTENT COMPONENT
  // =====================================================
  let collectJsInitLogged = false;
  function CollectJsContent(props) {
    const { eventRegistration, emitResponse } = props || {};
    const containerRef = useRef(null);
    const isCreatingTransaction = useRef(false);
    const collectJsReady = useRef(false);
    const isInitialized = useRef(false);
    const isSubmittingPayment = useRef(false);

    const hideLoading = () => {
      const loadingEl = document.getElementById("nmi-loading");
      if (loadingEl) loadingEl.style.display = "none";
    };

    const showError = (msg) => {
      hideLoading();
      const el = document.getElementById("nmi-error-message");
      if (el) {
        el.textContent = msg;
        el.style.display = "block";
      }
    };

    const hideError = () => {
      const el = document.getElementById("nmi-error-message");
      if (el) {
        el.style.display = "none";
      }
    };

    useEffect(() => {
      // Prevent multiple initializations
      if (isInitialized.current) return;
      isInitialized.current = true;
      
      if (!collectJsInitLogged) {
        collectJsInitLogged = true;
      }
      
      // Hide loading immediately if no valid key
      if (!hasValidKey) {
        hideLoading();
        showError(
          __("Collect.js is not configured. Please add your Public Tokenization Key in the NMI settings.", "peachpay")
        );
        return;
      }

      const init = () => {
        if (!window.CollectJS || !containerRef.current) return;

        if (!document.getElementById("nmi-blocks-checkout-styles")) {
          const style = document.createElement("style");
          style.id = "nmi-blocks-checkout-styles";
          document.head.appendChild(style);
        }

        containerRef.current.innerHTML = `
          <div id="nmi-collect-container">
            <div class="payment-field" style="margin-bottom:15px;">
              <label>${__("Card Number", "peachpay")}</label>
              <div id="ccnumber"></div>
            </div>
            <div style="display:flex; gap:10px;">
              <div style="flex:1;">
                <label>${__("Expiration", "peachpay")}</label>
                <div id="ccexp"></div>
              </div>
              <div style="flex:1;">
                <label>${__("CVV", "peachpay")}</label>
                <div id="nmi-cvv"></div>
              </div>
            </div>
          </div>
        `;

        // Initialize token resolve/reject callbacks
        window.nmiTokenResolve = null;
        window.nmiTokenReject = null;

        window.CollectJS.configure({
          fields: {
            ccnumber: { selector: "#ccnumber", title: "Card Number" },
            ccexp: { selector: "#ccexp", title: "Expiration" },
            cvv: { selector: "#nmi-cvv", title: "CVV" },
          },
          callback: (response) => {
            if (response.token) {
              window.nmiPaymentToken = response.token;
              hideError();

              const tokenInput = document.getElementById("nmi-payment-token");
              if (tokenInput) {
                tokenInput.value = response.token;
              }
              
              // Resolve pending promise if exists
              if (window.nmiTokenResolve) {
                window.nmiTokenResolve(response.token);
                window.nmiTokenResolve = null;
                window.nmiTokenReject = null;
              }
            } else {
              const errorMsg = response.error?.message || "Card tokenization failed";
              console.error("NMI Blocks: Collect.js error:", errorMsg);
              showError(errorMsg);
              
              // Reject pending promise if exists
              if (window.nmiTokenReject) {
                window.nmiTokenReject(new Error(errorMsg));
                window.nmiTokenResolve = null;
                window.nmiTokenReject = null;
              }
            }
          },
        });

        collectJsReady.current = true;
        hideLoading();
      };

      // Wait for Collect.js to be loaded (max 8 seconds)
      let attempts = 0;
      const maxAttempts = 8;
      const timer = setInterval(() => {
        attempts++;
        if (window.CollectJS) {
          clearInterval(timer);
          init();
        } else if (attempts >= maxAttempts) {
          clearInterval(timer);
          console.error("NMI Blocks CollectJS: Library not loaded after timeout");
          hideLoading();
          showError(__("The payment library (CollectJS) did not load correctly. Please refresh the page and try again.", "peachpay"));
        }
      }, 500);

      return () => {
        clearInterval(timer);
        isInitialized.current = false;
      };
    }, []);

    // Payment handler (onPaymentSetup)
    useEffect(() => {
      if (!eventRegistration?.onPaymentSetup) return;

      const unsubscribe = eventRegistration.onPaymentSetup(async () => {
        // Check if properly configured
        if (!hasValidKey) {
          return {
            type: emitResponse.responseTypes.ERROR,
            message: __(
              "Collect.js is not configured. Please contact the store administrator.",
              "peachpay"
            ),
          };
        }

        // Avoid multiple parallel executions
        if (isSubmittingPayment.current || isCreatingTransaction.current) {
          return {
            type: emitResponse.responseTypes.ERROR,
            message: __("Your payment is already being processed. Please wait a moment.", "peachpay"),
          };
        }

        try {
          isSubmittingPayment.current = true;

          // Create transaction if it doesn't exist
          if (!window.peachpayTransactionId) {
            isCreatingTransaction.current = true;
            try {
              await createTransactionIfNeeded();
            } catch (transactionError) {
              console.warn(
                "NMI Blocks: Transaction creation failed, using fallback transaction id instead",
                transactionError.message || transactionError
              );
            }
            isCreatingTransaction.current = false;
          }

          // Check for existing token first
          let token = window.nmiPaymentToken;
          const tokenInput = document.getElementById("nmi-payment-token");
          if (!token && tokenInput && tokenInput.value) {
            token = tokenInput.value;
            window.nmiPaymentToken = token;
          }

          // If no token, trigger Collect.js tokenization manually
          if (!token && window.CollectJS && collectJsReady.current) {
            // Clear any previous token
            window.nmiPaymentToken = null;
            
            token = await new Promise((resolve, reject) => {
              const timeout = setTimeout(() => {
                const lastError = getLastTransactionError();
                const timeoutMsg = lastError 
                  ? `Payment failed: ${lastError}` 
                  : __("Tokenization timeout - please try again", "peachpay");
                reject(new Error(timeoutMsg));
              }, 15000);

              // Store resolve/reject for the callback to use
              window.nmiTokenResolve = (tokenValue) => {
                clearTimeout(timeout);
                resolve(tokenValue);
              };
              window.nmiTokenReject = (error) => {
                clearTimeout(timeout);
                reject(error);
              };

              // Trigger tokenization - use startPaymentRequest
              try {
                window.CollectJS.startPaymentRequest();
              } catch (collectError) {
                clearTimeout(timeout);
                reject(new Error(collectError.message || "Failed to start payment request"));
              }
            }).catch((err) => {
              console.error("NMI Blocks: Tokenization error:", err.message);
              showError(err.message);
              return null;
            });
          }

          if (!token) {
            return {
              type: emitResponse.responseTypes.ERROR,
              message: __(
                "Please verify your card details and try again.",
                "peachpay"
              ),
            };
          }

          if (tokenInput) {
            tokenInput.value = token;
          }

          // Generate a client-side fallback if still no transaction ID
          const transactionId = window.peachpayTransactionId || "nmi_blocks_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);

          hideError();

          return {
            type: emitResponse.responseTypes.SUCCESS,
            meta: {
              paymentMethodData: {
                nmi_payment_token: String(token),
                peachpay_transaction_id: transactionId,
              },
            },
          };
        } catch (err) {
          return {
            type: emitResponse.responseTypes.ERROR,
            message: err.message,
          };
        } finally {
          isCreatingTransaction.current = false;
          isSubmittingPayment.current = false;
        }
      });

      return () => unsubscribe();
    }, [eventRegistration, emitResponse]);

    return createElement(
      "div",
      { className: "wc-nmi-blocks-content" },
      // Description
      settings.description && createElement(
        "p",
        { style: { margin: "0 0 15px", fontSize: "14px", color: "#666" } },
        settings.description
      ),
      createElement(
        "div",
        { id: "nmi-loading" },
        __("Loading payment form...", "peachpay")
      ),
      createElement("div", {
        ref: containerRef,
        id: "nmi-component-container",
      }),
      createElement("div", {
        id: "nmi-error-message",
        style: { color: "red", display: "none", marginTop: "10px" },
      }),
      createElement("input", {
        type: "hidden",
        id: "nmi-payment-token",
        name: "nmi_payment_token",
        value: "",
      }),
      createElement("input", {
        type: "hidden",
        id: "peachpay-transaction-id",
        name: "peachpay_transaction_id",
        value: "",
      })
    );
  }

  // =====================================================
  // MAIN CONTENT COMPONENT (Route based on mode)
  // =====================================================
  let contentRenderLogged = false;
  function NMIContent(props) {
    // Only log once to avoid console spam
    if (!contentRenderLogged) {
      contentRenderLogged = true;
    }
    
    // Use Direct Post or Collect.js based on settings
    if (isDirectPost) {
      return createElement(DirectPostContent, props);
    }
    return createElement(CollectJsContent, props);
  }

  const NMIPaymentMethod = {
    name: "peachpay_nmi_card",
    label: settings.title,
    content: createElement(NMIContent),
    edit: createElement(NMIContent),
    canMakePayment: () => true,
    ariaLabel: settings.title,
    supports: { features: settings.supports || ["products"] },
  };

  if (registerPaymentMethod) {
    registerPaymentMethod(NMIPaymentMethod);
  }
})(window.wp || {}, window);
