import { useEffect, useState } from "react";
import {
  PaymentRequestButtonElement,
  useStripe,
  useElements,
} from "@stripe/react-stripe-js";
import { PaymentRequest } from "@stripe/stripe-js";
import styles from "./styles.module.css";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import { IPaywallProduct } from "@/api/resources/Paywall";

interface ApplePayButtonProps {
  activeProduct: IPaywallProduct | null;
  client_secret: string;
  subscriptionReceiptId?: string;
  returnUrl?: string;
  setCanMakePayment?: (isCanMakePayment: boolean) => void;
}

function ApplePayButton({
  activeProduct,
  client_secret,
  subscriptionReceiptId,
  returnUrl,
  setCanMakePayment,
}: ApplePayButtonProps) {
  const stripe = useStripe();
  const elements = useElements();
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
    null
  );

  const getAmountFromProduct = (subPlan: IPaywallProduct) => {
    if (subPlan.isTrial) {
      return subPlan.trialPrice;
    }
    return subPlan.price;
  };

  useEffect(() => {
    if (!stripe || !elements || !activeProduct) {
      return;
    }

    const pr = stripe.paymentRequest({
      country: "US",
      currency: "usd",
      total: {
        label: activeProduct.name || "Subscription",
        amount: getAmountFromProduct(activeProduct),
      },
      requestPayerName: true,
      requestPayerEmail: true,
    });

    pr.canMakePayment().then((result) => {
      if (result) {
        setPaymentRequest(pr);
        setCanMakePayment?.(true);
      }
    });

    pr.on("paymentmethod", async (e) => {
      const { error: stripeError, paymentIntent } =
        await stripe.confirmCardPayment(
          client_secret,
          {
            payment_method: e.paymentMethod.id,
          },
          { handleActions: false }
        );
      paymentIntent;

      if (stripeError) {
        // Show error to your customer (e.g., insufficient funds)
        navigate(
          `${routes.client.paymentResult()}/${subscriptionReceiptId}/?redirect_status=failed`
        );
        return e.complete("fail");
      }
      navigate(
        returnUrl ||
          `${routes.client.paymentResult()}/${subscriptionReceiptId}/?redirect_status=succeeded`
      );
      e.complete("success");
      // Show a success message to your customer
      // There's a risk of the customer closing the window before callback
      // execution. Set up a webhook or plugin to listen for the
      // payment_intent.succeeded event that handles any business critical
      // post-payment actions.
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    client_secret,
    dispatch,
    elements,
    navigate,
    stripe,
    subscriptionReceiptId,
  ]);

  return (
    <>
      {paymentRequest && (
        <PaymentRequestButtonElement
          className={styles["stripe-element"]}
          options={{
            paymentRequest,
            style: { paymentRequestButton: { height: "60px" } },
          }}
        />
      )}
    </>
  );
}

export default ApplePayButton;
