import React from 'react';
import { ApolloError } from '@apollo/client';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';

import { downloadFileResponse } from 'src/__fixtures__/graphql/abacus-download-response';
import { AbacusStatementPeriodAdjustmentFileErrorType } from 'src/apollo/definitions/globalTypes';
import * as abacusDownloadQuery from 'src/apollo/queries/abacus-download';
import {
    AdjustmentsContext,
    AdjustmentsContextProps,
} from 'src/contexts/adjustments-context';
import { AdjustmentsUploadFormatErrorScreen } from '../adjustments-upload-format-error-screen';

import type { AdjustmentFile } from 'src/types/adjustment-file';
import type { DownloadFileQuery } from 'src/apollo/queries/__generated__/abacus-download';

describe('<AdjustmentUploadFormatErrorScreen>', () => {
    const mockAdjustmentFileObj: AdjustmentFile = {
        actionStates: null,
        errorType: AbacusStatementPeriodAdjustmentFileErrorType.FORMAT_ERROR,
        fileName: 'test.xlsx',
        invalidFileLocation: null,
        invalidRowCount: null,
        md5sum: null,
        statementPeriodAdjustmentFileId: 999,
        statementPeriodId: '123',
        totalFileAmountMulticurrency: null,
        totalRoundedAmountMulticurrency: null,
        validFileLocation: null,
        validRowCount: null,
    };

    const defaultContext: Partial<AdjustmentsContextProps> = {
        adjustmentFile: mockAdjustmentFileObj,
        resetToInitialState: jest.fn(),
    };

    const renderComponent = (
        contextValues: Partial<AdjustmentsContextProps> = {}
    ) => {
        const adjustmentsContext = {
            ...defaultContext,
            ...contextValues,
        } as AdjustmentsContextProps;

        return renderInAppContext(
            <AdjustmentsContext.Provider value={adjustmentsContext}>
                <AdjustmentsUploadFormatErrorScreen />
            </AdjustmentsContext.Provider>
        );
    };

    const getDownloadFile = jest.fn();

    const mockDownloadFile: DownloadFileQuery = downloadFileResponse;

    let downloadTemplateRequestSpy: jest.SpyInstance<
        {
            data: DownloadFileQuery | undefined;
            error: ApolloError | undefined;
            loading: boolean;
        },
        [downloadType: any, downloadId: string]
    >;

    beforeEach(() => {
        downloadTemplateRequestSpy = jest
            .spyOn(abacusDownloadQuery, 'useAbacusDownloadFile')
            .mockReturnValue({
                data: mockDownloadFile,
                error: undefined,
                loading: false,
                getDownloadFile,
            });
    });

    it('renders the title', () => {
        renderComponent();

        const title = screen.getAllByText('Upload Failed')[0];
        expect(title).toBeDefined();
    });

    it('renders the alert', () => {
        renderComponent();

        const errorAlert = screen.getByTestId(
            'AdjustmentsFormatErrorFormatAlert'
        );
        expect(errorAlert).toHaveTextContent('wrong file template');
    });

    it('renders the upload area', () => {
        renderComponent();

        const uploadArea = screen.getByTestId(
            'AdjustmentsUploadFormatErrorFormatArea'
        );

        const input = uploadArea.querySelector(
            'input[type="file"]'
        ) as HTMLInputElement;

        expect(uploadArea).toHaveTextContent('Upload Failed');

        // The upload area is disabled so the file input should be hidden
        expect(input).toHaveStyle('display: none');
    });

    it('renders a link to download the template', () => {
        renderComponent();

        const downloadLink = screen.getByText('download the current here');

        fireEvent.click(downloadLink);

        expect(downloadTemplateRequestSpy).toHaveBeenCalled();
        expect(getDownloadFile).toHaveBeenCalled();
    });

    it('renders a button to reset to inital state', () => {
        renderComponent();

        const reUploadFileButton = screen.getByText('RE-UPLOAD FILE');
        fireEvent.click(reUploadFileButton);
        expect(defaultContext.resetToInitialState).toHaveBeenCalled();
    });

    it('renders a Slack link with correct href and attributes', () => {
        renderComponent();

        const slackLink = screen.getByText('Slack');
        expect(slackLink).toHaveAttribute(
            'href',
            'https://sonymusic.enterprise.slack.com/archives/C041MDL16UT'
        );
        expect(slackLink).toHaveAttribute('target', '_blank');
        expect(slackLink).toHaveAttribute('rel', 'noopener noreferrer');
    });

    it('renders an email link with correct mailto href', () => {
        renderComponent();

        const emailLink = screen.getByText('email');
        expect(emailLink).toHaveAttribute(
            'href',
            'mailto:abacus-squad@sonymusic-pde.com'
        );
    });
});
