import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { Route } from 'react-router-dom';
import { assignedContributionsList } from 'src/__fixtures__/graphql/contributions';
import {
    contributorSchedule,
    contributorScheduleNotAutoAdd,
} from 'src/__fixtures__/graphql/schedule';
import * as nrContributionQueries from 'src/apollo/queries/nr-contributions';
import * as scheduleQueries from 'src/apollo/queries/schedule';
import { AUTO_ADD_TEXT, NO_AUTO_ADD_TEXT } from 'src/constants';
import { getContributorScheduleDetail } from 'src/urls/frontend-royalties';
import ScheduleDetail from '../schedule-detail';

describe('<ScheduleDetail/>', () => {
    let useScheduleByIdSpy: any;
    const contributorId = contributorSchedule.abacusSchedule.targetId;
    const scheduleId = contributorSchedule.abacusSchedule.scheduleId;

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        useScheduleByIdSpy = jest
            .spyOn(scheduleQueries, 'useScheduleById')
            .mockReturnValue({
                data: contributorSchedule,
                error: undefined,
                loading: false,
            });

        jest.spyOn(
            nrContributionQueries,
            'useNRContributionsList'
        ).mockReturnValue({
            data: assignedContributionsList,
            error: undefined,
            loading: false,
            fetchMore: jest.fn(),
            fetchNextExistingPage: jest.fn(),
        });
    });

    const render = () =>
        renderInAppContext(
            <Route path="/contributor/:contributorId/schedule/:scheduleId">
                <ScheduleDetail />
            </Route>,
            {
                pathname: getContributorScheduleDetail(
                    contributorId,
                    scheduleId
                ),
            }
        );

    it('renders', () => {
        const { container } = render();
        expect(container).toBeDefined();
    });

    it('requests schedule detail on render', () => {
        render();
        expect(useScheduleByIdSpy).toHaveBeenCalledWith(scheduleId);
    });

    it('displays the schedule name', () => {
        render();
        expect(
            screen.getByText(contributorSchedule.abacusSchedule.scheduleName)
        ).toBeDefined();
    });

    it('displays a message for auto-add schedules', () => {
        render();
        expect(screen.getByText(AUTO_ADD_TEXT)).toBeDefined();
        expect(contributorSchedule.abacusSchedule.conditions?.autoAdd).toBe(
            true
        );
    });

    it('displays a message for non auto-add schedules', () => {
        jest.spyOn(scheduleQueries, 'useScheduleById').mockReturnValue({
            data: contributorScheduleNotAutoAdd,
            error: undefined,
            loading: false,
        });

        render();
        expect(screen.getByText(NO_AUTO_ADD_TEXT)).toBeDefined();
    });

    it('renders a link-button that links to the edit contributor schedule page', () => {
        render();
        const link = screen.getByRole('link', { name: 'Edit' });

        expect(link.getAttribute('href')).toContain(
            `/contributor/${contributorId}/schedule/${scheduleId}/edit`
        );
        expect(link.textContent).toEqual('Edit');
    });

    it('renders a section to display unassigned contributions', () => {
        render();
        expect(screen.getByText('Unassigned Contributions')).toBeDefined();
    });

    it('renders a section to display assigned contributions', () => {
        render();
        expect(screen.getByText('Assigned Contributions')).toBeDefined();
    });
});
