import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import {
    AbacusContractMechDeductionAdminType,
    AbacusContractMechDeductionMechanicalType,
    AbacusContractMechDeductionTerritory,
} from 'src/apollo/definitions/globalTypes';
import {
    ContractMechanicalDeductions,
    ContractMechanicalDeductionsPropsTypes,
} from 'src/components/contract-detail/contract-mechanical-deductions';
import {
    ABACUS_PROFILE,
    NO_CONTRACT_MECHANICAL_DEDUCTIONS,
} from 'src/constants';

describe('<ContractMechanicalDeductions />', () => {
    const render = (props: ContractMechanicalDeductionsPropsTypes) =>
        renderInAppContext(<ContractMechanicalDeductions {...props} />, {
            identity: createIdentity({ profileType: ABACUS_PROFILE }),
        });

    const props: ContractMechanicalDeductionsPropsTypes = {
        contractId: '1234',
        mechanicalDeductions: [],
    };

    it('renders the mechanical deductions component', () => {
        render(props);
        expect(
            screen.getByTestId('contractMechanicalDeductionsCard')
        ).toBeDefined();
        expect(screen.getByText('Mechanical Deductions')).toBeDefined();
    });

    it('renders the add dropdown button', () => {
        render(props);
        expect(
            screen.getByTestId('contractMechanicalDeductionsDropdownButton')
        ).toBeDefined();
    });

    it('disables the add dropdown button when there are 3 mechanical deductions', () => {
        const mechanicalDeductions = [
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '1',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.USA,
            },
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '2',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.CAN,
            },
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '3',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.ROW,
            },
        ];
        const newProps = {
            ...props,
            mechanicalDeductions,
        };
        render(newProps);
        const addDropdownButton = screen.getByText('Add');
        expect(addDropdownButton).toBeDefined();
        expect(addDropdownButton).toBeDisabled();
    });

    it('shows dropdown options on click of Add button', async () => {
        render(props);

        const addButton = screen.getByText('Add');
        fireEvent.click(addButton);

        expect(await screen.findByText('Worldwide')).toBeDefined();
        expect(await screen.findByText('Individual Territory')).toBeDefined();
    });

    it('disables the worldwide option when there is a mechanical deduction', async () => {
        const mechanicalDeductions = [
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '1',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.USA,
            },
        ];
        const newProps = {
            ...props,
            mechanicalDeductions,
        };
        render(newProps);

        const addButton = screen.getByText('Add');
        fireEvent.click(addButton);

        const worldwideOption = await screen.findByText('Worldwide');
        expect(worldwideOption).toBeDefined();
        expect(worldwideOption.closest('.SuiteListView-option')).toHaveClass(
            'disabled'
        );
    });

    it('does not disable the worldwide option when there are no mechanical deductions', async () => {
        render(props);

        const addButton = screen.getByText('Add');
        fireEvent.click(addButton);

        const worldwideOption = await screen.findByText('Worldwide');
        expect(worldwideOption).toBeDefined();
        expect(worldwideOption).not.toHaveClass('disabled');
    });

    it('renders fullscreen modal for worldwide deduction on click of worldwide option', async () => {
        render(props);

        const addButton = screen.getByText('Add');
        fireEvent.click(addButton);

        const worldwideOption = await screen.findByText('Worldwide');
        fireEvent.click(worldwideOption);

        expect(await screen.findByTestId('header-title')).toHaveTextContent(
            'Setup mechanical deductionsworldwide'
        );
    });

    it('renders fullscreen modal for individual deduction on click of individual territory option', async () => {
        render(props);

        const addButton = screen.getByText('Add');
        fireEvent.click(addButton);

        const worldwideOption = await screen.findByText('Individual Territory');
        fireEvent.click(worldwideOption);

        expect(await screen.findByTestId('header-title')).toHaveTextContent(
            'Setup a mechanical deduction'
        );
    });

    it('renders the no contract mechanical deductions message when there is no data', () => {
        render(props);
        expect(
            screen.getByText(NO_CONTRACT_MECHANICAL_DEDUCTIONS)
        ).toBeDefined();
    });

    it('renders the mechanical deductions card when data is present', () => {
        const mechanicalDeductions = [
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '1',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.USA,
            },
        ];
        const newProps = {
            ...props,
            mechanicalDeductions,
        };
        render(newProps);
        expect(screen.getByTestId('mechanicalDeductionCard')).toBeDefined();
        expect(
            screen.queryByText(NO_CONTRACT_MECHANICAL_DEDUCTIONS)
        ).toBeNull();
    });

    it('renders multiple mechanical deductions cards when data is present', () => {
        const mechanicalDeductions = [
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '1',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.USA,
            },
            {
                adminFee: 12.2,
                adminType: AbacusContractMechDeductionAdminType.BOTH,
                contractId: '1234',
                contractMechanicalDeductionId: '2',
                mechanicalType: [
                    AbacusContractMechDeductionMechanicalType.DIGITAL,
                ],
                territory: AbacusContractMechDeductionTerritory.CAN,
            },
        ];
        const newProps = {
            ...props,
            mechanicalDeductions,
        };
        render(newProps);
        expect(screen.getAllByTestId('mechanicalDeductionCard')).toHaveLength(
            2
        );
    });
});
