import { jsx, jsxs } from "../../packages/jsx/src/jsx-runtime.js";
import { createActorContext } from "@xstate/react";
import { constants } from "ethers";
import { useEffect } from "react";
import { ApprovalFlowStep } from "./ApprovalFlowStep.js";
import { approvalFlowMachine } from "./machine/approval-flow.machine.js";
import { Icon } from "../../atoms/Icon/Icon.js";
const ApprovalMachineContext = createActorContext(approvalFlowMachine);
function ApprovalFlow(props) {
  return /* @__PURE__ */ jsx(
    ApprovalMachineContext.Provider,
    {
      machine: () => approvalFlowMachine.withContext({
        ethereumAccount: props.ethereumAccount,
        approvalContract: props.approvalContract,
        spender: props.contractAddress,
        vestingContract: props.vestingContract ?? null,
        vestingContractAddress: props.vestingContractAddress || null,
        allowedAmount: constants.Zero,
        // using a separate state for approval permit allowance to prevent edge case where a user has allowed with `approve`
        // and the ApprovalFlow moves to action step without getting permit signature
        allowedPermitAmount: constants.Zero,
        approvalAmount: null,
        approvalConfirmations: props.approvalConfirmations,
        approvalPermit: null,
        permitApprovalInput: props.permitApprovalInput
      }),
      children: /* @__PURE__ */ jsx(ApprovalFlowLogic, { ...props })
    }
  );
}
function ApprovalFlowLogic({
  ethereumAccount,
  approvalContract,
  contractAddress,
  requestedAmount,
  disabled = false,
  allowStepLabel,
  allowStepActionText,
  allowStepActionIcon = /* @__PURE__ */ jsx(Icon.LogoArbitrum, {}),
  allowStepTooltip,
  actionStepLabel,
  actionStepActionText,
  actionStepActionIcon = /* @__PURE__ */ jsx(Icon.LogoArbitrum, {}),
  actionStepStatus,
  actionStepLoadingProgress,
  handleAction,
  onApprove,
  permitApprovalInput,
  isMultisig = false,
  showStepNumber = true
}) {
  const actorRef = ApprovalMachineContext.useActorRef();
  const usePermitApproval = permitApprovalInput != null;
  const ethAccount = ApprovalMachineContext.useSelector((state) => state.context.ethereumAccount);
  const approvalContractInCtx = ApprovalMachineContext.useSelector((state) => state.context.approvalContract);
  const spender = ApprovalMachineContext.useSelector((state) => state.context.spender);
  const userPermitAllowanceAmount = ApprovalMachineContext.useSelector((state) => state.context.allowedPermitAmount);
  const userAllowanceAmount = ApprovalMachineContext.useSelector((state) => state.context.allowedAmount);
  const allowStepStatus = ApprovalMachineContext.useSelector((state) => {
    if (state.matches("allowance_retrieved.update_allowance_amount") || state.matches("allowance_retrieved.completing_allowance_approval") || state.matches("allowance_retrieved.update_allowance_permit_amount")) {
      return "loading";
    } else if (state.matches("allowance_retrieved.update_allowance_failure")) {
      return "error";
    }
    return void 0;
  });
  const activeStep = ApprovalMachineContext.useSelector((state) => {
    switch (true) {
      case requestedAmount.eq(constants.Zero): {
        return "allow";
      }
      case requestedAmount.lte(usePermitApproval ? state.context.allowedPermitAmount : state.context.allowedAmount): {
        return "action";
      }
      default: {
        return "allow";
      }
    }
  });
  const approvalPermit = ApprovalMachineContext.useSelector((state) => state.context.approvalPermit);
  useEffect(() => {
    if (ethereumAccount != null && ethAccount == null || ethereumAccount != null && ethAccount != null && ethereumAccount.toLowerCase() !== ethAccount.toLowerCase()) {
      actorRef.send({ type: "SET_ETHEREUM_ACCOUNT", payload: ethereumAccount });
    }
  }, [ethereumAccount, ethAccount]);
  useEffect(() => {
    async function compareApprovalContracts() {
      const approvalContractSigner = (approvalContract == null ? void 0 : approvalContract.signer) ?? null;
      const approvalContractInCtxSigner = (approvalContractInCtx == null ? void 0 : approvalContractInCtx.signer) ?? null;
      if (approvalContractInCtxSigner != null && approvalContractSigner != null) {
        const approvalContractSignerAddress = await approvalContractSigner.getAddress();
        const approvalContractInCtxSignerAddress = await approvalContractInCtxSigner.getAddress();
        if (approvalContractSignerAddress && approvalContractInCtxSignerAddress && approvalContractSignerAddress.toLowerCase() !== approvalContractInCtxSignerAddress.toLowerCase()) {
          actorRef.send({ type: "SET_APPROVAL_CONTRACT", payload: approvalContract });
        }
      }
    }
    void compareApprovalContracts();
  }, [approvalContract, approvalContractInCtx, actorRef]);
  useEffect(() => {
    if (contractAddress != null && contractAddress !== spender) {
      actorRef.send({ type: "SET_SPENDER", payload: contractAddress });
    }
  }, [contractAddress, spender]);
  const onAllowAmount = (amount) => {
    onApprove == null ? void 0 : onApprove();
    actorRef.send({ type: "UPDATE_ALLOWANCE", payload: amount });
  };
  const onPermitAllow = (amount) => {
    onApprove == null ? void 0 : onApprove();
    actorRef.send({ type: "UPDATE_ALLOWANCE_PERMIT", payload: amount });
  };
  if (ethereumAccount == null || approvalContract == null) {
    return null;
  }
  return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-y-8", children: [
    usePermitApproval ? /* @__PURE__ */ jsx(
      ApprovalFlowStep.Permit,
      {
        requestedAmount,
        userAllowanceAmount: userPermitAllowanceAmount,
        stepLabel: allowStepLabel,
        actionText: allowStepActionText,
        stepTooltip: allowStepTooltip,
        handleAllowAmount: onPermitAllow,
        active: activeStep === "allow",
        disabled,
        status: allowStepStatus,
        showStepNumber
      }
    ) : /* @__PURE__ */ jsx(
      ApprovalFlowStep.Allowance,
      {
        requestedAmount,
        userAllowanceAmount,
        stepLabel: allowStepLabel,
        actionText: allowStepActionText,
        actionIcon: allowStepActionIcon,
        stepTooltip: allowStepTooltip,
        handleAllowAmount: onAllowAmount,
        active: activeStep === "allow",
        disabled,
        status: allowStepStatus,
        isMultisig,
        showStepNumber
      }
    ),
    /* @__PURE__ */ jsx(
      ApprovalFlowStep.Action,
      {
        actionAmount: requestedAmount,
        userAllowanceAmount: usePermitApproval ? userPermitAllowanceAmount : userAllowanceAmount,
        stepLabel: actionStepLabel,
        actionText: actionStepActionText,
        actionIcon: actionStepActionIcon,
        handleAction,
        active: activeStep === "action",
        disabled,
        status: actionStepStatus,
        approvalPermit,
        loadingProgress: actionStepLoadingProgress,
        isMultisig,
        showStepNumber
      }
    )
  ] });
}
export {
  ApprovalFlow
};
