import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { graphql, createFragmentContainer } from 'react-relay';
import { ModalContainer } from 'dibs-elements/exports/ModalContainer';
import { BarHeader } from 'dibs-elements/exports/BarHeader';
import { ModalCloseButton } from 'dibs-elements/exports/ModalCloseButton';
import { ModalBackButton } from 'dibs-elements/exports/ModalBackButton';
import { ModalBody } from 'dibs-elements/exports/ModalBody';
import { injectIntl, intlShape, defineMessages, FormattedMessage } from 'react-intl';
import get from 'lodash.get';

import BulkOperationResultDisplay from 'dibs-bulk-operation-result-display';
import tracking from '../tracking';
import { RequestShippingQuoteForm } from './RequestShippingQuoteForm';
import RequestShippingSuccessContent from './RequestShippingSuccessContent';
import ShippingDetailsContainer from '../ShippingDetails/ShippingDetailsContainer';

import css from '../styles.scss';

const messages = defineMessages({
    mutationError: {
        id: 'dc.requestShippingModal.mutation_error',
        defaultMessage:
            'There was an error submitting your request. Please refresh the page and try again.',
    },
});

export class RequestShippingQuoteModal extends Component {
    constructor(props) {
        super(props);

        this.onSubmit = this.onSubmit.bind(this);
        this.onSuccess = this.onSuccess.bind(this);
        this.onFailure = this.onFailure.bind(this);
        this.onClose = this.onClose.bind(this);
        this.setInitialStep = this.setInitialStep.bind(this);
        this.onOpenQuoteRequestModal = this.onOpenQuoteRequestModal.bind(this);

        this.state = {
            bulkOperationResult: null,
            isSubmitting: false,
        };
        this.setInitialStep();
    }

    componentDidMount() {
        const { modalKey, setOpenModalKey, clearState } = this.props;
        clearState();
        setOpenModalKey(modalKey);
        this.setInitialStep();
    }

    componentWillUnmount() {
        this.props.clearState();
    }

    setInitialStep() {
        const { loadToStep, setCurrentStep } = this.props;
        if (loadToStep) {
            setCurrentStep(loadToStep);
        }
    }

    onSubmit() {
        const { trackingLocation, submitTrackingLocation } = this.props;
        // submitTrackingLocation is passed when the request modal is accessed through a cta in the prequotes modal
        tracking.trackSend({ trackingLocation: submitTrackingLocation || trackingLocation });
        this.setState({ isSubmitting: true });
    }

    onSuccess(response) {
        const { onSuccess, trackingLocation, submitTrackingLocation, setCurrentStep } = this.props;
        // submitTrackingLocation is passed when the request modal is accessed through a cta in the prequotes modal
        tracking.trackSuccess({ trackingLocation: submitTrackingLocation || trackingLocation });
        setCurrentStep('requestSuccess');

        const shipmentQuoteRequest = get(response, 'shipmentQuoteRequest') || null;
        this.setState({ bulkOperationResult: shipmentQuoteRequest, isSubmitting: false });

        if (onSuccess) {
            onSuccess(shipmentQuoteRequest || {});
        }
    }

    onFailure() {
        const errorMessage = this.props.intl.formatMessage(messages.mutationError);
        this.props.setErrorMessage({ errorMessage });
        this.setState({ isSubmitting: false });
    }

    onClose() {
        if (!this.state.isSubmitting) {
            this.props.closeShippingModal();
        }
    }

    onOpenQuoteRequestModal() {
        //this fires when the form is loaded
        const { setCurrentStep, trackingLocation, userId, showAuthModal, openModal } = this.props;

        if (!userId) {
            this.onClose();
            showAuthModal({
                onSuccess: () => {
                    openModal();
                    this.onOpenQuoteRequestModal();
                },
                onError: error => {
                    console.log('Login error: ', error);
                    return null;
                },
            });
        } else {
            tracking.trackClicked({ label: trackingLocation });
            setCurrentStep('quoteRequest');
        }
    }

    getQuoteRequestStatus({ hasPrequote, customQuoteRequested, customQuoteProvided }) {
        let status;
        if (customQuoteRequested) {
            status = 'customQuoteRequested';
        } else if (customQuoteProvided) {
            status = 'customQuoteProvided';
        } else if (hasPrequote) {
            status = 'viewQuotesNoCustom';
        } else {
            status = 'requestQuote';
        }
        return status;
    }

    customQuoteStatus() {
        const { viewer } = this.props;
        const relevantQuote = get(viewer, 'relevantShippingInfo.shipmentQuote');
        const hasSubtotalAmount = !!get(relevantQuote, 'subTotalAmount');

        return {
            requested: get(relevantQuote, 'isCustom') && !hasSubtotalAmount,
            provided: get(relevantQuote, 'isCustom') && hasSubtotalAmount,
        };
    }

    render() {
        const { bulkOperationResult, isSubmitting } = this.state;
        const {
            viewer,
            isOpened,
            currentStep,
            setCurrentStep,
            onOpen,
            isMC,
            userId,
            itemId,
            bulkItemIds,
            conversationIds,
            pageContext,
            errorMessage,
            clearState,
            currency,
            hasQuote,
        } = this.props;

        //custom quote and prequote checks
        const hasPrequote = get(viewer, 'item.hasPreQuotedShipping');
        const customQuoteRequested = this.customQuoteStatus().requested;
        const customQuoteProvided = this.customQuoteStatus().provided;
        const quoteRequestStatus = this.getQuoteRequestStatus({
            hasPrequote,
            customQuoteProvided,
            customQuoteRequested,
        });

        let conversation;
        let user;
        let transaction;

        if (isMC) {
            conversation = get(viewer, 'conversation');
            transaction = get(conversation, 'transaction') || {};
            user = get(conversation, 'originalBuyer.user');
        } else {
            conversation = get(viewer, 'buyerItemConversation');
            transaction = get(viewer, 'transactions.edges[0].node') || {};
            user = get(viewer, 'user');
        }

        const itemIsOnHold = get(viewer, 'item.itemIsOnHold');

        const conversationId = get(conversation, 'serviceId');
        const conversationRelayId = get(conversation, 'id');
        const transactionId = transaction.serviceId;
        const transactionRelayId = transaction.id;
        const userRelayId = get(user, 'id');
        const itemTitle = get(viewer, 'item.title');
        const seller = get(viewer, 'item.seller');
        const dealerPk = this.props.dealerPk || get(seller, 'serviceId');

        //enabler
        const isTrade = get(user, 'isVerifiedTrade');
        const onlyTradeRequestsQuote = get(viewer, 'onlyTradeRequestsQuote');
        const blockRequest =
            (!isTrade && onlyTradeRequestsQuote && !isMC) || (itemIsOnHold && !isMC);

        if (blockRequest) {
            setCurrentStep('preQuoteDisplay');
        }

        const shouldShowDetails = currentStep === 'preQuoteDisplay' && !isSubmitting;
        const shouldShowSuccess = currentStep === 'requestSuccess';
        const shouldShowSQR =
            (currentStep !== 'preQuoteDisplay' || isSubmitting) && currentStep !== 'requestSuccess';

        const isBulkRequest = !!(bulkItemIds && bulkItemIds.length);
        const shouldShowBulkOperationResultDisplay = shouldShowSuccess && isBulkRequest;
        const shouldShowIndividualRequestSuccess =
            shouldShowSuccess && !shouldShowBulkOperationResultDisplay;
        const showBackButton =
            this.props.hasQuote &&
            this.props.loadToStep !== 'requestQuote' &&
            currentStep !== 'preQuoteDisplay' &&
            currentStep !== 'requestSuccess' &&
            quoteRequestStatus !== 'requestQuote';

        const handleBackClick = () => {
            clearState();
            setCurrentStep('preQuoteDisplay');
        };

        const successHeader = (
            <FormattedMessage
                id="dc.requestShippingModal.success_header"
                defaultMessage="Request Sent"
            />
        );

        const header = (
            <FormattedMessage
                id="dc.requestShippingModal.header"
                defaultMessage={`{isBulkRequest, select,
                    true {Request Shipping Quotes}
                    false {Request a Shipping Quote}
                }`}
                values={{ isBulkRequest }}
            />
        );

        const subheader = (
            <FormattedMessage
                id="dc.requestShippingModal.subheader"
                defaultMessage="Due to the nature of our unique items, some may require professional packaging to your specific destination. Request a quote to see what options are available."
            />
        );

        const barHeaderTitle = shouldShowSuccess ? successHeader : header;

        return (
            <ModalContainer
                modalClass={css.sqrModalWrapper}
                isOpen={isOpened}
                onOpen={onOpen}
                onClose={this.onClose}
                modalPosition="center"
                modalSize="medium"
            >
                <ModalCloseButton disabled={isSubmitting} onClick={this.onClose} />
                {showBackButton && (
                    <ModalBackButton disabled={isSubmitting} onClick={handleBackClick} />
                )}
                {!viewer ? null : (
                    <React.Fragment>
                        {shouldShowDetails && (
                            <ShippingDetailsContainer
                                hasQuote={hasQuote}
                                viewer={viewer}
                                currency={currency}
                                isUserLoggedIn={!!userId}
                                openQuoteRequestModal={this.onOpenQuoteRequestModal}
                                closeModal={this.onClose}
                                showRequestCta={isMC}
                                quoteRequestStatus={quoteRequestStatus}
                                blockRequest={blockRequest}
                            />
                        )}
                        {(shouldShowSQR || shouldShowIndividualRequestSuccess) && (
                            <BarHeader title={barHeaderTitle} />
                        )}
                        {shouldShowSQR && (
                            <ModalBody>
                                <div className={css.subheader}>{subheader}</div>
                                {!!errorMessage && (
                                    <div data-tn="sqr-error" className={css.sqrError}>
                                        {errorMessage}
                                    </div>
                                )}
                                <RequestShippingQuoteForm
                                    viewer={viewer}
                                    user={user || null}
                                    userId={userId}
                                    itemId={itemId}
                                    bulkItemIds={bulkItemIds}
                                    conversationIds={conversationIds}
                                    isBulkRequest={isBulkRequest}
                                    isSubmitting={isSubmitting}
                                    itemTitle={itemTitle}
                                    conversationId={conversationId}
                                    dealerPk={dealerPk}
                                    transactionId={transactionId}
                                    conversationRelayId={conversationRelayId}
                                    transactionRelayId={transactionRelayId}
                                    userRelayId={userRelayId}
                                    pageContext={pageContext}
                                    copy={this.copy}
                                    onSubmit={this.onSubmit}
                                    onSuccess={this.onSuccess}
                                    onFailure={this.onFailure}
                                    openQuoteRequestModal={this.onOpenQuoteRequestModal}
                                    closeModal={this.onClose}
                                />
                            </ModalBody>
                        )}
                        {shouldShowIndividualRequestSuccess && (
                            <RequestShippingSuccessContent
                                isMC={isMC}
                                userId={userId}
                                seller={seller}
                            />
                        )}
                        {shouldShowBulkOperationResultDisplay && (
                            <BulkOperationResultDisplay
                                flowType="REQUEST_SHIPPING"
                                bulkOperationResult={bulkOperationResult}
                                conversations={get(bulkOperationResult, 'conversations') || null}
                                onClose={this.onClose}
                            />
                        )}
                    </React.Fragment>
                )}
            </ModalContainer>
        );
    }
}

RequestShippingQuoteModal.propTypes = {
    intl: intlShape,
    isOpened: PropTypes.bool,
    viewer: PropTypes.object,
    relay: PropTypes.object,
    userId: PropTypes.string,
    itemId: PropTypes.string,
    bulkItemIds: PropTypes.array,
    conversationIds: PropTypes.array,
    dealerPk: PropTypes.string,
    loadToStep: PropTypes.string,
    onOpen: PropTypes.func,
    onSuccess: PropTypes.func,
    pageContext: PropTypes.string,
    trackingLocation: PropTypes.string,
    submitTrackingLocation: PropTypes.string,
    onShowQuoteRequest: PropTypes.func,
    closeShippingModal: PropTypes.func,
    modalKey: PropTypes.string,
    isMC: PropTypes.bool,
    currency: PropTypes.string,
    hasQuote: PropTypes.bool,
    showAuthModal: PropTypes.func,
    openModal: PropTypes.func,

    // Redux

    currentStep: PropTypes.string,
    errorMessage: PropTypes.string,

    clearState: PropTypes.func,
    setOpenModalKey: PropTypes.func,
    setCurrentStep: PropTypes.func,
    setErrorMessage: PropTypes.func,
};

RequestShippingQuoteModal.defaultProps = {
    pageContext: 'DEALER_SHIPPING_REQUEST',
};

export default createFragmentContainer(injectIntl(RequestShippingQuoteModal), {
    viewer: graphql`
        fragment RequestShippingQuoteModal_viewer on Viewer {
            onlyTradeRequestsQuote: isEnabled(key: "useOldPdpShippingModals")
            user(userId: $userId) @include(if: $hasUserId) {
                id
                isVerifiedTrade
                ...RequestShippingQuoteForm_user
            }
            item(itemId: $itemId) @include(if: $shouldFetchItem) {
                title
                seller {
                    serviceId
                    ...RequestShippingSuccessContent_seller
                }
                hasPreQuotedShipping
                itemIsOnHold: isOnHold(buyerId: $userId)
            }
            buyerItemConversation(buyerId: $userId, itemId: $itemId)
                @include(if: $shouldFetchConversation) {
                id
                serviceId
            }
            transactions(
                first: 1
                buyerId: $userIds
                itemId: $itemIds
                viewName: "mc.conversationTransaction"
                sort: "createdDate desc"
            ) @include(if: $shouldFetchTransaction) {
                edges {
                    node {
                        id
                        serviceId
                        isCanceled
                        hasCompletedCheckout
                        lastShipmentQuote {
                            status
                        }
                    }
                }
            }
            conversation(conversationId: $conversationId) @include(if: $hasConversationId) {
                transaction {
                    id
                    serviceId
                }
                originalBuyer {
                    user {
                        ...RequestShippingQuoteForm_user
                    }
                }
            }
            relevantShippingInfo(buyerId: $userId, itemId: $itemId) @include(if: $hasUserId) {
                shipmentQuote {
                    subTotalAmount {
                        amount
                    }
                    isCustom
                }
            }
            ...ShippingDetailsContainer_viewer
            ...RequestShippingQuoteForm_viewer
        }
    `,
});
