// src/hooks/useFlyerItems.test.ts
import { renderHook } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { useFlyerItems } from './useFlyerItems';
import { useApiOnMount } from './useApiOnMount';
import type { Flyer, FlyerItem } from '../types';

// Mock the underlying useApiOnMount hook to isolate the useFlyerItems hook's logic.
vi.mock('./useApiOnMount');

const mockedUseApiOnMount = vi.mocked(useApiOnMount);

describe('useFlyerItems Hook', () => {
  const mockFlyer: Flyer = {
    flyer_id: 123,
    file_name: 'test-flyer.jpg',
    image_url: '/test.jpg',
    icon_url: '/icon.jpg',
    checksum: 'abc',
    valid_from: '2024-01-01',
    valid_to: '2024-01-07',
    store: {
      store_id: 1,
      name: 'Test Store',
      created_at: new Date().toISOString(),
    },
    item_count: 1,
    created_at: new Date().toISOString(),
  };

  const mockFlyerItems: FlyerItem[] = [
    { flyer_item_id: 1, flyer_id: 123, item: 'Apples', price_display: '$1.99', price_in_cents: 199, quantity: '1lb', created_at: new Date().toISOString(), view_count: 0, click_count: 0, updated_at: new Date().toISOString() },
  ];

  beforeEach(() => {
    // Clear mock history before each test
    vi.clearAllMocks();
  });

  it('should return initial state and not call useApiOnMount when flyer is null', () => {
    // Arrange: Mock the return value of the inner hook.
    mockedUseApiOnMount.mockReturnValue({
      data: null,
      loading: false,
      error: null,
      isRefetching: false,
    });

    // Act: Render the hook with a null flyer.
    const { result } = renderHook(() => useFlyerItems(null));

    // Assert: Check that the hook returns the correct initial state.
    expect(result.current.flyerItems).toEqual([]);
    expect(result.current.isLoading).toBe(false);
    expect(result.current.error).toBeNull();

    // Assert: Check that useApiOnMount was called with `enabled: false`.
    expect(mockedUseApiOnMount).toHaveBeenCalledWith(
      expect.any(Function), // the wrapped fetcher function
      [null], // dependencies array
      { enabled: false }, // options object
      undefined // flyer_id
    );
  });

  it('should call useApiOnMount with enabled: true when a flyer is provided', () => {
    mockedUseApiOnMount.mockReturnValue({ data: null, loading: true, error: null, isRefetching: false });

    renderHook(() => useFlyerItems(mockFlyer));

    // Assert: Check that useApiOnMount was called with the correct parameters.
    expect(mockedUseApiOnMount).toHaveBeenCalledWith(
      expect.any(Function),
      [mockFlyer],
      { enabled: true },
      mockFlyer.flyer_id
    );
  });

  it('should return isLoading: true when the inner hook is loading', () => {
    mockedUseApiOnMount.mockReturnValue({ data: null, loading: true, error: null, isRefetching: false });

    const { result } = renderHook(() => useFlyerItems(mockFlyer));

    expect(result.current.isLoading).toBe(true);
  });

  it('should return flyerItems when the inner hook provides data', () => {
    mockedUseApiOnMount.mockReturnValue({
      data: { items: mockFlyerItems },
      loading: false,
      error: null,
      isRefetching: false,
    });

    const { result } = renderHook(() => useFlyerItems(mockFlyer));

    expect(result.current.isLoading).toBe(false);
    expect(result.current.flyerItems).toEqual(mockFlyerItems);
    expect(result.current.error).toBeNull();
  });

  it('should return an error when the inner hook returns an error', () => {
    const mockError = new Error('Failed to fetch');
    mockedUseApiOnMount.mockReturnValue({ data: null, loading: false, error: mockError, isRefetching: false });

    const { result } = renderHook(() => useFlyerItems(mockFlyer));

    expect(result.current.isLoading).toBe(false);
    expect(result.current.flyerItems).toEqual([]);
    expect(result.current.error).toEqual(mockError);
  });
});