import React from 'react';
import { render, fireEvent, screen } from '@testing-library/react-native';
import DefaultMarketSelectorModal from '../DefaultMarketSelectorModalContainer';
import * as usePreSavedMarkets from '../../../hooks/usePreSavedMarkets';
import * as useSetPreSavedMarkets from '../../../hooks/useSetPreSavedMarkets';
import { bottomSheetHeaderAppliedFilters } from '../../../apollo/reactive-vars';

jest.mock('../../../i18n', () => ({
    formatMessage: jest.fn(key => key),
    formatUpperCase: jest.fn(key => key),
    getCurrentLanguage: jest.fn(() => 'en')
}));

jest.mock('../../../branding', () => ({
    ...jest.requireActual('../../../branding'),
    useTheme: () => ({ colors: { midnight800: '#000', midnight600: '#111' } })
}));

// Stub the heavy gorhom-backed BottomSheet: expose its title and footer buttons,
// and drive each footer button with the live draft (as the real host does).
jest.mock('../../../componentsDS/BottomSheet', () => {
    /* eslint-disable @typescript-eslint/no-var-requires */
    const ReactMock = require('react');
    const { Text, TouchableOpacity } = require('react-native');
    const {
        bottomSheetHeaderAppliedFilters: draft
    } = require('../../../apollo/reactive-vars');
    const {
        bottomSheetScreen: screens
    } = require('../../../screens/MyCatalogScreen/BottomSheetFilter/constants');
    /* eslint-enable @typescript-eslint/no-var-requires */

    return {
        __esModule: true,
        default: ({
            title,
            isVisible,
            footerButtons,
            onClose
        }: {
            title: string;
            isVisible: boolean;
            footerButtons: {
                title: string;
                onPress: (
                    routeName: string,
                    currentScreenFilters: string[],
                    filters: Record<string, string[]>
                ) => void;
            }[];
            onClose: () => void;
        }) =>
            isVisible
                ? ReactMock.createElement(
                      ReactMock.Fragment,
                      null,
                      ReactMock.createElement(
                          Text,
                          { testID: 'sheet-title' },
                          title
                      ),
                      ...footerButtons.map(button =>
                          ReactMock.createElement(TouchableOpacity, {
                              key: button.title,
                              testID: `footer-${button.title}`,
                              onPress: () =>
                                  button.onPress(
                                      screens.countries,
                                      draft()[screens.countries] || [],
                                      draft()
                                  )
                          })
                      ),
                      ReactMock.createElement(TouchableOpacity, {
                          testID: 'sheet-close',
                          onPress: onClose
                      })
                  )
                : null
    };
});

describe('DefaultMarketSelectorModal', () => {
    const setMarkets = jest.fn();
    const onClose = jest.fn();
    const existingMarket = 'US';

    const renderSheet = ({
        isVisible = true,
        savedMarkets = [] as string[]
    } = {}) => {
        jest.spyOn(usePreSavedMarkets, 'default').mockReturnValue({
            data: savedMarkets,
            loading: false
        } as ReturnType<typeof usePreSavedMarkets.default>);
        jest.spyOn(useSetPreSavedMarkets, 'default').mockReturnValue({
            setMarkets
        } as ReturnType<typeof useSetPreSavedMarkets.default>);

        return render(
            <DefaultMarketSelectorModal
                isVisible={isVisible}
                onClose={onClose}
            />
        );
    };

    beforeEach(() => {
        const i18n = jest.requireMock('../../../i18n');
        i18n.formatMessage.mockImplementation((key: string) => key);
        bottomSheetHeaderAppliedFilters({});
    });

    afterEach(jest.resetAllMocks);

    test('renders nothing while closed', () => {
        renderSheet({ isVisible: false });

        expect(screen.queryByTestId('sheet-title')).toBeNull();
    });

    test('shows the contextual MARKET title with Clear and Apply actions', () => {
        renderSheet();

        expect(screen.getByTestId('sheet-title').props.children).toBe(
            'filtering.market'
        );
        expect(screen.getByTestId('footer-button.clear')).toBeTruthy();
        expect(screen.getByTestId('footer-filtering.apply')).toBeTruthy();
    });

    test('applies the pre-saved markets and closes', () => {
        renderSheet({ savedMarkets: [existingMarket] });

        fireEvent.press(screen.getByTestId('footer-filtering.apply'));

        expect(setMarkets).toHaveBeenCalledWith([existingMarket]);
        expect(onClose).toHaveBeenCalledTimes(1);
    });

    test('clearing empties the selection so applying saves no markets', () => {
        renderSheet({ savedMarkets: [existingMarket] });

        fireEvent.press(screen.getByTestId('footer-button.clear'));
        fireEvent.press(screen.getByTestId('footer-filtering.apply'));

        expect(setMarkets).toHaveBeenCalledWith([]);
    });

    test('closing the sheet does not save', () => {
        renderSheet({ savedMarkets: [existingMarket] });

        fireEvent.press(screen.getByTestId('sheet-close'));

        expect(onClose).toHaveBeenCalledTimes(1);
        expect(setMarkets).not.toHaveBeenCalled();
    });
});
