// src/components/MyDealsPage.test.tsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach, type Mocked } from 'vitest';
import MyDealsPage from './MyDealsPage';
import * as apiClient from '../services/apiClient';
import { WatchedItemDeal } from '../types';

// Mock the apiClient. The component now directly uses `fetchBestSalePrices`.
// By mocking the entire module, we can control the behavior of `fetchBestSalePrices`
// for our tests.
vi.mock('../services/apiClient');
const mockedApiClient = apiClient as Mocked<typeof apiClient>;

// Mock the logger
vi.mock('../services/logger', () => ({
  logger: {
    error: vi.fn(),
  },
}));

// 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();
  });

  it('should display a loading message initially', () => {
    // Mock a pending promise
    mockedApiClient.fetchBestSalePrices.mockReturnValue(new Promise(() => {}));
    render(<MyDealsPage />);
    expect(screen.getByText('Loading your deals...')).toBeInTheDocument();
  });

  it('should display an error message if the API call fails', async () => {
    mockedApiClient.fetchBestSalePrices.mockResolvedValue(new Response(null, { status: 500, statusText: 'Server Error' }));
    render(<MyDealsPage />);

    await waitFor(() => {
      expect(screen.getByText('Error')).toBeInTheDocument();
      expect(screen.getByText('Failed to fetch deals. Please try again later.')).toBeInTheDocument();
    });
  });

  it('should display a message when no deals are found', async () => {
    mockedApiClient.fetchBestSalePrices.mockResolvedValue(new Response(JSON.stringify([]), {
      headers: { 'Content-Type': 'application/json' },
    }));
    render(<MyDealsPage />);

    await waitFor(() => {
      expect(screen.getByText('No deals found for your watched items right now.')).toBeInTheDocument();
    });
  });

  it('should render the list of deals on successful fetch', async () => {
    const mockDeals: WatchedItemDeal[] = [
      {
        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',
      },
      {
        master_item_id: 2,
        item_name: 'Almond Milk',
        best_price_in_cents: 349,
        store_name: 'SuperMart',
        flyer_id: 102,
        valid_to: '2024-10-22',
      },
    ];
    mockedApiClient.fetchBestSalePrices.mockResolvedValue(new Response(JSON.stringify(mockDeals), {
      headers: { 'Content-Type': 'application/json' },
    }));

    render(<MyDealsPage />);

    await waitFor(() => {
      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();
    });
  });
});