import React from 'react';
import { Form } from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import {
    CONTRACT_FLOWTHROUGH_RATE_ERROR_MSG,
    CONTRACT_FLOWTHROUGH_RECOUPMENT_CAP_ERROR_MSG,
} from 'src/constants';
import { ContractFlowthroughCalculationComment } from './contract-flowthrough-calculation-comment';
import { ContractFlowthroughCalculation } from './contract-flowthrough-calculation';
import { ContractFlowthroughRate } from './contract-flowthrough-rate';
import { ContractFlowthroughRecoupmentCap } from './contract-flowthrough-recoupment-cap';
import { ContractFlowthroughStatus } from './contract-flowthrough-status';
import type {
    AbacusContractFlowthroughInput,
    AbacusContractFlowthroughUpdate,
} from 'src/apollo/definitions/globalTypes';
import type {
    AbacusContractFlowthroughErrorFieldKeys,
    AbacusContractFlowthroughErrors,
} from 'src/types/abacus-contract-flowthrough-input-errors';
import {
    isFlowthroughCalculationUsingComment,
    isFlowthroughCalculationUsingRate,
    isFlowthroughCalculationUsingRecoupmentCap,
    isFlowthroughRateValid,
    isFlowthroughRecoupmentCapValid,
} from 'src/utils/contract-flowthrough';

export interface ContractFlowthroughFormFieldsPropTypes {
    abacusContractFlowthrough:
        | Partial<AbacusContractFlowthroughInput>
        | AbacusContractFlowthroughUpdate;
    errors: AbacusContractFlowthroughErrors;
    isEditForm: boolean;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    serverErrors: any;
    setAbacusContractFlowthrough: (
        // eslint-disable-next-line no-unused-vars
        params:
            | Partial<AbacusContractFlowthroughInput>
            | AbacusContractFlowthroughUpdate
    ) => void;
    // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-explicit-any
    setServerErrors: (params: any) => void;
    // eslint-disable-next-line no-unused-vars
    setErrors: (params: AbacusContractFlowthroughErrors) => void;
}

export const ContractFlowthroughFormFields: React.FC<
    ContractFlowthroughFormFieldsPropTypes
> = ({
    abacusContractFlowthrough,
    errors,
    isEditForm,
    setAbacusContractFlowthrough,
    setErrors,
    serverErrors,
    setServerErrors,
}) => {
    const defaultedContractFlowthroughValues = {
        hasAutomaticShutoff:
            abacusContractFlowthrough?.hasAutomaticShutoff ?? true,
        ...abacusContractFlowthrough,
    };

    const updateError = (
        field: AbacusContractFlowthroughErrorFieldKeys,
        message: string | undefined
    ) => {
        setErrors((prev: AbacusContractFlowthroughErrors) => ({
            ...prev,
            [field]: message,
        }));
    };

    const handleFormChange = (
        fieldName: string,
        inputValue: boolean | string | null | undefined
    ) => {
        // Reset the state when the calculation option changes
        if (fieldName === 'referenceFlowthroughCalculationId' && inputValue) {
            setErrors({});

            setAbacusContractFlowthrough({
                ...abacusContractFlowthrough,
                referenceFlowthroughCalculationId: inputValue as string,
                flowthroughRate: undefined,
                recoupmentCap: undefined,
                calculationComment: null,
            });

            return;
        }

        setAbacusContractFlowthrough({
            ...abacusContractFlowthrough,
            [fieldName]: inputValue,
        });
    };

    const handleFormChangeValidation = (
        fieldName: string,
        inputValue: string | null | undefined
    ) => {
        if (
            fieldName === 'flowthroughRate' &&
            inputValue !== null &&
            inputValue !== undefined
        ) {
            if (!isFlowthroughRateValid(inputValue)) {
                updateError(
                    'flowthroughRate',
                    CONTRACT_FLOWTHROUGH_RATE_ERROR_MSG
                );
                return;
            }
            updateError('flowthroughRate', undefined);
            setAbacusContractFlowthrough({
                ...abacusContractFlowthrough,
                [fieldName]: parseFloat(inputValue),
            });
        }

        if (
            fieldName === 'recoupmentCap' &&
            inputValue !== null &&
            inputValue !== undefined
        ) {
            if (!isFlowthroughRecoupmentCapValid(inputValue)) {
                updateError(
                    'recoupmentCap',
                    CONTRACT_FLOWTHROUGH_RECOUPMENT_CAP_ERROR_MSG
                );
                return;
            }
            updateError('recoupmentCap', undefined);
            setAbacusContractFlowthrough({
                ...abacusContractFlowthrough,
                [fieldName]: parseFloat(inputValue),
            });
        }
    };

    const showRate = isFlowthroughCalculationUsingRate(
        abacusContractFlowthrough.referenceFlowthroughCalculationId
    );
    const showRecoupmentCap = isFlowthroughCalculationUsingRecoupmentCap(
        abacusContractFlowthrough.referenceFlowthroughCalculationId
    );

    const showComment = isFlowthroughCalculationUsingComment(
        abacusContractFlowthrough.referenceFlowthroughCalculationId
    );

    return (
        <div className="ContractFlowthroughFormFields">
            <ContractFlowthroughCalculation
                abacusContractFlowthroughCalculationId={
                    defaultedContractFlowthroughValues.referenceFlowthroughCalculationId ??
                    undefined
                }
                errors={errors}
                serverErrors={serverErrors}
                setServerErrors={setServerErrors}
                handleFormChange={handleFormChange}
            />
            {showRate && (
                <ContractFlowthroughRate
                    abacusContractFlowthrough={{
                        flowthroughRate:
                            defaultedContractFlowthroughValues.flowthroughRate ??
                            undefined,
                    }}
                    errors={errors}
                    handleFormChange={handleFormChange}
                    handleFormChangeValidation={handleFormChangeValidation}
                />
            )}
            {showRecoupmentCap && (
                <ContractFlowthroughRecoupmentCap
                    abacusContractFlowthroughRecoupmentCap={
                        defaultedContractFlowthroughValues.recoupmentCap || null
                    }
                    errors={errors}
                    handleFormChange={handleFormChange}
                    handleFormChangeValidation={handleFormChangeValidation}
                />
            )}
            {showComment && (
                <ContractFlowthroughCalculationComment
                    abacusContractFlowthroughCalculationComment={
                        defaultedContractFlowthroughValues.calculationComment ||
                        abacusContractFlowthrough.calculationComment ||
                        null
                    }
                    handleFormChange={handleFormChange}
                />
            )}
            {isEditForm && (
                <ContractFlowthroughStatus
                    abacusContractFlowthrough={
                        abacusContractFlowthrough as AbacusContractFlowthroughUpdate
                    }
                    errors={errors}
                    handleFormChange={handleFormChange}
                />
            )}
            <hr />
            <Form.Text
                className="ContractFlowthroughFormFields-Text-Info"
                muted
            >
                <GlyphIcon name="info" size={16} />
                Abacus does not support automatic flowthrough payments yet.
            </Form.Text>
        </div>
    );
};
