import React, { useEffect, useState } from 'react';
import { Sidecar, useToast } from '@theorchard/suite-components';
import { isEmpty, trim } from 'lodash-es';
import { useCreatePaymentGroup } from 'src/apollo/mutations/payment-group';
import { NewPaymentGroupFormFields } from 'src/components/payment-group/new-payment-group-form-fields';
import {
    CURRENCIES,
    PAYMENT_GROUP_SUCCESS_MSG,
    PAYMENT_SCHEDULES,
} from 'src/constants';
import type {
    CustomChangeEvent,
    PaymentGroupFormFields,
} from 'src/types/payment-group';

interface NewPaymentGroupFormPropTypes {
    isSidecarOpen: boolean;
    setIsSidecarOpen: (open: boolean) => void;
    refetchCurrentPage: () => void;
}

const NewPaymentGroupForm: React.FC<NewPaymentGroupFormPropTypes> = ({
    isSidecarOpen,
    setIsSidecarOpen,
    refetchCurrentPage,
}) => {
    const [error, setError] = useState<string | null>(null);
    const [formData, setFormData] = useState<Partial<PaymentGroupFormFields>>(
        {}
    );
    const [disableContinueBtn, setDisableContinueBtn] = useState<boolean>(true);
    const [isSavingFormData, setIsSavingFormData] = useState<boolean>(false);
    const addToast = useToast();

    const changeHandler = (
        e: React.ChangeEvent<HTMLInputElement> | CustomChangeEvent
    ) => {
        const {
            target: { name, value },
        } = e;
        setError(null);
        setFormData({ ...formData, [name]: value });
    };

    const addPaymentGroup = useCreatePaymentGroup(null);

    const between = (min: number, max: number, num: number) =>
        min < num && num < max;

    const validateFields = (isConditionValid: string | boolean) => {
        if (isConditionValid) setDisableContinueBtn(false);
        else setDisableContinueBtn(true);
    };

    const submitHandler = () => {
        setDisableContinueBtn(true);
        setIsSavingFormData(true);
        let groupCriteria = {};

        const {
            currencyCodes,
            referencePaymentEntities,
            paymentSchedules,
            groupName,
            referenceAgreementTypes,
        } = formData;

        if (
            currencyCodes &&
            between(0, CURRENCIES.length, currencyCodes.length)
        )
            groupCriteria = { ...groupCriteria, currencyCodes };

        if (
            paymentSchedules &&
            between(0, PAYMENT_SCHEDULES.length, paymentSchedules.length)
        )
            groupCriteria = { ...groupCriteria, paymentSchedules };

        groupCriteria = {
            ...groupCriteria,
            referencePaymentEntities,
            referenceAgreementTypes,
        };

        const variables = {
            groupCriteria,
            groupName: trim(groupName),
            isReusable: true,
        };

        addPaymentGroup({ variables })
            .then(() => {
                refetchCurrentPage();
                setIsSidecarOpen(false);
                setIsSavingFormData(false);
                addToast(PAYMENT_GROUP_SUCCESS_MSG);
            })
            .catch(e => {
                setDisableContinueBtn(false);
                setIsSavingFormData(false);
                if (Array.isArray(e))
                    setError(
                        `Error: ${JSON.stringify(e[0])}, Failed to create payment group.`
                    );
                else
                    setError(
                        `Error: ${String(e)}, Failed to create payment group.`
                    );
            });
    };

    useEffect(() => {
        const { groupName, referencePaymentEntities } = formData;
        validateFields(trim(groupName) && !isEmpty(referencePaymentEntities));
    }, [formData]);

    useEffect(() => {
        setFormData({});
    }, [isSidecarOpen]);

    return (
        <Sidecar
            confirmButtonProps={{
                disabled: disableContinueBtn,
                title: 'Create',
            }}
            isOpen={isSidecarOpen}
            onConfirm={() => submitHandler()}
            onRequestClose={
                isSavingFormData
                    ? () => false
                    : () => {
                          setIsSidecarOpen(false);
                          setError(null);
                      }
            }
            title="New Payment Group"
            testId="PaymentGroupFormSidecar"
        >
            <NewPaymentGroupFormFields
                changeHandler={changeHandler}
                error={error}
                formData={formData}
            />
        </Sidecar>
    );
};

export default NewPaymentGroupForm;
