/**
 * Footer for the Step component used inside Wizard
 * Represents buttons for navigating through the steps of the wizard
 * Works with Wizardcontent for easy access to the state and methods of the wizard
 * You need to connect this component inside the Step where navigation is required
 *
 * @author: Denis Makarov
 * @date: 2020-02-12
 */
import * as React from 'react';
import {WizardContext} from '../Wizard';
import {WizardContextProps} from '../../../type/WizardTypes';
import {Button} from '../../index';
import {INTENT} from '../../../constants';

import * as styles from './footer.m.scss';
import {joinClassNames} from '../../../utils/joinClassNames';

export interface IWizardFooterProps {
    allowPrev?: boolean;
    allowNext?: boolean;
    allowSubmit?: boolean;
    isSubmitStep?: boolean; // custom flag for determining whether onSubmit will be called
    leftElement?: React.ReactNode; // custom controls that use custom handlers
    rightElement?: React.ReactNode;
    beforePrevStep?: () => void; // custom handler for clicking the "back" button"
    beforeNextStep?: () => void; // custom handler for clicking the "next" button"
    beforeSubmit?: () => void; // custom handler for clicking the "submit" button"

    isWaitingNext?: boolean;
    isWaitingPrev?: boolean;

    prevText: string;
    nextText: string;
    submitText: string;
    nextButtonTitle?: string;
}

interface IDefaultProps {
    allowPrev: boolean;
    allowNext: boolean;
    allowSubmit: boolean;
}

export class Footer extends React.Component<IWizardFooterProps> {
    static defaultProps: IDefaultProps = {
        allowPrev: true,
        allowNext: true,
        allowSubmit: true
    };

    onNextStep (wizardProps: WizardContextProps) {
        if (!this.props.allowNext) {
            return;
        }

        if (this.props.beforeNextStep) {
            this.props.beforeNextStep();
        } else {
            wizardProps.moveNextStep();
        }
    }

    onPrevStep (wizardProps: WizardContextProps) {
        if (!this.props.allowPrev) {
            return;
        }

        if (this.props.beforePrevStep) {
            this.props.beforePrevStep();
        } else {
            wizardProps.movePrevStep();
        }
    }

    onSubmit (wizardProps: WizardContextProps) {
        if (!this.props.allowSubmit) {
            return;
        }

        if (this.props.beforeSubmit) {
            this.props.beforeSubmit();
        } else {
            wizardProps.onSubmit();
        }
    }

    renderDefaultLeftElement (wizardProps: WizardContextProps) {
        const buttonText = (typeof this.props.leftElement === 'string') ? this.props.leftElement : this.props.prevText;

        return (
            <Button
                isGhost={true}
                data-qaid={'prevbutton'}
                isRound
                onClick={this.onPrevStep.bind(this, wizardProps)}
                isDisabled={!this.props.allowPrev}
                isWaiting={this.props.isWaitingPrev}
            >
                {buttonText}
            </Button>
        );
    }

    renderDefaultRightElement (wizardProps: WizardContextProps, isSubmitStep: boolean) {
        let rightElementText;

        if (typeof this.props.rightElement === 'string') {
            rightElementText = this.props.rightElement;
        } else {
            rightElementText = isSubmitStep ? this.props.submitText : this.props.nextText;
        }

        return (
            isSubmitStep ? (
                <Button
                    intent={INTENT.PRIMARY}
                    data-qaid={'nextbutton'}
                    isRound
                    title={this.props.nextButtonTitle}
                    onClick={this.onSubmit.bind(this, wizardProps)}
                    isDisabled={!this.props.allowSubmit}
                    isWaiting={this.props.isWaitingNext}
                >
                    {rightElementText}
                </Button>
            ) : (
                <Button
                    intent={INTENT.PRIMARY}
                    isGhost={true}
                    data-qaid={'nextbutton'}
                    isRound
                    title={this.props.nextButtonTitle}
                    onClick={this.onNextStep.bind(this, wizardProps)}
                    isDisabled={!this.props.allowNext}
                    isWaiting={this.props.isWaitingNext}
                >
                    {rightElementText}
                </Button>
            )
        );
    }

    renderLeftElement (wizardProps: WizardContextProps) {
        const CustomLeftElement: React.ReactElement | null = React.isValidElement(this.props.leftElement) ? this.props.leftElement : null;
        const showLeftElement = Boolean(CustomLeftElement) || Boolean(wizardProps.getPrevStep());

        let leftElement = null;

        if (showLeftElement) {
            leftElement = CustomLeftElement ||
                this.renderDefaultLeftElement(wizardProps);
        }

        return (
            <div className={joinClassNames(styles.footerControls, styles.leftContainer)}>
                {leftElement}
            </div>
        );
    }

    renderRightElement (wizardProps: WizardContextProps) {
        const CustomRightElement: React.ReactElement | null =
            React.isValidElement(this.props.rightElement) ? this.props.rightElement : null;

        const nextStep = wizardProps.getNextStep();

        let isSubmitStep: boolean = false;
        let showRightElement: boolean = false;

        isSubmitStep = this.props.isSubmitStep === undefined ? Boolean(!nextStep) : this.props.isSubmitStep;

        if (isSubmitStep) {
            showRightElement = true;
        } else {
            showRightElement = Boolean(CustomRightElement) || Boolean(nextStep);
        }

        let rightElement = null;

        if (showRightElement) {
            rightElement = CustomRightElement ||
                this.renderDefaultRightElement(wizardProps, isSubmitStep);
        }

        return (
            <div className={joinClassNames(styles.footerControls, styles.rightContainer)}>
                {rightElement}
            </div>
        );
    }

    override render () {
        return (
            <WizardContext.Consumer>
                {(wizardProps: WizardContextProps) => {
                    return (
                        <div className={styles.footer}>
                            {this.renderLeftElement(wizardProps)}
                            {this.renderRightElement(wizardProps)}
                        </div>
                    );
                }}
            </WizardContext.Consumer>
        );
    }

}
