/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useApi } from "@/api";
import {
  ResponsePost,
  ResponsePostAnonymousSuccess,
} from "@/api/resources/Payment";
import { useAuthentication } from "@/hooks/authentication/use-authentication";
import useElementRemovalObserver from "@/hooks/DOM/useElementRemovalObserver";
import { selectors } from "@/store";
import { useEffect, useMemo, useRef, useState } from "react";
import { useSelector } from "react-redux";
import { AddressFields } from "./useAddressFields";
import { IFunnelPaymentVariant } from "@/api/resources/Session";
import { ELocalesPlacement } from "@/locales";
import { useFunnel } from "@/hooks/funnel/useFunnel";

interface IUsePaymentProps {
  activeProduct: IFunnelPaymentVariant;
  paymentFormType?: "lightbox" | "inline";
  cardNumberRef?: React.RefObject<HTMLDivElement>;
  cardExpiryRef?: React.RefObject<HTMLDivElement>;
  cardCvvRef?: React.RefObject<HTMLDivElement>;
  isAnonymous?: boolean;
  sessionId?: string;
  funnel: ELocalesPlacement;
  paymentPlacement: string;
}

interface IFieldValidation {
  isValid: boolean;
  message: string;
}

interface IFormValidation {
  ccnumber: IFieldValidation;
  ccexp: IFieldValidation;
  cvv: IFieldValidation;
}

export const usePayment = ({
  activeProduct,
  paymentFormType = "lightbox",
  isAnonymous = false,
  sessionId = "",
  funnel,
  paymentPlacement,
}: IUsePaymentProps) => {
  const api = useApi();
  const token = useSelector(selectors.selectToken);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [paymentResponse, setPaymentResponse] = useState<
    ResponsePost | ResponsePostAnonymousSuccess
  >();
  const [error, setError] = useState<string | null>(null);
  const [isPaymentSuccess, setIsPaymentSuccess] = useState(false);
  const formPrice = String((activeProduct?.trialPrice || 99) / 100);
  const [isOpenModal, setIsOpenModal] = useState(false);
  const [isModalClosed, setIsModalClosed] = useState(false);
  const [formValidation, setFormValidation] = useState<IFormValidation>({
    ccnumber: { isValid: false, message: "" },
    ccexp: { isValid: false, message: "" },
    cvv: { isValid: false, message: "" },
  });
  const [isCollectJSLoaded, setIsCollectJSLoaded] = useState(false);
  const addressRef = useRef<AddressFields>({
    country: "",
    address: "",
    zip: "",
  });
  const [cardType, setCardType] = useState("");

  const { anonymousAuthorization } = useAuthentication();

  const isFormValid = useMemo(() => {
    return Object.values(formValidation).every((field) => field.isValid);
  }, [formValidation]);

  const updatePaymentModalState = () => {
    setIsOpenModal(false);
    setIsModalClosed(true);
  };

  useElementRemovalObserver("CollectJSIframe", updatePaymentModalState);

  // const { products, placementId, paywallId } = usePaywall({
  //     placementKey,
  // });

  const { isPending, products, placementId, paywallId } = useFunnel({
    funnel,
    paymentPlacement,
  });

  const isLoading = useMemo(() => {
    return isSubmitting || isPending;
  }, [isSubmitting, isPending]);

  useEffect(() => {
    if (!activeProduct || !products.length) return;
    const product = products.find((product) => product.id === activeProduct.id);
    if (!product) {
      setError("Product not found");
    } else {
      setError(null);
    }
  }, [products, activeProduct]);

  useEffect(() => {
    const checkCollectJSLoaded = () => {
      if (window.CollectJS) {
        setIsCollectJSLoaded(true);
        return true;
      }
      return false;
    };

    const configureCollectJS = () => {
      if (!checkCollectJSLoaded()) {
        console.warn("CollectJS not loaded yet, retrying...");
        return false;
      }

      const config: unknown = {
        variant: paymentFormType,
        callback: (token: unknown) => {
          finishSubmit(token);
        },
        paymentSelector: "#customPayButton",
        primaryColor: "#066fde",
        theme: "material",
        price: formPrice,
        styleSniffer: true,
        customCss: {
          "background-color": "#F0F5FF",
          height: "51px",
          padding: "11px 0",
          "letter-spacing": "6px",
          border: "none",
          "font-size": "18px",
          "margin-right": "auto",
          "margin-left": "auto",
        },
        focusCss: {
          border: "none",
        },
        placeholderCss: {
          "letter-spacing": "6px",
          "font-size": "18px",
        },
        fields: {
          ccnumber: {
            placeholder: "____ ____ ____ ____",
            selector: "#card-number",
            title: "Card Number",
            // enableCardBrandPreviews: true
          },
          ccexp: {
            placeholder: "__ / __",
            selector: "#card-expiry",
            title: "Card Expiry",
          },
          cvv: {
            placeholder: "CVC",
            selector: "#card-cvv",
            title: "Card CVC",
            // display: "hide"
          },
        },
        validationCallback: (
          field: string,
          status: boolean,
          message: string
        ) => {
          setFormValidation((prev) => ({
            ...prev,
            [field]: {
              isValid: status,
              message: status ? "" : message,
            },
          }));
        },
      };
      window.CollectJS?.configure(config);
      return true;
    };

    if ((!activeProduct || !token) && !isAnonymous) return;

    const retryInterval = setInterval(() => {
      if (configureCollectJS()) {
        clearInterval(retryInterval);
      }
    }, 1000);

    return () => clearInterval(retryInterval);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [placementId, paywallId, activeProduct, token]);

  const finishSubmit = async (response: any) => {
    setCardType(response?.card?.type);
    if (response?.card?.type !== "mastercard") {
      setError("card_type_error");
      return setIsSubmitting(false);
    }

    try {
      setIsSubmitting(true);
      if (isAnonymous && !sessionId?.length) {
        setError("Session ID is required for anonymous payment");
        throw new Error("Session ID is required for anonymous payment");
      }
      if (!placementId || !paywallId) {
        setError("Placement ID or Paywall ID is required");
        console.error(`Placement ID: ${placementId}, Paywall ID: ${paywallId}`);
        throw new Error("Placement ID or Paywall ID is required");
      }
      const res = !isAnonymous
        ? await api.makePayment({
            token,
            productId: activeProduct?.id || "",
            placementId,
            paywallId,
            paymentToken: response.token,
            address: addressRef.current || undefined,
          })
        : await api.makeAnonymousPayment({
            productId: activeProduct?.id || "",
            placementId,
            paywallId,
            paymentToken: response.token,
            sessionId: sessionId,
            address: addressRef.current || undefined,
          });

      if (isAnonymous && "user" in res && res?.user) {
        await anonymousAuthorization(res.user);
      }

      setPaymentResponse(res);
      if ("payment" in res) {
        setIsPaymentSuccess(res.payment.status === "paid");
      } else {
        setIsPaymentSuccess(res.status === "paid");
      }
      const status = "payment" in res ? res.payment.status : res.status;
      if (status !== "paid") {
        setError("message" in res ? res.message : "Something went wrong");
      }
    } catch (error: any) {
      console.error("Payment error:", error);
      setError(error?.message);
    } finally {
      setIsSubmitting(false);
    }
  };

  const showCreditCardForm = async () => {
    await window.CollectJS.startPaymentRequest({
      amount: formPrice,
    });
    setIsOpenModal(true);
  };

  const submitInlineForm = (address?: AddressFields) => {
    setError(null);
    if (address) {
      addressRef.current = address;
    }
    try {
      setIsSubmitting(true);
      window.CollectJS.startPaymentRequest();
    } catch (error: any) {
      console.error("Payment form error:", error);
      setError(error?.message);
      setIsSubmitting(false);
    }
  };

  const closeModal = () => {
    setIsOpenModal(false);
    setIsModalClosed(true);
  };

  return useMemo(
    () => ({
      isLoading,
      paymentResponse,
      error,
      isPaymentSuccess,
      isOpenModal,
      isModalClosed,
      showCreditCardForm,
      submitInlineForm,
      closeModal,
      formValidation,
      isFormValid,
      isCollectJSLoaded,
      cardType,
    }),
    [
      isLoading,
      paymentResponse,
      error,
      isPaymentSuccess,
      isOpenModal,
      isModalClosed,
      showCreditCardForm,
      submitInlineForm,
      closeModal,
      formValidation,
      isFormValid,
      isCollectJSLoaded,
      cardType,
    ]
  );
};
