// src/pages/MyDealsPage.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
import MyDealsPage from './MyDealsPage';
import { useBestSalePricesQuery } from '../hooks/queries/useBestSalePricesQuery';
import type { WatchedItemDeal } from '../types';
import { createMockWatchedItemDeal } from '../tests/utils/mockFactories';
import { QueryWrapper } from '../tests/utils/renderWithProviders';

vi.mock('../hooks/queries/useBestSalePricesQuery');
const mockedUseBestSalePricesQuery = useBestSalePricesQuery as Mock;

const renderWithQuery = (ui: React.ReactElement) => render(ui, { wrapper: QueryWrapper });

// Mock lucide-react icons to prevent rendering errors in the test environment
vi.mock('lucide-react', () => ({
  AlertCircle: () => <div data-testid="alert-circle-icon" />,
  Tag: () => <div data-testid="tag-icon" />,
  Store: () => <div data-testid="store-icon" />,
  Calendar: () => <div data-testid="calendar-icon" />,
}));

describe('MyDealsPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Default mock: loading false, empty data
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: [],
      isLoading: false,
      error: null,
    });
  });

  it('should display a loading message initially', () => {
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: [],
      isLoading: true,
      error: null,
    });
    renderWithQuery(<MyDealsPage />);
    expect(screen.getByText('Loading your deals...')).toBeInTheDocument();
  });

  it('should display an error message if the API call fails', () => {
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: [],
      isLoading: false,
      error: new Error('Request failed with status 500'),
    });
    renderWithQuery(<MyDealsPage />);
    expect(screen.getByText('Error')).toBeInTheDocument();
    expect(screen.getByText('Request failed with status 500')).toBeInTheDocument();
  });

  it('should handle network errors and log them', () => {
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: [],
      isLoading: false,
      error: new Error('Network connection failed'),
    });
    renderWithQuery(<MyDealsPage />);
    expect(screen.getByText('Error')).toBeInTheDocument();
    expect(screen.getByText('Network connection failed')).toBeInTheDocument();
  });

  it('should handle unknown errors and log them', () => {
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: [],
      isLoading: false,
      error: new Error('Unknown failure'),
    });
    renderWithQuery(<MyDealsPage />);
    expect(screen.getByText('Error')).toBeInTheDocument();
    expect(screen.getByText('Unknown failure')).toBeInTheDocument();
  });

  it('should display a message when no deals are found', () => {
    renderWithQuery(<MyDealsPage />);
    expect(
      screen.getByText('No deals found for your watched items right now.'),
    ).toBeInTheDocument();
  });

  it('should render the list of deals on successful fetch', () => {
    const mockDeals: WatchedItemDeal[] = [
      createMockWatchedItemDeal({
        master_item_id: 1,
        item_name: 'Organic Bananas',
        best_price_in_cents: 99,
        store_name: 'Green Grocer',
        flyer_id: 101,
        valid_to: '2024-10-20',
      }),
      createMockWatchedItemDeal({
        master_item_id: 2,
        item_name: 'Almond Milk',
        best_price_in_cents: 349,
        store_name: 'SuperMart',
        flyer_id: 102,
        valid_to: '2024-10-22',
      }),
    ];
    mockedUseBestSalePricesQuery.mockReturnValue({
      data: mockDeals,
      isLoading: false,
      error: null,
    });

    renderWithQuery(<MyDealsPage />);

    expect(screen.getByText('Organic Bananas')).toBeInTheDocument();
    expect(screen.getByText('$0.99')).toBeInTheDocument();
    expect(screen.getByText('Almond Milk')).toBeInTheDocument();
    expect(screen.getByText('$3.49')).toBeInTheDocument();
    expect(screen.getByText('Green Grocer')).toBeInTheDocument();
  });
});
