import {
    AbacusEarningsTransferRateTypes,
    AbacusEarningsTransferSources,
} from 'src/apollo/definitions/globalTypes';
import {
    validateAmount,
    createEmptyUiState,
    createUiState,
} from '../contract-earnings-transfer-config-screen-columns';
import { TransferRow } from 'src/types/abacus-contract-earnings-transfer';

describe('validateAmount', () => {
    describe('empty value', () => {
        it('returns undefined for empty string regardless of rateType', () => {
            expect(
                validateAmount('', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBeUndefined();
            expect(
                validateAmount('', AbacusEarningsTransferRateTypes.FLAT_RATE)
            ).toBeUndefined();
            expect(validateAmount('', undefined)).toBeUndefined();
        });
    });

    describe('invalid number', () => {
        it('returns error message for non-numeric input', () => {
            expect(
                validateAmount('abc', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBe('Please enter a valid number');
            expect(
                validateAmount('---', AbacusEarningsTransferRateTypes.FLAT_RATE)
            ).toBe('Please enter a valid number');
        });
    });

    describe('PERCENT rate type', () => {
        it('returns error when value is below 0', () => {
            expect(
                validateAmount('-1', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBe('Value must be between .01 and 100');
        });

        it('returns error when value is above 100', () => {
            expect(
                validateAmount('101', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBe('Value must be between .01 and 100');
            expect(
                validateAmount(
                    '100.01',
                    AbacusEarningsTransferRateTypes.PERCENT
                )
            ).toBe('Value must be between .01 and 100');
        });

        it('returns an error for value 0', () => {
            expect(
                validateAmount('0', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBe('Value must be between .01 and 100');
        });

        it('returns undefined for value 100', () => {
            expect(
                validateAmount('100', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBeUndefined();
        });

        it('returns undefined for valid value within 0-100', () => {
            expect(
                validateAmount('50', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBeUndefined();
            expect(
                validateAmount('12.5', AbacusEarningsTransferRateTypes.PERCENT)
            ).toBeUndefined();
        });
    });

    describe('FLAT_RATE rate type', () => {
        it('returns error when value is 0', () => {
            expect(
                validateAmount('0', AbacusEarningsTransferRateTypes.FLAT_RATE)
            ).toBe('Value must be a positive number');
        });

        it('returns error when value is negative', () => {
            expect(
                validateAmount(
                    '-100',
                    AbacusEarningsTransferRateTypes.FLAT_RATE
                )
            ).toBe('Value must be a positive number');
        });

        it('returns undefined for positive value', () => {
            expect(
                validateAmount('1', AbacusEarningsTransferRateTypes.FLAT_RATE)
            ).toBeUndefined();
            expect(
                validateAmount(
                    '999.99',
                    AbacusEarningsTransferRateTypes.FLAT_RATE
                )
            ).toBeUndefined();
        });
    });

    describe('undefined rate type', () => {
        it('returns undefined for any valid number when rateType is undefined', () => {
            expect(validateAmount('150', undefined)).toBeUndefined();
            expect(validateAmount('-50', undefined)).toBeUndefined();
            expect(validateAmount('0', undefined)).toBeUndefined();
        });
    });
});

describe('createEmptyUiState', () => {
    it('returns correct default values', () => {
        const uiState = createEmptyUiState();
        expect(uiState.selectedAccount).toBeUndefined();
        expect(uiState.selectedContract).toBeUndefined();
        expect(uiState.amountError).toBeUndefined();
        expect(uiState.contractOptions).toEqual([]);
        expect(uiState.contractsLoading).toBe(false);
    });

    it('returns a new object on each call', () => {
        const a = createEmptyUiState();
        const b = createEmptyUiState();
        expect(a).not.toBe(b);
        expect(a.contractOptions).not.toBe(b.contractOptions);
    });
});

describe('createUiState', () => {
    it('returns the correct values', () => {
        const row: TransferRow = {
            rowId: '1',
            fromContractId: '1',
            toAccountId: '1',
            toAccountName: 'Account1',
            toContractId: '1',
            toContractName: 'Contract1',
            rateType: AbacusEarningsTransferRateTypes.FLAT_RATE,
            transferAmount: '100',
            input: AbacusEarningsTransferSources.CLOSING_BALANCE,
            negative: false,
            active: true,
        };

        expect(createUiState(row)).toEqual({
            selectedAccount: {
                label: 'Account1',
                value: '1',
            },
            selectedContract: {
                label: 'Contract1',
                value: '1',
            },
            amountError: undefined,
            contractOptions: [],
            contractsLoading: false,
        });
    });
});
