import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { testComponent } from 'lib/test-utils/common';
import { NumberInput, Props } from '../numberInput';

describe('<NumberInput>', () => {
    const defaultProps: Props = {
        value: '12',
        onChange: vi.fn(),
        allowNegatives: true,
        placeholder: 'Enter Number',
    };

    beforeEach(() => {
        vi.resetAllMocks();
    });

    testComponent(NumberInput, defaultProps);

    const renderComponent = (props?: Partial<Props>) =>
        render(<NumberInput {...defaultProps} {...props} />);

    test('Increments value by arrows', () => {
        const { getByTestId } = renderComponent();
        const upGlyph = getByTestId('CaretUpGlyph');
        if (upGlyph) fireEvent.click(upGlyph);
        expect(defaultProps.onChange).toHaveBeenCalledWith('13');
    });

    test('Decrements value by arrows', () => {
        const { getByTestId } = renderComponent();
        const downGlyph = getByTestId('CaretDownGlyph');
        if (downGlyph) fireEvent.click(downGlyph);
        expect(defaultProps.onChange).toHaveBeenCalledWith('11');
    });

    test('Should not decrement by arrows if disabled', () => {
        const { getByTestId } = renderComponent({ disabled: true });
        const downGlyph = getByTestId('CaretDownGlyph');
        if (downGlyph) fireEvent.click(downGlyph);
        expect(defaultProps.onChange).not.toHaveBeenCalledWith('11');
    });

    test('should not allow negative values if allowNegatives is false', () => {
        const { getByTestId } = renderComponent({
            value: '0',
            allowNegatives: false,
        });
        const downGlyph = getByTestId('CaretDownGlyph');
        if (downGlyph) fireEvent.click(downGlyph);
        expect(defaultProps.onChange).not.toHaveBeenCalled();
    });

    test('should allow decimal precision', () => {
        const { getByDisplayValue } = renderComponent({
            value: '15',
            allowNegatives: false,
            decimalPrecision: 2,
        });
        const input = getByDisplayValue('15');
        if (input) fireEvent.change(input, { target: { value: '23.234' } });
        expect(defaultProps.onChange).toHaveBeenCalledWith('23.23');
    });

    test('should allow decimals that start with 0', () => {
        const { getByDisplayValue } = renderComponent({
            value: '15',
            allowNegatives: false,
            decimalPrecision: 2,
        });
        const input = getByDisplayValue('15');
        if (input) fireEvent.change(input, { target: { value: '23.01' } });
        expect(defaultProps.onChange).toHaveBeenCalledWith('23.01');
    });

    test('should allow decimal negatives', () => {
        const { getByDisplayValue } = renderComponent({
            value: '15',
            allowNegatives: false,
            decimalPrecision: 2,
        });
        const input = getByDisplayValue('15');
        if (input) fireEvent.change(input, { target: { value: '-23.23' } });
        expect(defaultProps.onChange).toHaveBeenCalledWith('-23.23');
    });
});
