import React, { useState } from 'react';
import {
    Alert,
    Button,
    FullscreenModal,
    useFullscreenModal,
    useToast,
} from '@theorchard/suite-components';
import { Page } from '@theorchard/suite-frontend';
import { isEmpty } from 'lodash-es';
import { useHistory } from 'react-router-dom';
import { getAdjustmentsPage } from 'src/urls/frontend-royalties';
import { useGenerateAdjustmentBatch } from 'src/apollo/mutations/statement-period-adjustment-file';
import { useStatementPeriodCurrentPeriod } from 'src/apollo/queries/statement-periods';
import {
    AUTO_GENERATE_BATCH_MODAL_TITLE,
    PAYMENT_SCHEDULES_MAPPING,
    BATCH_TYPE_OPTIONS,
    fileGenerationMessage,
} from 'src/apollo/type-constants/adjustment';
import { GenerateAdjustmentsFormFields } from 'src/components/adjustments/generate-adjustments/generate-adjustments-form-fields';
import { ChangeHandlerEvent } from 'src/types/change-handler';

export const GenerateAdjustmentsForm: React.FC = () => {
    const history = useHistory();
    const { close } = useFullscreenModal();
    const [serverError, setServerError] = useState<string | null>(null);
    const [step, setStep] = useState<number>(1);
    const [formData, setFormData] = useState({
        batchType: BATCH_TYPE_OPTIONS[0].value,
        fileName: '',
        referencePaymentEntities: [],
        paymentSchedules: [],
    });
    const [isGenerating, setIsGenerating] = useState<boolean>(false);
    const toast = useToast();

    const { data: currentStatementPeriod } = useStatementPeriodCurrentPeriod();
    const { generateAdjustmentBatch } = useGenerateAdjustmentBatch();

    const closeModal = () => {
        close(() => history.push(getAdjustmentsPage));
    };

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

    const getCurrentStatementPeriodId = () => {
        if (
            !isEmpty(currentStatementPeriod) &&
            currentStatementPeriod?.abacusCurrentStatementPeriod
        ) {
            return currentStatementPeriod.abacusCurrentStatementPeriod
                .statementPeriodId;
        }
    };

    const handleGenerate = async () => {
        setIsGenerating(true);
        setServerError('');
        try {
            const result = await generateAdjustmentBatch({
                batchCriteria: {
                    referencePaymentEntities:
                        formData.referencePaymentEntities.map(item =>
                            parseInt(item, 10)
                        ),
                    paymentSchedules: formData.paymentSchedules.map(
                        item =>
                            PAYMENT_SCHEDULES_MAPPING[
                                item as keyof typeof PAYMENT_SCHEDULES_MAPPING
                            ]
                    ),
                },
                statementPeriodId: getCurrentStatementPeriodId() || '',
                fileName: formData.fileName,
            });

            close(() =>
                history.push({
                    pathname: getAdjustmentsPage,
                    state: { autoGenerated: true },
                })
            );
            toast(
                fileGenerationMessage(
                    result?.abacusCreateAdjustmentFileAndBatchCriteria
                        ?.fileName || ''
                ),
                { variant: 'info' }
            );
        } catch (error) {
            if (error instanceof Error) {
                setServerError(
                    `Error: ${error.message}, Failed to generate adjustments.`
                );
            } else if (Array.isArray(error)) {
                setServerError(
                    `Error: ${JSON.stringify(error[0])}, Failed to generate adjustments.`
                );
            } else {
                setServerError(
                    `Error: ${String(error)}, Failed to generate adjustments.`
                );
            }
            setIsGenerating(false);
        }
    };

    const title =
        step === 1 ? 'Generate Automated Batch' : 'Generated Automated Batch';

    const alertMessage = serverError ? (
        <div className="GenerateAdjustments-Error">
            <Alert variant="error" text={<span>{serverError}</span>} />
        </div>
    ) : (
        ''
    );

    return (
        <FullscreenModal layout="fluid" className="GenerateAdjustments">
            <FullscreenModal.Header title="Generate Automated Batch">
                <Button
                    data-testid="generateAdjustmentsCancelButton"
                    onClick={isGenerating ? () => false : closeModal}
                    variant="tertiary"
                >
                    Cancel
                </Button>
            </FullscreenModal.Header>
            <FullscreenModal.Title title={title}>
                {AUTO_GENERATE_BATCH_MODAL_TITLE}
            </FullscreenModal.Title>
            <FullscreenModal.Body>
                <Page.Grid>
                    <Page.Col>{alertMessage}</Page.Col>
                    <GenerateAdjustmentsFormFields
                        changeHandler={changeHandler}
                        formData={formData}
                        isGenerating={isGenerating}
                        handleGenerate={handleGenerate}
                        step={step}
                        setStep={setStep}
                    />
                </Page.Grid>
            </FullscreenModal.Body>
        </FullscreenModal>
    );
};
