import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as statementPeriodResponse from 'src/__fixtures__/graphql/statement-period-response.json';
import * as statementPeriodQueries from 'src/apollo/queries/statement-periods';
import StatementPeriodDetail from '../statement-period-detail';
import type { GetStatementPeriodQuery } from 'src/apollo/queries/statement-periods/__generated__/statement-period';

describe('<StatementPeriodDetail>', () => {
    let useStatementPeriodSpy: any;
    const render = () => renderInAppContext(<StatementPeriodDetail />);

    describe('no errors', () => {
        beforeEach(() => {
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: statementPeriodResponse as GetStatementPeriodQuery,
                    loading: false,
                    error: undefined,
                });
        });

        it('renders the statement period correctly', () => {
            render();
            expect(
                screen.getByText(
                    statementPeriodResponse.abacusStatementPeriod
                        .statementPeriodName,
                    { ignore: '.breadcrumb-item' }
                )
            ).toBeDefined();
            expect(useStatementPeriodSpy).toHaveBeenCalled();
        });

        it('renders the status/actions sidebar', () => {
            render();
            expect(screen.getByText('Status / Actions')).toBeDefined();
            expect(screen.getByText('UPLOAD EXCHANGE RATES')).toBeDefined();
            expect(screen.getByText('Release Physical Reserves')).toBeDefined();
            expect(screen.getByText('Close Statement Period')).toBeDefined();
        });
    });

    describe('errors', () => {
        beforeEach(() => {
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: {
                        abacusStatementPeriod: {
                            abacusEvents: [],
                            actionStates: [
                                {
                                    abacusStateId: '1',
                                    actionName: 'apply_pending_adjustments',
                                    actionStatus: 'init',
                                    message: null,
                                },
                                {
                                    abacusStateId: '2',
                                    actionName: 'mark_adjustments_applied',
                                    actionStatus: 'init',
                                    message: null,
                                },
                                {
                                    abacusStateId: '3',
                                    actionName: 'release_reserves',
                                    actionStatus: 'init',
                                    message: null,
                                },
                                {
                                    abacusStateId: '4',
                                    actionName: 'upload_exchange_rates',
                                    actionStatus: 'init',
                                    message: null,
                                },
                                {
                                    abacusStateId: '5',
                                    actionName: 'statement_period_close',
                                    actionStatus: 'error',
                                    message: null,
                                },
                            ],
                            statementPeriodId: '1',
                            statementPeriodName: 'July 2022',
                            statementPeriodStatus: 'current',
                            paymentEntities: [
                                {
                                    actionStates: [
                                        {
                                            abacusStateId: '304637',
                                            actionName: 'close_balance',
                                            actionStatus: 'init',
                                        },
                                    ],
                                    isVisibleToCustomer: false,
                                    pendingAdjustments: {
                                        totalCount: 0,
                                    },
                                    referencePaymentEntity: {
                                        paymentEntityName: 'AWAL-UK',
                                        referencePaymentEntityId: '1',
                                    },
                                    statementPeriodId: '1',
                                    statementPeriodPaymentEntityId: '1',
                                },
                            ],
                            statementPeriodAdjustmentFiles: [],
                        },
                    },
                    loading: false,
                    error: undefined,
                });
        });

        it('renders an alert if the statement_period_close state errors', () => {
            render();
            expect(
                screen.getByText(
                    'Please contact the Accounting Tech Team to resolve this issue.'
                )
            ).toBeDefined();
        });
    });

    describe('close statement period link', () => {
        const mockStatementPeriod = {
            abacusStatementPeriod: {
                abacusEvents: [],
                actionStates: [
                    {
                        abacusStateId: '1',
                        actionName: 'apply_pending_adjustments',
                        actionStatus: 'complete',
                        message: null,
                    },
                    {
                        abacusStateId: '2',
                        actionName: 'mark_adjustments_applied',
                        actionStatus: 'complete',
                        message: null,
                    },
                    {
                        abacusStateId: '3',
                        actionName: 'release_reserves',
                        actionStatus: 'complete',
                        message: null,
                    },
                    {
                        abacusStateId: '4',
                        actionName: 'upload_exchange_rates',
                        actionStatus: 'complete',
                        message: null,
                    },
                    {
                        abacusStateId: '5',
                        actionName: 'statement_period_close',
                        actionStatus: 'init',
                        message: null,
                    },
                ],
                statementPeriodId: '1',
                statementPeriodName: 'July 2022',
                statementPeriodStatus: 'current',
                paymentEntities: [
                    {
                        actionStates: [
                            {
                                abacusStateId: '304637',
                                actionName: 'close_balance',
                                actionStatus: 'init',
                            },
                        ],
                        isVisibleToCustomer: false,
                        pendingAdjustments: {
                            totalCount: 0,
                        },
                        referencePaymentEntity: {
                            paymentEntityName: 'AWAL-UK',
                            referencePaymentEntityId: '1',
                        },
                        statementPeriodId: '1',
                        statementPeriodPaymentEntityId: '1',
                    },
                ],
                statementPeriodAdjustmentFiles: [],
            },
        };

        it('renders a disabled close statement period link if customer accounting actions are not complete', () => {
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: mockStatementPeriod,
                    loading: false,
                    error: undefined,
                });
            render();
            const button = screen.getByText('Close Statement Period');
            expect(button).toHaveAttribute('disabled');
        });

        it('renders enable close statement period link if customer accounting actions are complete', () => {
            const mockData = {
                ...mockStatementPeriod,
                paymentEntities: [
                    {
                        isVisibleToCustomer: true,
                        referencePaymentEntity: {
                            paymentEntityName: 'AWAL-UK',
                            referencePaymentEntityId: '1',
                        },
                        statementPeriodId: '1',
                        statementPeriodPaymentEntityId: '1',
                    },
                ],
            };
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: mockData,
                    loading: false,
                    error: undefined,
                });
            render();
            const button = screen.getByText('Close Statement Period');
            expect(button.getAttribute('disabled')).toBe('');
        });

        it(`disables close statement period link when all adjustments are not applied`, () => {
            const updatedMockStatementPeriod = {
                abacusStatementPeriod: {
                    ...mockStatementPeriod.abacusStatementPeriod,
                    statementPeriodAdjustmentFiles: [
                        {
                            actionStates: [
                                {
                                    abacusStateId: '6',
                                    actionName: 'upload_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '7',
                                    actionName: 'import_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '8',
                                    actionName: 'approve_file',
                                    actionStatus: 'init',
                                },
                                {
                                    abacusStateId: '9',
                                    actionName: 'apply_file',
                                    actionStatus: 'init',
                                },
                            ],
                            statementPeriodAdjustmentFileId: '1',
                        },
                        {
                            actionStates: [
                                {
                                    abacusStateId: '10',
                                    actionName: 'upload_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '11',
                                    actionName: 'import_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '12',
                                    actionName: 'approve_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '13',
                                    actionName: 'apply_file',
                                    actionStatus: 'complete',
                                },
                            ],
                            statementPeriodAdjustmentFileId: '2',
                        },
                    ],
                    paymentEntities: [
                        {
                            actionStates: [
                                {
                                    abacusStateId: '304637',
                                    actionName: 'close_balance',
                                    actionStatus: 'init',
                                },
                            ],
                            isVisibleToCustomer: true,
                            pendingAdjustments: {
                                totalCount: 0,
                            },
                            referencePaymentEntity: {
                                paymentEntityName: 'AWAL-UK',
                                referencePaymentEntityId: '1',
                            },
                            statementPeriodId: '1',
                            statementPeriodPaymentEntityId: '1',
                        },
                    ],
                },
            };
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: updatedMockStatementPeriod,
                    loading: false,
                    error: undefined,
                });
            render();
            const button = screen.getByText('Close Statement Period');
            expect(button).toHaveAttribute('disabled');
        });

        it(`enables close statement period link when all adjustments are applied and
            FF "abacus_remove_apply_pending_adjustments" is enabled`, () => {
            const updatedMockStatementPeriod = {
                abacusStatementPeriod: {
                    ...mockStatementPeriod.abacusStatementPeriod,
                    statementPeriodAdjustmentFiles: [
                        {
                            actionStates: [
                                {
                                    abacusStateId: '6',
                                    actionName: 'upload_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '7',
                                    actionName: 'import_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '9',
                                    actionName: 'approve_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '9',
                                    actionName: 'apply_file',
                                    actionStatus: 'complete',
                                },
                            ],
                            statementPeriodAdjustmentFileId: '1',
                        },
                        {
                            actionStates: [
                                {
                                    abacusStateId: '10',
                                    actionName: 'upload_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '11',
                                    actionName: 'import_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '12',
                                    actionName: 'approve_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '13',
                                    actionName: 'apply_file',
                                    actionStatus: 'complete',
                                },
                            ],
                            statementPeriodAdjustmentFileId: '2',
                        },
                        {
                            actionStates: [
                                {
                                    abacusStateId: '14',
                                    actionName: 'upload_file',
                                    actionStatus: 'complete',
                                },
                                {
                                    abacusStateId: '15',
                                    actionName: 'import_file',
                                    actionStatus: 'init',
                                },
                                {
                                    abacusStateId: '16',
                                    actionName: 'approve_file',
                                    actionStatus: 'init',
                                },
                                {
                                    abacusStateId: '17',
                                    actionName: 'apply_file',
                                    actionStatus: 'init',
                                },
                            ],
                            statementPeriodAdjustmentFileId: '3',
                        },
                    ],
                    paymentEntities: [
                        {
                            actionStates: [
                                {
                                    abacusStateId: '304637',
                                    actionName: 'close_balance',
                                    actionStatus: 'complete',
                                },
                            ],
                            isVisibleToCustomer: true,
                            pendingAdjustments: {
                                totalCount: 0,
                            },
                            referencePaymentEntity: {
                                paymentEntityName: 'AWAL-UK',
                                referencePaymentEntityId: '1',
                            },
                            statementPeriodId: '1',
                            statementPeriodPaymentEntityId: '1',
                        },
                    ],
                },
            };
            useStatementPeriodSpy = jest
                .spyOn(statementPeriodQueries, 'useStatementPeriod')
                .mockReturnValue({
                    data: updatedMockStatementPeriod,
                    loading: false,
                    error: undefined,
                });
            render();
            const button = screen.getByText('Close Statement Period');
            expect(button.getAttribute('disabled')).toBeNull();
        });
    });
});
