import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { graphql, createFragmentContainer } from 'react-relay';
import get from 'lodash.get';
import { TextArea } from 'dibs-elements/exports/TextArea';
import { AddressSelector } from 'dibs-address-form';
import { injectIntl, intlShape, defineMessages, FormattedMessage } from 'react-intl';
import { Spinner } from 'dibs-elements/exports/Spinner';

// mutations
import BuyerProfileMutation from '../mutations/drsmBuyerProfileName';
import UserAddAddressMutation from '../mutations/drsmUserAddAddress';
import RequestQuoteMutation from '../mutations/drsmRequestShipmentQuote';

//components
import RequestModalSelectProject from './RequestModalSelectProject';

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

const messages = defineMessages({
    messagePlaceholder: {
        id: 'dc.requestShippingModal.message_placeholder',
        defaultMessage:
            'Please indicate whether you have a delivery deadline or preferred delivery method. If you are interested in multiple quantities, please specify. Note that expedited shipping may be substantially more expensive.',
    },
});

class RequestShippingQuoteFormComponent extends Component {
    constructor(props) {
        super(props);

        this.state = {
            isSaving: false,
            selectedProject: null,
        };

        // Used for storing the optional message field's data
        this.message = '';

        this.failureHandler = this.failureHandler.bind(this);
        this.getUserProjects = this.getUserProjects.bind(this);
        this.requestShipmentQuote = this.requestShipmentQuote.bind(this);
        this.onMessageChange = this.onMessageChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }
    failureHandler() {
        this.setState({ isSaving: false });
        this.props.onFailure();
    }
    getUserProjects() {
        const { viewer } = this.props;
        const edges = get(viewer, 'projects.edges');
        return edges ? edges.map(edge => edge.node) : [];
    }
    requestShipmentQuote(address) {
        const {
            relay,
            userId,
            user,
            itemId,
            bulkItemIds,
            itemTitle,
            conversationId,
            conversationIds,
            dealerPk,
            transactionId,
            conversationRelayId,
            transactionRelayId,
            userRelayId,
            pageContext,
            onSuccess,
        } = this.props;

        const { selectedProject } = this.state;
        const portfolioId = get(selectedProject, 'portfolio.serviceId');
        let portfolioIds;
        if (portfolioId) {
            portfolioIds = [portfolioId];
        }

        const args = {
            userId,
            itemId,
            itemIds: bulkItemIds,
            dealerPk,
            conversationId,
            conversationIds,
            transactionId,
            conversationRelayId,
            transactionRelayId,
            userRelayId,
            itemTitle,
            pageContext,
            shippingAddressId: address.serviceId,
            message: this.message,
            onSuccess,
            onFailure: this.failureHandler,
            portfolioIds,
        };

        const { firstName, lastName } = get(user, 'profile') || {};

        /**
         * If firstName and lastName are undefined update user profile with display name,
         * then request a shipping quote
         */
        if (!firstName && !lastName) {
            BuyerProfileMutation.commit(relay.environment, {
                userServiceId: userId,
                displayName: `${address.firstName} ${address.lastName}`,
                onSuccess: () => {
                    RequestQuoteMutation.commit(relay.environment, args);
                },
                onFailure: this.failureHandler,
            });

            return;
        }

        RequestQuoteMutation.commit(relay.environment, args);
    }
    onMessageChange(e) {
        this.message = e.target.value;
    }
    onSubmit({ address, isValid }) {
        const { relay, userId } = this.props;
        const isNewAddress = address && !address.serviceId;

        if (isValid) {
            this.setState({ isSaving: true });
            this.props.onSubmit();

            if (isNewAddress) {
                UserAddAddressMutation.commit(relay.environment, {
                    userId,
                    address,
                    onSuccess: payload => {
                        this.requestShipmentQuote(get(payload, 'userAddAddress.address'));
                    },
                    onFailure: this.failureHandler,
                });
            } else {
                this.requestShipmentQuote(address);
            }
        }
    }
    render() {
        const { intl, isBulkRequest, isSubmitting, user, viewer } = this.props;
        const { selectedProject, isSaving } = this.state;
        const addressSelectorCopy = {
            addFromSavedAddresses: (
                <FormattedMessage
                    id="dc.requestShippingModal.add_from_saved_addresses"
                    defaultMessage="Add from saved addresses"
                />
            ),
            addNewAddress: (
                <FormattedMessage
                    id="dc.requestShippingModal.add_new_address"
                    defaultMessage="Add new address"
                />
            ),
            send: <FormattedMessage id="dc.requestShippingModal.send" defaultMessage="Submit" />,
        };

        const showRequestModalSelectProject = isBulkRequest && get(user, 'isVerifiedTrade');

        return !viewer ? (
            <Spinner dark />
        ) : (
            <div>
                {isSubmitting && <div className={css.overlaySpinner} />}
                {showRequestModalSelectProject && (
                    <RequestModalSelectProject
                        onProjectSelection={project => this.setState({ selectedProject: project })}
                        selectedProject={selectedProject}
                        user={user}
                        viewer={viewer}
                    />
                )}
                <div className={`${css.bodyHeaderWrapper} ${css.bodyHeader}`}>
                    <FormattedMessage
                        id="dc.requestShippingModal.address_form_header"
                        defaultMessage="Select your shipping address"
                    />
                </div>
                <AddressSelector
                    viewer={viewer}
                    user={user}
                    copy={addressSelectorCopy}
                    onSubmit={this.onSubmit}
                    isSaving={isSaving}
                    fields={[, 'line1', 'line2', 'country', 'city', 'state', 'zipCode']}
                    hideCompany
                    hidePhoneNumber
                >
                    <TextArea
                        label={
                            <FormattedMessage
                                id="dc.requestShippingModal.message_label"
                                defaultMessage={`{isBulkRequest, select,
                                    true {Provide additional information to the seller(s)}
                                    false {Provide additional information to the seller}
                                }`}
                                values={{ isBulkRequest }}
                            />
                        }
                        placeholder={intl.formatMessage(messages.messagePlaceholder)}
                        disabled={isSubmitting}
                        onChange={this.onMessageChange}
                        value={this.message}
                    />
                </AddressSelector>
            </div>
        );
    }
}

RequestShippingQuoteFormComponent.propTypes = {
    relay: PropTypes.object,
    viewer: PropTypes.object.isRequired,
    user: PropTypes.object,
    userId: PropTypes.string,
    itemId: PropTypes.string,
    bulkItemIds: PropTypes.array,
    conversationIds: PropTypes.array,
    isBulkRequest: PropTypes.bool,
    isSubmitting: PropTypes.bool.isRequired,
    itemTitle: PropTypes.string,
    conversationId: PropTypes.string,
    dealerPk: PropTypes.string,
    transactionId: PropTypes.string,
    conversationRelayId: PropTypes.string,
    transactionRelayId: PropTypes.string,
    userRelayId: PropTypes.string,
    pageContext: PropTypes.string,
    onSubmit: PropTypes.func.isRequired,
    onSuccess: PropTypes.func.isRequired,
    onFailure: PropTypes.func.isRequired,
    intl: intlShape,
    hasLoggedIn: PropTypes.bool,
    address: PropTypes.object,
};

export const RequestShippingQuoteForm = createFragmentContainer(
    injectIntl(RequestShippingQuoteFormComponent),
    {
        user: graphql`
            fragment RequestShippingQuoteForm_user on User {
                profile {
                    firstName
                    lastName
                }
                isVerifiedTrade
                ...AddressSelector_user
                ...RequestModalSelectProject_user
            }
        `,
        viewer: graphql`
            fragment RequestShippingQuoteForm_viewer on Viewer {
                id
                projects(userIds: $userIds, first: 200) @include(if: $hasUserId) {
                    edges {
                        node {
                            serviceId
                            name
                            portfolio {
                                serviceId
                            }
                        }
                    }
                }
                ...AddressSelector_viewer
                ...RequestModalSelectProject_viewer
            }
        `,
    }
);
