import Title from "@/components/Title";
import styles from "./styles.module.css";
import PaymentMethodsChoice from "../pages/TrialPayment/components/PaymentMethodsChoice";
import { useEffect, useMemo, useState } from "react";
import { EPaymentMethod, paymentMethods } from "@/data/paymentMethods";
import { Elements } from "@stripe/react-stripe-js";
import CheckoutForm from "@/components/PaymentPage/methods/CheckoutForm";
import { AvailablePaymentMethods, Stripe, loadStripe } from "@stripe/stripe-js";
import { useSelector } from "react-redux";
import { selectors } from "@/store";
import Loader from "@/components/Loader";
import SecurityPayments from "../pages/TrialPayment/components/SecurityPayments";
import { EPlacementKeys, IPaywallProduct } from "@/api/resources/Paywall";
import { usePaywall } from "@/hooks/paywall/usePaywall";
import { useMakePayment } from "@/hooks/payment/useMakePayment";
import ExpressCheckoutStripe from "@/components/PaymentPage/methods/ExpressCheckoutStripe";
import routes from "@/routes";
import { useNavigate } from "react-router-dom";

interface IPaymentModalProps {
  activeProduct?: IPaywallProduct;
  noTrial?: boolean;
  returnUrl?: string;
  placementKey: EPlacementKeys;
}

const getPrice = (product: IPaywallProduct | null) => {
  if (!product) {
    return 0;
  }
  return (product.trialPrice === 100 ? 99 : product.trialPrice || 0) / 100;
};

function PaymentModal({
  activeProduct,
  noTrial,
  returnUrl,
  placementKey,
}: IPaymentModalProps) {
  const navigate = useNavigate();
  const [stripePromise, setStripePromise] =
    useState<Promise<Stripe | null> | null>(null);

  const { products, placementId, paywallId } = usePaywall({
    placementKey,
  });
  const activeProductFromStore = useSelector(selectors.selectActiveProduct);

  const _activeProduct = activeProduct ? activeProduct : activeProductFromStore;
  const {
    paymentIntentId,
    clientSecret,
    returnUrl: checkoutUrl,
    paymentType,
    publicKey,
    isLoading: isLoadingPayment,
    error,
  } = useMakePayment({
    productId: _activeProduct?._id || "",
    placementId,
    paywallId,
    returnPaidUrl: returnUrl,
  });

  const [availableMethods, setAvailableMethods] = useState<
    AvailablePaymentMethods | undefined
  >();

  const [isLoadingExpressCheckout, setIsLoadingExpressCheckout] =
    useState(true);

  const isLoading = useMemo(() => {
    return isLoadingPayment || isLoadingExpressCheckout;
  }, [isLoadingPayment, isLoadingExpressCheckout]);

  if (checkoutUrl?.length) {
    window.location.href = checkoutUrl;
  }

  const paymentMethodsButtons = useMemo(() => {
    return paymentMethods(availableMethods || null);
  }, [availableMethods]);

  const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(
    paymentMethodsButtons[0].id
  );

  const onSelectPaymentMethod = (method: EPaymentMethod) => {
    setSelectedPaymentMethod(method);
  };

  useEffect(() => {
    (async () => {
      if (!products?.length || !publicKey) return;
      setStripePromise(loadStripe(publicKey));
      const isActiveProduct = products.find(
        (product) => product._id === _activeProduct?._id
      );
      if (!_activeProduct || !isActiveProduct) {
        navigate(routes.client.trialChoice());
      }
    })();
  }, [_activeProduct, navigate, products, publicKey]);

  const onAvailableExpressCheckout = (
    isAvailable: boolean,
    availableMethods: AvailablePaymentMethods | undefined
  ) => {
    if (isAvailable && availableMethods) {
      setAvailableMethods(availableMethods);
      return setSelectedPaymentMethod(EPaymentMethod.PAYMENT_BUTTONS);
    }
    return setAvailableMethods(undefined);
  };

  if (error?.length) {
    return (
      <div className={styles["payment-modal"]}>
        <Title variant="h3" className={styles.title}>
          Something went wrong
        </Title>
      </div>
    );
  }

  return (
    <>
      {isLoading && (
        <div className={styles["payment-modal"]}>
          <div className={styles["payment-loader"]}>
            <Loader />
          </div>
        </div>
      )}
      <div
        className={`${styles["payment-modal"]} ${isLoading ? styles.hide : ""}`}
      >
        <Title variant="h3" className={styles.title}>
          Choose payment method
        </Title>
        <PaymentMethodsChoice
          paymentMethods={paymentMethodsButtons}
          selectedPaymentMethod={selectedPaymentMethod}
          onSelectPaymentMethod={onSelectPaymentMethod}
        />
        {_activeProduct && (
          <div>
            {!noTrial && (
              <>
                <p className={styles["sub-plan-description"]}>
                  You will be charged only{" "}
                  <b>${getPrice(_activeProduct)} for your 3-day trial.</b>
                </p>
                <p className={styles["sub-plan-description"]}>
                  We`ll <b>email you a reminder</b> before your trial period
                  ends.
                </p>
              </>
            )}

            <p className={styles["sub-plan-description"]}>
              Cancel anytime. The charge will appear on your bill as witapps.
            </p>
          </div>
        )}
        <div className={styles["payment-method-container"]}>
          {stripePromise && clientSecret && (
            <>
              <Elements stripe={stripePromise} options={{ clientSecret }}>
                <ExpressCheckoutStripe
                  clientSecret={clientSecret}
                  returnUrl={returnUrl}
                  isHide={
                    selectedPaymentMethod !== EPaymentMethod.PAYMENT_BUTTONS
                  }
                  onAvailable={(_isAvailable, _availableMethods) =>
                    onAvailableExpressCheckout(_isAvailable, _availableMethods)
                  }
                  onChangeLoading={(isLoading) =>
                    setIsLoadingExpressCheckout(isLoading)
                  }
                />
              </Elements>
              <Elements stripe={stripePromise} options={{ clientSecret }}>
                <CheckoutForm
                  confirmType={paymentType}
                  subscriptionReceiptId={paymentIntentId}
                  returnUrl={returnUrl}
                  isHide={selectedPaymentMethod !== EPaymentMethod.CREDIT_CARD}
                />
              </Elements>
            </>
          )}
        </div>
        <SecurityPayments />
        <p className={styles.address}>1123 Rimer Dr Moraga, California 94556</p>
      </div>
    </>
  );
}

export default PaymentModal;
