import React, { useState, useEffect } from 'react'
import { Formik, Form } from 'formik'
import { connect } from 'react-redux'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import { validators } from "./patient-register.validation.rules"
import ReferralCodeCard from './tabs/referral-code.component'
import PersonalCard from './tabs/personal-card.component'
import AddressCard from './tabs/address-card.component'
import ConfirmSubmitCard from '../common-cards/final-card.component'
import {initialValues} from './patient-register.initial-values'
import ToastComponent from '../../../utility/toast/toast.component'
import { TermsAndConditionContentComponent, TermsAndConditionComponent } from '../../../utility/terms_and_conditions/terms_and_conditions.component'

import {registerPatientAsync, clearPatientRegistrationState, 
    setPatientRegistrationCurrentPage, startPatientRegistrationPayment, 
    registrationPaymentCapture, failedPatientRegistrationPayment,
    validateSubscriptionCodeAsync,postPatientFailure, cancelPatientRegistrationPayment
    } from '../../../../redux/patient/patient.action'
import { getResult, getErrorMessages, getInProgress, getSubscCodeValidationInProgress, getCurrentPage, 
    getSubscodeValidationDone, getPaymentInProgress} from '../../../../redux/patient/selector'
import {getTermsAndConditionsContent} from '../../../../redux/user/selectors'
import {fetchUserTermsAndConditionsAsync} from '../../../../redux/user/user.action'

import usePaymentEffect from "../../../utility/effects/use-payment-fetch.effect";
import WithSpinner from "../../../utility/hoc/spinner/with-spinner.component"
import './patient-register.styles.scss'

const PatientRegisterCard = props => {
    
    const totalPages = 4
    const { t_n_c_content, errorMessages, currentPage, doChangeCurrentPageTo, result,
        subscCodeValidationInProgress,inProgress, paymentInProgress,
        doDismissError,doRegister, doFetchTermsCondition, subscodeValidationDone,  doSubscodeValidation, validationErrorOccurred } = props
    const [subscriptionCode, setSubscriptionCode ] = useState('')
    // terms and condition setup
    const [showTerms, setShowTerms ] = useState(false)
    const [acceptTerms, setAcceptTerms ] = useState(false)
    // terms and condition setup end
    const [cacheResult, setCacheResult] = useState(null)

    usePaymentEffect({...props, result: cacheResult})
    
    useEffect(() =>{
        doFetchTermsCondition()
    },[])
    
    useEffect(()=>{
        if(subscodeValidationDone){
            doNext()
        }
        return () => {
            setCacheResult(null)            
        }
    },[subscodeValidationDone])
    
    //First time when user registration completes and a new result with payment information
    //has come back as response from server.
    useEffect(() =>{
        setCacheResult(result)
    },[result])
    //This triggers everytime payment progress is set to false, when user cancels the payment dialog
    //or due to error in payment.
    useEffect(() => {
        if(!paymentInProgress){
            setCacheResult(null)
        }
    }, [paymentInProgress])

    const  doPrevious = (e) => {
        doChangeCurrentPageTo(currentPage - 1)
    }
    
    const doValidateBeforeNext = () => {
        if (acceptTerms)
            doSubscodeValidation(subscriptionCode)
    }

    const doNext = () => {
        if (currentPage < totalPages - 1){    
            doChangeCurrentPageTo(currentPage + 1)
        }
    }

    const onChangeOfSubscriptionCodeField = theValue => {
        setSubscriptionCode(theValue)
    }

    const takeOnSubmit = async (formik) => {
        const {values} = formik
        // const {errors} = values
        try {
            if (!!props.result && !!props.result.userID){
                setCacheResult(props.result)
            }else{
                //reason of the sequence in educator register page.
                await formik.submitForm()
                await validators.validate(values)
            }
            
        } catch (ex) {
            // console.log('validation error = ', ex.message)
            validationErrorOccurred(ex.message)            
        }
    }

    const currentCard = (index) => {
        var displayCard = null
        switch (index) {
            case 0:
                displayCard = <ReferralCodeCard text={subscriptionCode} onTextChange={onChangeOfSubscriptionCodeField}/>
                break;

            case 1:
                displayCard = < PersonalCard/>
                break;

            case 2:
                displayCard = <AddressCard />
                break;
                        
            case 3:
                displayCard = <ConfirmSubmitCard />
                break;
            default:
                break;
        }

        return { displayCard, _key: index }
    }


    const { displayCard, _key } = currentCard(currentPage)
    
    const ValidateButtonWithSpinner = WithSpinner(() =>
        (
            !acceptTerms ? 
            <button type="button" name="next" disabled
                hidden={currentPage > 0} className="p-2 next ml-3 mt-3">
                    Validate &amp; Next
                </button>
            :
            <button type="button" name="next" onClick={doValidateBeforeNext}
                hidden={currentPage > 0} className="p-2 next btn-register ml-3 mt-3">
                    Validate &amp; Next
                </button>
               
        )
    )

    const PayButtonWithSpinner = WithSpinner(({onClickHandler}) =>
        (
            <button type="button" name="submit" onClick={onClickHandler}
                hidden={currentPage !== totalPages - 2} className="p-2 next btn-register ml-3 mt-3">
                    Pay now                                   
            </button>
        )
    )

// terms and condition setup
    const termsLinkClicked = () => {
        setShowTerms(!showTerms)
    }

    const onTermsModalHide = (accepted) => {
        setAcceptTerms(accepted)
        setShowTerms(false)
    }
// terms and condition setup end    

    return (
        <div id="patient" className="tab-pane">
            <TermsAndConditionContentComponent show={showTerms} onHide={onTermsModalHide} content={t_n_c_content}/>
            <Formik
                initialValues={{
                    ...initialValues
                }}
                /*
                validate= {(values) => {
                     validators.validate(values)
                      .then(() => {})
                      .catch((err) => {
                        console.log('error is ',err)
                        throw err
                      })
                  }}
                */
                validationSchema={validators}
                onSubmit={ values => {
                    values["SubsCode"] = subscriptionCode
                    doRegister(values)
                    // handlePayment()
                    

                }}
            >
                {formik => (
                    <Form className="msform">
                        
                        <div className="container">
                            <div className="row" id="progresspatient">
                                <div className="active col" id="patientaccount">Ref-code</div>
                                <div className={currentPage >= 1 ? "active col": "col"} id="patientpersonal">Personal</div>
                                <div className={currentPage >= 2 ? "active col": "col"} id="patientaddress">Address</div>
                                <div className={currentPage >= 3 ? "active col": "col"} id="patientpayment">Payment</div>
                            </div>
                        </div>
                        <TransitionGroup>
                            <CSSTransition
                                key={_key}
                                timeout={600}
                                classNames="fade"
                            >
                                {
                                    displayCard
                                }
                            </CSSTransition>
                        </TransitionGroup>


                        <div className="d-flex flex-row-reverse">
                            
                            <PayButtonWithSpinner isLoading={
                                (inProgress && !paymentInProgress) 
                                || 
                                    (!inProgress && paymentInProgress)
                                } defaultHeight={false}
                                onClickHandler={() => takeOnSubmit(formik)}
                            />                                
                            <ValidateButtonWithSpinner isLoading={subscCodeValidationInProgress} defaultHeight={false}/>                                
                            <button type="button" name="next" onClick={doNext}
                                hidden={currentPage === 0 || currentPage >= totalPages - 2} className="p-2 next btn-register ml-3 mt-3">
                                   Next Step                             
                                </button>
                            <button type="button" name="previous" onClick={doPrevious}
                                hidden={currentPage === totalPages - 1 || currentPage === 0} className="p-2 previous btn-outlines mt-3">Previous</button>
                        </div>
                        <div className={ currentPage > 0 || currentPage == 0 && acceptTerms ? 'hidden': ""}>
                            <TermsAndConditionComponent onLinkClick={termsLinkClicked}/>
                        </div>                        
                    </Form>
                )}
            </Formik>
            { !!errorMessages ? <ToastComponent message={errorMessages} onclose={doDismissError}/> : null }
        
        </div>
    )
}

const mapStateToProps = (state) => ({

    result: getResult(state),
    errorMessages: getErrorMessages(state),
    inProgress: getInProgress(state),
    subscCodeValidationInProgress: getSubscCodeValidationInProgress(state),
    currentPage: getCurrentPage(state),
    subscodeValidationDone: getSubscodeValidationDone(state),
    paymentInProgress: getPaymentInProgress(state),
    t_n_c_content: getTermsAndConditionsContent(state)

})

const mapDispatchToProps = dispatch => ({
    doSubscodeValidation: (subscriptionCode) => dispatch(validateSubscriptionCodeAsync({SubsCode: subscriptionCode})),
    doFetchTermsCondition: () => dispatch(fetchUserTermsAndConditionsAsync()),
    doRegister: body => dispatch(registerPatientAsync(body)),
    /** dismiss open alert */
    doDismissError: () => dispatch(clearPatientRegistrationState()),
    /** change current page navigation */
    doChangeCurrentPageTo: (pageNum) => dispatch(setPatientRegistrationCurrentPage(pageNum)),
    /** start payment */
    initiatePayment: () => dispatch(startPatientRegistrationPayment()),
    /** verify with bakend to complete registration after check payment details  */
    verifyPayment: payment => dispatch(registrationPaymentCapture(payment)),
    /** in case of payment failed */
    paymentFailed: err => dispatch((failedPatientRegistrationPayment(err))),
    cancelPayment: () => dispatch((cancelPatientRegistrationPayment())),
    validationErrorOccurred: (err) => dispatch(postPatientFailure({message: err}))
    
})

export default connect(mapStateToProps, mapDispatchToProps)(PatientRegisterCard)