import React, {useEffect, useState} from 'react';
import { Elements } from '@stripe/react-stripe-js';

import { PrimaryButton } from "../buttons/primary_button";
import { ModalWindow } from "../modal_window";
import { CheckoutForm } from "./checkout_form";
import { AppleGooglePay } from "./apple_google_pay";
import { AmazonButton } from "./amazon_button";
import { PayPal } from "./pay_pal";
import { Divider } from "./divider";
import { LoaderBox } from "../loader_box";
import { InfoBlock } from "../info_block";

import creditCard from '../../assets/paywall/credit_card.svg';
import { useStyles } from "./styles";

export type TranslationPaywallProps = {
    dividerText: string,
    primaryButtonText: string,
    modalTitle: string,
    inputText: {
        cardNumberPlaceholder: string,
        expiryMonthPlaceholder: string,
        expiryYearPlaceholder: string,
        cvvPlaceholder: string,
        nameOfCardPlaceholder: string,
        billingPostcodePlaceholder: string,
    },
    inputErrors: {
        errorCard: string,
        errorDate: string,
        errorCvv: string
    },
    modalPrimaryButtonText: {
        btnUpdate: string,
        btnStartTrail: string,
    },
}

export type PaywallProps = {
    accessPaymentsKeys: {
        checkoutPayKey: string,
        braintreeAuthorization?: string,
        stripePromise?: any,
        amazonSellerId: string,
        amazonClientId: string
    },
    stripeProp: {
        price: number,
        currency: string
    }
    isUpdateForm: boolean,
    countryCode: string,
    onSubmit: any,
    isApplePayActive: boolean,
    isGooglePayActive: boolean,
    isPaypalActive: boolean,
    isAmazonActive: boolean,
    env: string,
    onAmazonButtonClicked: () => void,
    formText?: any,
    onComponentReady?: () => void,
    cardError: string,
    error: string,
    loading?: boolean,
    forceReadyComponentTime?: number,
    isModalCheckoutOpened?: boolean,
    modalCheckoutWindowTriggered?: (arg: boolean) => void,
    buttonWrapperClass?: string,
    errorBlockClass?: string,
    translation?: TranslationPaywallProps
}

const mockTranslationPaywall = {
    dividerText: 'OR',
    primaryButtonText: 'Credit / Debit Card',
    modalTitle: 'Credit / Debit Card',
    inputText: {
        cardNumberPlaceholder: 'Card Number',
        expiryMonthPlaceholder: 'MM',
        expiryYearPlaceholder: 'YY',
        cvvPlaceholder: 'CVV',
        nameOfCardPlaceholder: 'Name on Card',
        billingPostcodePlaceholder: 'Billing Postcode',
    },
    inputErrors: {
        errorCard: 'Please enter a valid card number',
        errorDate: 'Please enter a valid expiry date',
        errorCvv: 'Please enter a valid cvv code'
    },
    modalPrimaryButtonText: {
        btnUpdate: 'Update',
        btnStartTrail: 'Start 7-Day Trial',
    },
}

export const Paywall = ({
    onAmazonButtonClicked,
    accessPaymentsKeys,
    countryCode,
    onSubmit,
    stripeProp,
    isApplePayActive,
    isGooglePayActive,
    isPaypalActive,
    isAmazonActive,
    env,
    formText,
    onComponentReady = () => {},
    cardError,
    error,
    loading,
    forceReadyComponentTime = 4000,
    isUpdateForm = false,
    isModalCheckoutOpened = false,
    modalCheckoutWindowTriggered = () => {},
    buttonWrapperClass = '',
    errorBlockClass = '',
    translation = mockTranslationPaywall
}: PaywallProps) => {
    const {
        button, buttonContent, cardIcon,
        hiddenWindow, wrapper, active,
        errorBlock
    } = useStyles();
    const [open, setOpen] = useState(false)
    const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(null);
    const [stripeResult, setStripeResult] = useState<Record<string, boolean> | null>(null);
    const [gPayLoaded, setGpayLoaded] = useState(!isGooglePayActive);
    const [aPayLoaded, setApayLoaded] = useState(!isApplePayActive);
    const [pPalLoaded, setPayPalLoaded] = useState(!isPaypalActive);
    const { dividerText, primaryButtonText } = translation;

    const toggleModal = () => {
        setOpen(!open)
        modalCheckoutWindowTriggered(!open)
    }

    const {
        checkoutPayKey, stripePromise, braintreeAuthorization,
        amazonClientId, amazonSellerId
    } = accessPaymentsKeys;
    const isAppleGooglePayShowed =  isApplePayActive || isGooglePayActive;
    const isPaymentRequestShowed = !!(stripeResult?.googlePay && paymentRequest)
        || !!(stripeResult?.applePay && paymentRequest);

    const isDividerShowed = (isAppleGooglePayShowed && isPaymentRequestShowed) || isPaypalActive || isAmazonActive;

    useEffect(() => {
        const isComponentReady = gPayLoaded && aPayLoaded && pPalLoaded;

        if(isComponentReady && onComponentReady) {
            onComponentReady()
        }
    }, [gPayLoaded, aPayLoaded, pPalLoaded]);

    useEffect(() => {
        setTimeout(() => {
            setApayLoaded(true);
            setGpayLoaded(true);
            setPayPalLoaded(true);
        }, forceReadyComponentTime);
    }, [])

    useEffect(() => setOpen(isModalCheckoutOpened), [isModalCheckoutOpened])

    const isComponentReady = gPayLoaded && aPayLoaded && pPalLoaded;

    const wrapperClass = `${wrapper} ${isComponentReady ? active: ''} ${buttonWrapperClass}`;

    if(loading) return <LoaderBox />;

    return (
        <>
            {!isComponentReady && <LoaderBox />}
            {error && isComponentReady && (
                <InfoBlock
                    className={`${errorBlock} ${errorBlockClass}`}
                    text={error}
                    variant="error"
                />
            )}
            <div className={wrapperClass}>
                {isAppleGooglePayShowed && stripePromise && (
                    <Elements stripe={stripePromise}>
                        <AppleGooglePay
                            setGpayLoaded={setGpayLoaded}
                            setApayLoaded={setApayLoaded}
                            paymentRequest={paymentRequest}
                            onSubmit={onSubmit}
                            setPaymentRequest={setPaymentRequest}
                            setStripeResult={setStripeResult}
                            isPaymentRequestShowed={isPaymentRequestShowed}
                            {...stripeProp}
                        />
                    </Elements>
                )}
                {isPaypalActive && (
                    <PayPal
                        setPayPalLoaded={setPayPalLoaded}
                        braintreeAuthorization={braintreeAuthorization}
                        onSubmit={onSubmit}
                    />
                )}
                {isAmazonActive && (
                    <AmazonButton
                        onAuth={onAmazonButtonClicked}
                        clientId={amazonClientId}
                        sellerId={amazonSellerId}
                        env={env}
                    />
                )}
                {isDividerShowed && <Divider dataDividerText={dividerText}/>}
                <PrimaryButton
                    onClick={toggleModal}
                    className={button}
                    //@ts-ignore
                    label={(
                        <div className={buttonContent}>
                            <img className={cardIcon} src={creditCard} alt=""/>
                            { primaryButtonText }
                        </div>
                    )}
                />
                <ModalWindow
                    open={open && isComponentReady}
                    rootClassName={!open || !isComponentReady ? hiddenWindow : ''}
                >
                    <CheckoutForm
                        isUpdateForm={isUpdateForm}
                        error={cardError}
                        formText={formText}
                        handleClose={toggleModal}
                        onSubmit={onSubmit}
                        countryCode={countryCode}
                        publicKey={checkoutPayKey}
                        translation={translation}
                    />
                </ModalWindow>
            </div>
        </>
    )
}