import React, { useEffect, useState } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import {
    Button,
    LoadingButton,
    DayInput,
    Modal,
    Form,
    Field
} from '@orchard/frontend-react-components';
import { formatMessage } from '@orchard/frontend-localization';
import { RootState } from 'src/store/store';
import Segment from 'src/utils/segment';
import CurrencyInput from 'src/components/currency-input/currency-input';
import { CollaboratorTransactionType } from 'src/__definitions__/globalTypes';
import { TransactionState } from 'src/types/TransactionState';
import { CreateCollaboratorTransactionsVariables } from 'src/mutations/__definitions__/CreateCollaboratorTransactions';
import { getVariablesFromTransactionState } from '../../../mutations/create-collaborator-transactions';
import { setTransactionField, clearTransaction } from '../../../actions/transaction';
import { RoyaltiesPageCollaborator_collaborator } from '../queries/__definitions__/RoyaltiesPageCollaborator';
import {
    SEGMENT_EVENTS,
    SEGMENT_CATEGORIES,
} from '../../../constants';
import messages from '../i18n';

const CLASS_NAME = 'PaymentModal';

type TransactionField = keyof TransactionState;
const connector = connect(({ transaction }: RootState) => ({ transaction }));
type PropsFromRedux = ConnectedProps<typeof connector>;

type Props = {
    onClose(): void;
    collaborator: RoyaltiesPageCollaborator_collaborator;
    onClose(): void;
    onConfirm(variables: CreateCollaboratorTransactionsVariables): void;
    isLoading: boolean;
} & PropsFromRedux;

const PaymentModal: React.FC<Props> = ({
    onClose,
    onConfirm,
    isLoading,
    collaborator,
    transaction,
    dispatch,
}) => {
    useEffect(() => () => { dispatch(clearTransaction()); }, [dispatch]);

    const [validated, setValidated] = useState(false);

    const isDateError = !transaction.date;
    const isDescriptionError = !transaction.description;
    const isOriginalAmountError = !transaction.originalAmount;

    const isError = isDateError || isDescriptionError || isOriginalAmountError;

    const handleConfirm = () => {
        if (isError) {
            setValidated(true);
            return;
        }

        onConfirm(
            getVariablesFromTransactionState({
                transaction,
                collaborator,
                type: CollaboratorTransactionType.PAYMENT,
            })
        );
    };

    const handleFieldChange = (field: TransactionField, value: TransactionState[TransactionField] | TransactionState['reports'] = []) =>
        dispatch(setTransactionField(field, value));

    return (
        <Modal
            className={ `${CLASS_NAME}` }
            onRequestClose={ onClose }
            headerLabel={ formatMessage(messages.addPayment) }
            isOpen
        >
            <div className={ `${CLASS_NAME}-content` }>
                <div className={ `${CLASS_NAME}-body` }>
                    <div className={ `${CLASS_NAME}-balance-message` }>
                        { formatMessage(messages.wisePaymentModalBalanceMessage) }
                    </div>
                </div>
                <Form className={ `${CLASS_NAME}-form` } validated={ validated }>
                    <div className={ `${CLASS_NAME}-row` }>
                        <Field
                            id={ `${CLASS_NAME}-input-field` }
                            labelText={ formatMessage(messages.date) }
                            controlId={ `${CLASS_NAME}-input-field` }
                            isRequired
                            errorMessage={ isDateError && formatMessage(messages.blankField) }
                        >
                            <DayInput
                                name={ `${CLASS_NAME}-date-input` }
                                data-testid={ `${CLASS_NAME}-date-input` }
                                value={ transaction.date }
                                onChange={ (value: TransactionField) => {
                                    Segment.trackEvent(
                                        SEGMENT_EVENTS.PAYMENT_DATE_SELECT,
                                        SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                    );
                                    handleFieldChange('date', value);
                                } }
                                dayPickerInputOptions={ {
                                    placeholder: formatMessage(
                                        messages.selectDate
                                    ),
                                } }
                            />
                        </Field>
                    </div>
                    <div
                        className={ `${CLASS_NAME}-row ${CLASS_NAME}-row-description` }
                    >
                        <Field
                            id={ `${CLASS_NAME}-input-field` }
                            labelText={ formatMessage(messages.description) }
                            controlId={ `${CLASS_NAME}-input-field` }
                            isRequired
                            errorMessage={ isDescriptionError && formatMessage(messages.blankField) }
                        >
                            <Form.Control
                                type="text"
                                data-testid="payment-description-input"
                                placeholder={ formatMessage(
                                    messages.typeDescription
                                ) }
                                value={ transaction.description || '' }
                                onChange={ ({ target: { value } }) => {
                                    if (!transaction.description)
                                        Segment.trackEvent(
                                            SEGMENT_EVENTS.PAYMENT_DESCRIPTION_ENTER,
                                            SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                        );
                                    handleFieldChange('description', value);
                                } }
                            />
                        </Field>
                    </div>
                    <div className={ `${CLASS_NAME}-row` }>
                        <Field
                            id={ `${CLASS_NAME}-input-field` }
                            labelText={ formatMessage(messages.amount) }
                            controlId={ `${CLASS_NAME}-input-field` }
                            isRequired
                            errorMessage={ isOriginalAmountError && formatMessage(messages.blankField) }
                        >
                            <CurrencyInput
                                placeholder={ formatMessage(
                                    messages.enterAmount
                                ) }
                                data-testid="payment-amount-input"
                                value={ transaction.originalAmount }
                                onChange={ (value: TransactionField) => {
                                    if (!transaction.originalAmount)
                                        Segment.trackEvent(
                                            SEGMENT_EVENTS.PAYMENT_AMOUNT_ENTER,
                                            SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                        );
                                    handleFieldChange('originalAmount', value);
                                } }
                                inputGroupClass={ `${CLASS_NAME}-payment-amount-input-group` }
                                currency={ collaborator.currency }
                            />
                        </Field>
                    </div>
                </Form>
                <div className={ `${CLASS_NAME}-footer` }>
                    <div className={ `${CLASS_NAME}-buttons` }>
                        <Button
                            type="button"
                            onClick={ onClose }
                            aria-label={ formatMessage(messages.cancel) }
                            data-testid="payment-modal-cancel-button"
                        >
                            { formatMessage(messages.cancel) }
                        </Button>
                        <LoadingButton
                            type="button"
                            variant="primary"
                            onClick={ handleConfirm }
                            aria-label={ formatMessage(messages.addPayment) }
                            data-testid="payment-modal-confirm-button"
                            loading={ isLoading }
                        >
                            { formatMessage(messages.addPayment) }
                        </LoadingButton>
                    </div>
                </div>
            </div>
        </Modal>
    );
};

export default connector(PaymentModal);
