import { act, fireEvent, render, screen } from '@testing-library/react';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import React from 'react';
import UpdatedAddRule from 'src/components/fingerprintRulesOAPanel/updatedAddRule/updated-add-rule';
import type { FingerprintRuleInput } from 'shared/data/schema';
import type { UpdatedAddRuleProps } from 'src/components/fingerprintRulesOAPanel/updatedAddRule/updated-add-rule';
import type { FingerprintRule } from 'src/types';

dayjs.extend(utc);

describe('<UpdateAddRule>', () => {
    const currentRules = [
        {
            active: true,
            policy: 'Monetize',
            service: 'Meta',
            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 higherLevelRules = [
        {
            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 territories = [
        {
            territoryCodeA2: 'FR',
            territoryName: 'France',
            continent: 'Europe',
        },
        {
            territoryCodeA2: 'US',
            territoryName: 'United States of America',
            continent: 'North America',
        },
    ];

    const defaultProps: UpdatedAddRuleProps = {
        title: 'Add rule',
        currentRules,
        higherLevelRules,
        isOpen: false,
        onClose: jest.fn(),
        onConfirm: (rules: FingerprintRuleInput[]) => undefined,
        territories,
    };

    const renderWrapper = (props: Partial<UpdatedAddRuleProps> = {}) =>
        render(<UpdatedAddRule {...defaultProps} {...props} />);

    test('renders default UpdatedAddRule', async () => {
        const { queryByTestId } = renderWrapper({ isOpen: true });
        const sidecar = await screen.findByTestId('sidecar');
        const countryDropdown = await screen.findByTestId('country-dropdown');
        const serviceDropdown = await screen.findByTestId('service-dropdown');
        const policyDropdown = await screen.findByTestId('policy-dropdown');
        const startDatePicker = queryByTestId('start-date-picker');
        const endDatePicker = queryByTestId('end-date-picker');

        expect(sidecar).toBeTruthy();
        expect(countryDropdown).toBeTruthy();
        expect(serviceDropdown).toBeTruthy();
        expect(policyDropdown).toBeTruthy();

        expect(startDatePicker).not.toBeInTheDocument();
        expect(endDatePicker).not.toBeInTheDocument();
    });

    test('renders editMode UpdatedAddRule', async () => {
        renderWrapper({
            title: 'Edit Rule',
            isOpen: true,
            editRowData: {
                policy: { value: 'Monetize' },
                service: { value: 'TikTok' },
                territories: ['FR'],
                startDate: '2023-01-01',
                endDate: '2023-02-01',
            },
        });
        const sidecar = await screen.findByTestId('sidecar');
        const countryDropdown = await screen.findByTestId('country-dropdown');
        const serviceDropdown = await screen.findByTestId('service-dropdown');
        const policyDropdown = await screen.findByTestId('policy-dropdown');
        const startDatePicker = await screen.findByTestId('start-date-picker');
        const endDatePicker = await screen.findByTestId('end-date-picker');

        expect(sidecar).toBeTruthy();
        expect(countryDropdown).toBeTruthy();
        expect(serviceDropdown).toBeTruthy();
        expect(policyDropdown).toBeTruthy();
        expect(startDatePicker).toBeTruthy();
        expect(endDatePicker).toBeTruthy();
    });

    test('renders UpdatedAddRule with the pre-set options', async () => {
        const { getByTestId, queryByTestId } = renderWrapper({
            isOpen: true,
            showSetUpSelection: true,
        });
        const sidecar = getByTestId('sidecar');
        const radioPreselectionCarveout = getByTestId(
            'radioPreselectionCarveout'
        );
        const radioPreselectionCustom = getByTestId('radioPreselectionCustom');
        const countryDropdown = queryByTestId('country-dropdown');
        const serviceDropdown = queryByTestId('service-dropdown');
        const policyDropdown = queryByTestId('policy-dropdown');
        const startDatePicker = queryByTestId('start-date-picker');
        const endDatePicker = queryByTestId('end-date-picker');

        expect(sidecar).toBeInTheDocument();
        expect(radioPreselectionCarveout).toBeInTheDocument();
        expect(radioPreselectionCustom).toBeInTheDocument();
        expect(countryDropdown).not.toBeInTheDocument();
        expect(serviceDropdown).not.toBeInTheDocument();
        expect(policyDropdown).not.toBeInTheDocument();
        expect(startDatePicker).not.toBeInTheDocument();
        expect(endDatePicker).not.toBeInTheDocument();
    });

    test('correctly selects custom pre-set', async () => {
        const { getByTestId, queryByTestId } = renderWrapper({
            isOpen: true,
            showSetUpSelection: true,
        });
        const radioPreselectionCustom = getByTestId('radioPreselectionCustom');

        act(() => {
            fireEvent.click(radioPreselectionCustom);
        });

        expect(queryByTestId('country-dropdown')).toBeInTheDocument();
        expect(queryByTestId('service-dropdown')).toBeInTheDocument();
        expect(queryByTestId('policy-dropdown')).toBeInTheDocument();
        expect(queryByTestId('start-date-picker')).toBeInTheDocument();
        expect(queryByTestId('end-date-picker')).toBeInTheDocument();
    });

    test('correctly selects carveout pre-set', async () => {
        const { getByTestId, queryByTestId } = renderWrapper({
            isOpen: true,
            showSetUpSelection: true,
        });
        const radioPreselectionCarveout = getByTestId(
            'radioPreselectionCarveout'
        );

        act(() => {
            fireEvent.click(radioPreselectionCarveout);
        });

        expect(queryByTestId('country-dropdown')).not.toBeInTheDocument();
        expect(queryByTestId('service-dropdown')).not.toBeInTheDocument();
        expect(queryByTestId('policy-dropdown')).not.toBeInTheDocument();
        expect(queryByTestId('start-date-picker')).not.toBeInTheDocument();
        expect(queryByTestId('end-date-picker')).not.toBeInTheDocument();
    });

    test('applies custom date range to end date picker when start date is selected', async () => {
        const { getByTestId } = renderWrapper({
            isOpen: true,
            showSetUpSelection: true,
        });

        const radioPreselectionCustom = getByTestId('radioPreselectionCustom');
        act(() => {
            fireEvent.click(radioPreselectionCustom);
        });

        const policyDropdown = getByTestId('policy-dropdown');
        expect(policyDropdown).toBeInTheDocument();

        // The component should render with date pickers when custom option is selected
        const startDatePicker = getByTestId('start-date-picker');
        const endDatePicker = getByTestId('end-date-picker');

        expect(startDatePicker).toBeInTheDocument();
        expect(endDatePicker).toBeInTheDocument();
    });

    test('calculates end date range correctly with 10 year offset', async () => {
        const testStartDate = '2024-06-01';
        const { getByTestId } = renderWrapper({
            isOpen: true,
            showSetUpSelection: true,
        });

        const radioPreselectionCustom = getByTestId('radioPreselectionCustom');
        act(() => {
            fireEvent.click(radioPreselectionCustom);
        });

        const policyDropdown = getByTestId('policy-dropdown');
        expect(policyDropdown).toBeInTheDocument();

        // Verify end date picker exists for non-carveout policies
        const endDatePicker = getByTestId('end-date-picker');
        expect(endDatePicker).toBeInTheDocument();

        // The end date picker should have the custom date range applied
        // which starts from startDate + 1 day and goes to 10 years from now
        const futureYear = new Date().getFullYear() + 10;
        const expectedMaxDate = dayjs(new Date(futureYear, 11, 31)).format(
            'YYYY-MM-DD'
        );

        expect(expectedMaxDate).toBeTruthy();
    });
});
