import { WidgetIntegrationPayload } from "@src/models";
import { isServer } from "@tanstack/react-query";
import { useEffect } from "react";
import { createTxWidgetWC, TxWidgetWCAttributes } from "../TxWidgetWC";

const TxWidgetWC = createTxWidgetWC();

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace JSX {
    interface IntrinsicElements {
      "xpay-widget": React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement>,
        HTMLElement
      > &
        TxWidgetWCAttributes;
    }
  }
}

if (!isServer && typeof customElements !== "undefined") {
  if (!customElements.get("xpay-widget")) {
    customElements.define("xpay-widget", TxWidgetWC);
  }
}

export const TxWidgetWCWrapped = ({
  integratorId,
  dstChain,
  dstToken,
  srcChain,
  srcToken,
  customContractCalls = [],
  desc,
  dstDisplayToken,
  lightTheme,
  defaultWalletPicker,
  styles,
  onPendingTransactionsChange,
  dstTokenLocked,
  dstChainLocked,
  srcTokenLocked,
  srcChainLocked,
  onDstTokenChange,
  onDstChainChange,
  onSrcTokenChange,
  onSrcChainChange,
  onConnectWallet,
  bridge,
  override,
  integratorFee,
  integratorFeeReceiverAddress,
  highlightedDstTokens,
  wagmiConfig,
}: WidgetIntegrationPayload) => {
  // Must be synchronous: the WC mounts its inner React tree before useEffect fires.
  if (typeof window !== "undefined") {
    window.xPayWagmiConfig = wagmiConfig;
  }

  useEffect(() => {
    // We couldn't find a way to pass a function to the web component created by @r2wc/core.
    // It is assigned to window to be accessed later from within the web component.
    window.xPayOnPendingTransactionsChange = onPendingTransactionsChange;
    window.xPayOnDstTokenChange = onDstTokenChange;
    window.xPayOnDstChainChange = onDstChainChange;
    window.xPayOnSrcTokenChange = onSrcTokenChange;
    window.xPayOnSrcChainChange = onSrcChainChange;
    window.xPayOnConnectWallet = onConnectWallet;
  }, [
    onPendingTransactionsChange,
    onDstTokenChange,
    onDstChainChange,
    onSrcTokenChange,
    onSrcChainChange,
    onConnectWallet,
  ]);

  return (
    <xpay-widget
      integrator-id={integratorId}
      dst-chain={dstChain}
      dst-token={dstToken}
      src-chain={srcChain}
      src-token={srcToken}
      custom-contract-calls={JSON.stringify(customContractCalls)}
      desc={desc}
      dst-display-token={dstDisplayToken}
      light-theme={lightTheme}
      default-wallet-picker={defaultWalletPicker}
      styles={typeof styles === "string" ? styles : JSON.stringify(styles)}
      dst-token-locked={dstTokenLocked}
      dst-chain-locked={dstChainLocked}
      src-token-locked={srcTokenLocked}
      src-chain-locked={srcChainLocked}
      bridge={bridge}
      override={JSON.stringify(override)}
      integrator-fee={integratorFee}
      integrator-fee-receiver-address={integratorFeeReceiverAddress}
      highlighted-dst-tokens={JSON.stringify(highlightedDstTokens)}
    ></xpay-widget>
  );
};
