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


const CLASS_NAME = 'ExpenseModal';
const connector = connect(({ transaction }: RootState) => ({ transaction }));

type TransactionField = keyof TransactionState;
type PropsFromRedux = ConnectedProps<typeof connector>;

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

const ExpenseModal: React.FC<Props> = ({
    onClose,
    onConfirm,
    isLoading,
    collaborator,
    transaction,
    dispatch,
}) => {
    useEffect(() => {
        dispatch(setTransactionField('collaboratorShare', '100'));
        return () => { dispatch(clearTransaction()); };
    }, [dispatch]);

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

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

    const isError = isDateError
        || isDescriptionError
        || isOriginalAmountError
        || isCollaboratorShareError;

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

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

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

    const chargeableAmount = (transaction.originalAmount && transaction.collaboratorShare
        ? ((transaction.originalAmount
                * parseFloat(transaction.collaboratorShare))
            / 100)
        : 0
    ).toFixed(2);

    return (
        <Modal
            className={ CLASS_NAME }
            onRequestClose={ onClose }
            headerLabel={ formatMessage(messages.addExpense) }
            isOpen
        >
            <div className={ `${CLASS_NAME}-content` }>
                <div className={ `${CLASS_NAME}-body` }>
                    <div className={ `${CLASS_NAME}-balance-message` }>
                        { formatMessage(messages.expenseModalBalanceMessage) }
                    </div>
                </div>
                <Form className={ `${CLASS_NAME}-form` } validated={ validated }>
                    <Form.Row>
                        <Col>
                            <Field
                                id={ `${CLASS_NAME}-date-field` }
                                labelText={ formatMessage(messages.date) }
                                controlId={ `${CLASS_NAME}-date-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.EXPENSE_DATE_SELECT,
                                            SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                        );
                                        handleFieldChange('date', value);
                                    } }
                                    dayPickerInputOptions={ {
                                        placeholder: formatMessage(
                                            messages.selectDate
                                        ),
                                    } }
                                />
                            </Field>
                        </Col>
                    </Form.Row>
                    <Form.Row>
                        <Col xs={ 9 }>
                            <Field
                                id={ `${CLASS_NAME}-description-field` }
                                labelText={ formatMessage(messages.description) }
                                controlId={ `${CLASS_NAME}-description-field` }
                                isRequired
                                errorMessage={ isDescriptionError && formatMessage(messages.blankField) }
                            >
                                <Form.Control
                                    type="text"
                                    data-testid="description-input"
                                    value={ transaction.description || '' }
                                    onChange={ ({ target: { value } }) => {
                                        if (!transaction.description)
                                            Segment.trackEvent(
                                                SEGMENT_EVENTS.EXPENSE_DESCRIPTION_ENTER,
                                                SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                            );
                                        handleFieldChange('description', value);
                                    } }
                                    placeholder={ formatMessage(
                                        messages.typeDescription
                                    ) }
                                />
                            </Field>
                        </Col>
                    </Form.Row>
                    <Form.Row>
                        <Col xs={ 4 }>
                            <Field
                                id={ `${CLASS_NAME}-amount-field` }
                                labelText={ formatMessage(
                                    messages.originalExpense
                                ) }
                                controlId={ `${CLASS_NAME}-amount-field` }
                                isRequired
                                errorMessage={ isOriginalAmountError && formatMessage(messages.blankField) }
                            >
                                <CurrencyInput
                                    data-testid="amount-input"
                                    value={ transaction.originalAmount }
                                    onChange={ (value: TransactionField) => {
                                        if (!transaction.originalAmount)
                                            Segment.trackEvent(
                                                SEGMENT_EVENTS.EXPENSE_AMOUNT_ENTER,
                                                SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                            );
                                        handleFieldChange(
                                            'originalAmount',
                                            value
                                        );
                                    } }
                                    placeholder={ formatMessage(
                                        messages.enterAmount
                                    ) }
                                    inputGroupClass={ `${CLASS_NAME}-amount-input-group` }
                                    currency={ collaborator && collaborator.currency }
                                />
                            </Field>
                        </Col>
                        <Col xs={ 3 }>
                            <Field
                                id={ `${CLASS_NAME}-recoupable-field` }
                                labelText={ formatMessage(messages.recoupable) }
                                controlId={ `${CLASS_NAME}-recoupable-field` }
                                isRequired
                                errorMessage={ isCollaboratorShareError && formatMessage(messages.blankField) }
                            >
                                <InputGroup
                                    className={ `${CLASS_NAME}-recoupable-input-group` }
                                >
                                    <NumberInput
                                        data-testid="recoupable-input"
                                        value={ transaction.collaboratorShare }
                                        maxValue={ 100 }
                                        onChange={ (value: TransactionField) => {
                                            if (transaction.collaboratorShare === '100')
                                                Segment.trackEvent(
                                                    SEGMENT_EVENTS.EXPENSE_RECOUPABLE_ENTER,
                                                    SEGMENT_CATEGORIES.COLLAB_ROYALTIES
                                                );
                                            handleFieldChange(
                                                'collaboratorShare',
                                                value
                                            );
                                        } }
                                        placeholder={ formatMessage(
                                            messages.enterAmount
                                        ) }
                                    />
                                    <InputGroup.Append>
                                        <InputGroup.Text>%</InputGroup.Text>
                                    </InputGroup.Append>
                                </InputGroup>
                            </Field>
                        </Col>
                    </Form.Row>
                    <Form.Row>
                        <Col xs={ 4 }>
                            <Field
                                id={ `${CLASS_NAME}-chargeable-amount-field` }
                                labelText={ formatMessage(
                                    messages.chargeableAmount
                                ) }
                                controlId={ `${CLASS_NAME}-chargeable-amount-field` }
                            >
                                <CurrencyInput
                                    data-testid="chargeable-amount-input"
                                    value={ Number(chargeableAmount) }
                                    onChange={ () => {} }
                                    placeholder={ formatMessage(messages.enterAmount) }
                                    inputGroupClass={ `${CLASS_NAME}-chargeable-amount-input-group` }
                                    currency={ collaborator && collaborator.currency }
                                    disabled
                                />
                            </Field>
                        </Col>
                    </Form.Row>
                </Form>
                <div className={ `${CLASS_NAME}-footer` }>
                    <div className={ `${CLASS_NAME}-buttons` }>
                        <Button
                            type="button"
                            onClick={ onClose }
                            aria-label={ formatMessage(messages.cancel) }
                            data-testid="expense-modal-cancel-button"
                        >
                            { formatMessage(messages.cancel) }
                        </Button>
                        <LoadingButton
                            type="button"
                            variant="primary"
                            onClick={ handleConfirm }
                            aria-label={ formatMessage(messages.addExpense) }
                            data-testid="expense-modal-confirm-button"
                            loading={ isLoading }
                        >
                            { formatMessage(messages.addExpense) }
                        </LoadingButton>
                    </div>
                </div>
            </div>
        </Modal>
    );
};

export default connector(ExpenseModal);
