import { useRef, useState } from "react";

export interface UsePaymentDetailsFormState {
    paymentMethod: string;
    setPaymentMethod: React.Dispatch<React.SetStateAction<string>>;
    poNumber: string;
    setPONumber: React.Dispatch<React.SetStateAction<string>>;
    vatNumber: string;
    setVatNumber: React.Dispatch<React.SetStateAction<string>>;
    saveCard: boolean;
    setSaveCard: React.Dispatch<React.SetStateAction<boolean>>;
    cardHolderName: string;
    setCardHolderName: React.Dispatch<React.SetStateAction<string>>;
    cardNumber: string;
    setCardNumber: React.Dispatch<React.SetStateAction<string>>;
    maskedCardNumber: string;
    setMaskedCardNumber: React.Dispatch<React.SetStateAction<string>>;
    antiFraudSessionId: string;
    setAntiFraudSessionId: React.Dispatch<React.SetStateAction<string>>;
    cardType: string;
    setCardType: React.Dispatch<React.SetStateAction<string>>;
    possibleCardType: string;
    setPossibleCardType: React.Dispatch<React.SetStateAction<string>>;
    expirationMonth: number;
    setExpirationMonth: React.Dispatch<React.SetStateAction<number>>;
    expirationYear: number;
    setExpirationYear: React.Dispatch<React.SetStateAction<number>>;
    securityCode: string;
    setSecurityCode: React.Dispatch<React.SetStateAction<string>>;
    useBillingAddress: boolean;
    setUseBillingAddress: React.Dispatch<React.SetStateAction<boolean>>;
    address1: string;
    setAddress1: React.Dispatch<React.SetStateAction<string>>;
    countryId: string;
    setCountryId: React.Dispatch<React.SetStateAction<string>>;
    stateId: string;
    setStateId: React.Dispatch<React.SetStateAction<string>>;
    city: string;
    setCity: React.Dispatch<React.SetStateAction<string>>;
    postalCode: string;
    setPostalCode: React.Dispatch<React.SetStateAction<string>>;
    paymentMethodError: string;
    setPaymentMethodError: React.Dispatch<React.SetStateAction<string>>;
    poNumberError: string;
    setPONumberError: React.Dispatch<React.SetStateAction<string>>;
    address1Error: string;
    setAddress1Error: React.Dispatch<React.SetStateAction<string>>;
    countryError: string;
    setCountryError: React.Dispatch<React.SetStateAction<string>>;
    stateError: string;
    setStateError: React.Dispatch<React.SetStateAction<string>>;
    cityError: string;
    setCityError: React.Dispatch<React.SetStateAction<string>>;
    postalCodeError: string;
    setPostalCodeError: React.Dispatch<React.SetStateAction<string>>;
    payPalError: string;
    setPayPalError: React.Dispatch<React.SetStateAction<string>>;
    paystandError: string;
    setPaystandError: React.Dispatch<React.SetStateAction<string>>;
    googlePayError: string;
    setGooglePayError: React.Dispatch<React.SetStateAction<string>>;
    showFormErrors: boolean;
    setShowFormErrors: React.Dispatch<React.SetStateAction<boolean>>;
    isCardNumberTokenized: boolean;
    setIsCardNumberTokenized: React.Dispatch<React.SetStateAction<boolean>>;
    isTokenExIframeLoaded: boolean;
    setIsTokenExIframeLoaded: React.Dispatch<React.SetStateAction<boolean>>;
    isECheckTokenized: boolean;
    setIsECheckTokenized: React.Dispatch<React.SetStateAction<boolean>>;
    accountHolderName: string;
    setAccountHolderName: React.Dispatch<React.SetStateAction<string>>;
    accountNumber: string;
    setAccountNumber: React.Dispatch<React.SetStateAction<string>>;
    routingNumber: string;
    setRoutingNumber: React.Dispatch<React.SetStateAction<string>>;
    payerId: string;
    setPayerId: React.Dispatch<React.SetStateAction<string>>;
    creditCardLastFourDigits: string;
    setCreditCardLastFourDigits: React.Dispatch<React.SetStateAction<string>>;
    bankAccountLastFourDigits: string;
    setBankAccountLastFourDigits: React.Dispatch<React.SetStateAction<string>>;
    isIframeLoaded: boolean;
    setIsIframeLoaded: React.Dispatch<React.SetStateAction<boolean>>;
    isPayPal: boolean;
    setIsPayPal: React.Dispatch<React.SetStateAction<boolean>>;
    runSubmitPayPal: boolean;
    setRunSubmitPayPal: React.Dispatch<React.SetStateAction<boolean>>;
    paymentMethodRef: React.RefObject<HTMLSelectElement | null>;
    poNumberRef: React.RefObject<HTMLInputElement | null>;
    address1Ref: React.RefObject<HTMLInputElement | null>;
    countryRef: React.RefObject<HTMLSelectElement | null>;
    stateRef: React.RefObject<HTMLSelectElement | null>;
    cityRef: React.RefObject<HTMLInputElement | null>;
    postalCodeRef: React.RefObject<HTMLInputElement | null>;
    externalTokenProvider: "GooglePay" | "ApplePay" | null;
    setExternalTokenProvider: React.Dispatch<React.SetStateAction<"GooglePay" | "ApplePay" | null>>;
}

function usePaymentDetailsFormState(): UsePaymentDetailsFormState {
    const [paymentMethod, setPaymentMethod] = useState("");
    const [poNumber, setPONumber] = useState("");
    const [vatNumber, setVatNumber] = useState("");
    const [saveCard, setSaveCard] = useState(false);
    const [cardHolderName, setCardHolderName] = useState("");
    const [maskedCardNumber, setMaskedCardNumber] = useState("");
    const [antiFraudSessionId, setAntiFraudSessionId] = useState("");
    const [cardNumber, setCardNumber] = useState("");
    const [cardType, setCardType] = useState("");
    const [possibleCardType, setPossibleCardType] = useState("");
    const [expirationMonth, setExpirationMonth] = useState(1);
    const [expirationYear, setExpirationYear] = useState(new Date().getFullYear());
    const [securityCode, setSecurityCode] = useState("");
    const [useBillingAddress, setUseBillingAddress] = useState(true);
    const [address1, setAddress1] = useState("");
    const [countryId, setCountryId] = useState("");
    const [stateId, setStateId] = useState("");
    const [city, setCity] = useState("");
    const [postalCode, setPostalCode] = useState("");

    const [paymentMethodError, setPaymentMethodError] = useState("");
    const [poNumberError, setPONumberError] = useState("");
    const [address1Error, setAddress1Error] = useState("");
    const [countryError, setCountryError] = useState("");
    const [stateError, setStateError] = useState("");
    const [cityError, setCityError] = useState("");
    const [postalCodeError, setPostalCodeError] = useState("");
    const [payPalError, setPayPalError] = useState("");
    const [paystandError, setPaystandError] = useState("");
    const [googlePayError, setGooglePayError] = useState("");

    const [showFormErrors, setShowFormErrors] = useState(false);
    const [isCardNumberTokenized, setIsCardNumberTokenized] = useState(false);
    const [isTokenExIframeLoaded, setIsTokenExIframeLoaded] = useState(false);
    const [isECheckTokenized, setIsECheckTokenized] = useState(false);
    const [accountHolderName, setAccountHolderName] = useState("");
    const [accountNumber, setAccountNumber] = useState("");
    const [routingNumber, setRoutingNumber] = useState("");
    const [payerId, setPayerId] = useState("");
    const [creditCardLastFourDigits, setCreditCardLastFourDigits] = useState("");
    const [bankAccountLastFourDigits, setBankAccountLastFourDigits] = useState("");
    const [isIframeLoaded, setIsIframeLoaded] = useState(false);

    // Used in validation of form, since some form elements will not be validated when PayPal is active.
    const [isPayPal, setIsPayPal] = useState(false);
    // Help to work in the flow of React to validate the form.
    // Since setting isPayPal and validating will not have the correct "effect" in place to correctly validate the form.
    const [runSubmitPayPal, setRunSubmitPayPal] = useState(false);

    const [externalTokenProvider, setExternalTokenProvider] = useState(<"GooglePay" | "ApplePay" | null>null);

    // Used in deciding which form element to focus on in the case the form is submitted with errors
    const paymentMethodRef = useRef<HTMLSelectElement>(null);
    const poNumberRef = useRef<HTMLInputElement>(null);
    const address1Ref = useRef<HTMLInputElement>(null);
    const countryRef = useRef<HTMLSelectElement>(null);
    const stateRef = useRef<HTMLSelectElement>(null);
    const cityRef = useRef<HTMLInputElement>(null);
    const postalCodeRef = useRef<HTMLInputElement>(null);

    return {
        paymentMethod,
        setPaymentMethod,
        poNumber,
        setPONumber,
        vatNumber,
        setVatNumber,
        saveCard,
        setSaveCard,
        cardHolderName,
        setCardHolderName,
        cardNumber,
        setCardNumber,
        cardType,
        setCardType,
        possibleCardType,
        setPossibleCardType,
        expirationMonth,
        setExpirationMonth,
        expirationYear,
        setExpirationYear,
        securityCode,
        setSecurityCode,
        useBillingAddress,
        setUseBillingAddress,
        address1,
        setAddress1,
        countryId,
        setCountryId,
        stateId,
        setStateId,
        city,
        setCity,
        postalCode,
        setPostalCode,
        paymentMethodError,
        setPaymentMethodError,
        poNumberError,
        setPONumberError,
        address1Error,
        setAddress1Error,
        countryError,
        setCountryError,
        stateError,
        setStateError,
        cityError,
        setCityError,
        postalCodeError,
        setPostalCodeError,
        payPalError,
        setPayPalError,
        paystandError,
        setPaystandError,
        googlePayError,
        setGooglePayError,
        showFormErrors,
        setShowFormErrors,
        isCardNumberTokenized,
        setIsCardNumberTokenized,
        isTokenExIframeLoaded,
        setIsTokenExIframeLoaded,
        isECheckTokenized,
        setIsECheckTokenized,
        accountHolderName,
        setAccountHolderName,
        accountNumber,
        setAccountNumber,
        routingNumber,
        setRoutingNumber,
        payerId,
        setPayerId,
        creditCardLastFourDigits,
        setCreditCardLastFourDigits,
        bankAccountLastFourDigits,
        setBankAccountLastFourDigits,
        isIframeLoaded,
        setIsIframeLoaded,
        isPayPal,
        setIsPayPal,
        runSubmitPayPal,
        setRunSubmitPayPal,
        paymentMethodRef,
        poNumberRef,
        address1Ref,
        countryRef,
        stateRef,
        cityRef,
        postalCodeRef,
        maskedCardNumber,
        setMaskedCardNumber,
        antiFraudSessionId,
        setAntiFraudSessionId,
        externalTokenProvider,
        setExternalTokenProvider,
    };
}

export default usePaymentDetailsFormState;
