import * as apollo from '@apollo/client';
import { fireEvent, render } from '@testing-library/react';
import { ToastProvider } from '@theorchard/suite-frontend';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import React from 'react';
import * as accountMutation from 'src/data/mutations';
import DeliveryRules from '../delivery-rules';
import type { AccountFingerprintRules, FingerprintRule } from 'src/types';
import type { DeliveryRulesProps } from '../delivery-rules';

dayjs.extend(utc);

describe('<DeliveryRules>', () => {
    const vendorRules = [
        {
            active: true,
            policy: 'Monetize',
            service: 'TikTok',
            territory: 'FR',
            startDate: dayjs
                .utc('2023-01-02T00:00:00.000Z')
                .format('D MMM YYYY'),
            endDate: '-',
            createdDate: dayjs
                .utc('2023-01-01T00:00:00.000Z')
                .format('D MMM YYYY'),
            lastModifiedDate: dayjs
                .utc('2023-01-01T00:00:00.000Z')
                .format('D MMM YYYY'),
            createdBy: {
                profileId: '123',
                profileType: 'ContentProfile',
                profileName: 'Name',
            },
            lastModifiedBy: {
                profileId: '123',
                profileType: 'ContentProfile',
                profileName: 'Name',
            },
        },
    ] as FingerprintRule[];
    const subaccountRules = [] as FingerprintRule[];
    const territories = [
        {
            territoryCodeA2: 'FR',
            territoryName: 'France',
            continent: 'Europe',
        },
        {
            territoryCodeA2: 'US',
            territoryName: 'United States of America',
            continent: 'North America',
        },
    ];
    const accountRules = {
        accountType: 'Vendor',
        accountId: 123,
        vendorRules,
        subaccountRules,
    } as AccountFingerprintRules;
    const territoriesFilter = ['GLOBAL'];
    const defaultProps: DeliveryRulesProps = {
        rules: accountRules,
        territories,
        territoriesFilter,
        editable: true,
    };
    beforeEach(() => {
        jest.spyOn(apollo, 'useMutation').mockReturnValue([
            jest.fn(),
            {} as apollo.MutationResult,
        ]);
        jest.spyOn(accountMutation, 'useSetFingerprintRulesForVendorMutation');
        jest.spyOn(
            accountMutation,
            'useSetFingerprintRulesForSubaccountMutation'
        );
    });

    afterEach(jest.restoreAllMocks);

    const renderWrapper = (props: Partial<DeliveryRulesProps> = {}) =>
        render(
            <ToastProvider>
                <DeliveryRules {...defaultProps} {...props} />
            </ToastProvider>
        );

    test('renders default filters and table for current rules', () => {
        const { container } = renderWrapper();
        expect(container).toMatchSnapshot();
    });

    test('renders default filters and table for current and scheduled rules', () => {
        const accountRulesWithScheduled = [
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'FR',
                startDate: dayjs
                    .utc('2025-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: '-',
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'US',
                startDate: dayjs
                    .utc('2023-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: '-',
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
        ] as FingerprintRule[];
        const subaccountRules = [] as FingerprintRule[];
        const { container } = renderWrapper({
            rules: {
                accountType: 'Vendor',
                vendorRules: accountRulesWithScheduled,
                subaccountRules,
            } as AccountFingerprintRules,
        });
        expect(container).toMatchSnapshot();
    });

    test('renders vendor and subaccount rules if in subaccount mode', () => {
        const vendorRules = [
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'US',
                startDate: dayjs
                    .utc('2023-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: '-',
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
        ] as FingerprintRule[];
        const subaccountRules = [
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'FR',
                startDate: dayjs
                    .utc('2023-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: '-',
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
        ] as FingerprintRule[];
        const { container } = renderWrapper({
            rules: {
                accountType: 'Subaccount',
                vendorRules,
                subaccountRules,
            } as AccountFingerprintRules,
        });
        expect(container).toMatchSnapshot();
    });

    test('renders only expired table when selected', () => {
        const accountRulesWithScheduled = [
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'FR',
                startDate: dayjs
                    .utc('2021-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: dayjs
                    .utc('2021-02-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
            {
                active: true,
                policy: 'Monetize',
                service: 'TikTok',
                territory: 'US',
                startDate: dayjs
                    .utc('2023-01-02T00:00:00.000Z')
                    .format('D MMM YYYY'),
                endDate: '-',
                createdDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                lastModifiedDate: dayjs
                    .utc('2023-01-01T00:00:00.000Z')
                    .format('D MMM YYYY'),
                createdBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
                lastModifiedBy: {
                    profileId: '123',
                    profileType: 'ContentProfile',
                    profileName: 'Name',
                },
            },
        ] as FingerprintRule[];
        const subaccountRules = [] as FingerprintRule[];
        const { container, getByTestId } = renderWrapper({
            rules: {
                accountType: 'Vendor',
                vendorRules: accountRulesWithScheduled,
                subaccountRules,
            } as AccountFingerprintRules,
        });

        const button = getByTestId('btn-expired');
        fireEvent.click(button);

        expect(container).toMatchSnapshot();
    });
});
