import { renderHook } from '@testing-library/react';
import { usePostViewerEvents } from '../usePostViewerEvents';
import { useStore } from '../../services/store';
import { IMedia } from '../../types';

jest.mock('../../services/store', () => ({
  useStore: jest.fn(),
}));

const makePost = (products: IMedia['products'] = []): IMedia => ({
  id: 'post-1',
  type: 'image',
  caption: 'caption',
  source: 'instagram',
  post: 'https://example.com/post',
  productsLinked: {},
  postIndex: 0,
  products,
});

describe('usePostViewerEvents', () => {
  let mockTriggerEvent: jest.Mock;

  beforeEach(() => {
    jest.clearAllMocks();
    mockTriggerEvent = jest.fn();
  });

  const mockStore = (overrides = {}) => {
    (useStore as jest.Mock).mockReturnValue({
      isMobile: false,
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'none',
          mobile_player_display: true,
          display_desktop_player: false,
        },
      },
      triggerEvent: mockTriggerEvent,
      ...overrides,
    });
  };

  it('fires postOpened when STL is disabled', () => {
    const post = makePost();
    mockStore({
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'none',
          mobile_player_display: false,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerOpenEvent(post);

    expect(mockTriggerEvent).toHaveBeenCalledWith('postOpened', { post }, 'widget-1');
  });

  it('fires stlOpened when modal STL has products', () => {
    const post = makePost([{ id: 'product-1' } as any]);
    mockStore({
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'modal',
          mobile_player_display: false,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerOpenEvent(post);

    expect(mockTriggerEvent).toHaveBeenCalledWith('stlOpened', { post }, 'widget-1');
  });

  it('does not fire an open event when the mobile player is active', () => {
    const post = makePost();
    mockStore({
      isMobile: true,
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'none',
          mobile_player_display: true,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerOpenEvent(post);

    expect(mockTriggerEvent).not.toHaveBeenCalled();
  });

  it('fires stlClosed when closing an STL post', () => {
    const post = makePost([{ id: 'product-1' } as any]);
    mockStore({
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'product_list',
          mobile_player_display: false,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerCloseEvent(post);

    expect(mockTriggerEvent).toHaveBeenCalledWith('stlClosed', { post }, 'widget-1');
  });

  it('fires postClosed only when STL display is none', () => {
    const post = makePost();
    mockStore({
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'none',
          mobile_player_display: false,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerCloseEvent(post);

    expect(mockTriggerEvent).toHaveBeenCalledWith('postClosed', { post }, 'widget-1');
  });

  it('fires the matching navigation event for STL content', () => {
    const post = makePost([{ id: 'product-1' } as any]);
    mockStore({
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'modal',
          mobile_player_display: false,
          display_desktop_player: false,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerNavigationEvent(post, 'right');

    expect(mockTriggerEvent).toHaveBeenCalledWith(
      'stlNavigation',
      { direction: 'right', post },
      'widget-1',
    );
  });

  it('fires STL toggle events based on the opening state', () => {
    const post = makePost();
    mockStore();

    const { result } = renderHook(() => usePostViewerEvents());

    result.current.triggerStlToggleEvent(post, true);
    result.current.triggerStlToggleEvent(post, false);

    expect(mockTriggerEvent).toHaveBeenNthCalledWith(1, 'stlOpened', { post }, 'widget-1');
    expect(mockTriggerEvent).toHaveBeenNthCalledWith(2, 'stlClosed', { post }, 'widget-1');
  });

  it('does not fire a close event when the desktop player is active', () => {
    const post = makePost([{ id: 'product-1' } as any]);
    mockStore({
      isMobile: false,
      data: {
        id: 'widget-1',
        settings: {
          shop_this_look_display: 'product_list',
          mobile_player_display: false,
          display_desktop_player: true,
        },
      },
    });

    const { result } = renderHook(() => usePostViewerEvents());
    result.current.triggerCloseEvent(post);

    expect(mockTriggerEvent).not.toHaveBeenCalled();
  });
});
