// src/features/charts/PriceChart.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
import { PriceChart } from './PriceChart';
import type { DealItem, User } from '../../types';
import { useActiveDeals } from '../../hooks/useActiveDeals';

// Mock the hook that the component now depends on
vi.mock('../../hooks/useActiveDeals');
const mockedUseActiveDeals = useActiveDeals as Mock;

const mockUser: User = { user_id: 'user-123', email: 'test@example.com' };

const mockDeals: DealItem[] = [
  {
    item: 'Organic Bananas',
    master_item_name: 'Bananas',
    price_display: '$1.99',
    price_in_cents: 199,
    quantity: 'per lb',
    storeName: 'Metro',
    unit_price: { value: 199, unit: 'lb' },
  },
  {
    item: 'Milk 2%',
    master_item_name: null, // No different master name
    price_display: '$4.50',
    price_in_cents: 450,
    quantity: '4L',
    storeName: 'Walmart',
    unit_price: { value: 112.5, unit: 'L' },
  },
];

const defaultProps = {
  unitSystem: 'imperial' as const,
  user: mockUser,
};

describe('PriceChart', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Provide a default successful mock implementation for each test
    mockedUseActiveDeals.mockReturnValue({
      activeDeals: mockDeals,
      isLoading: false,
      error: null,
      totalActiveItems: mockDeals.length,
    });
  });

  it('should render a login prompt when user is not authenticated', () => {
    render(<PriceChart unitSystem="imperial" user={null} />);
    expect(screen.getByRole('heading', { name: /personalized deals/i })).toBeInTheDocument();
    expect(screen.getByText(/log in to see active deals/i)).toBeInTheDocument();
  });

  it('should render a loading spinner when isLoading is true', () => {
    mockedUseActiveDeals.mockReturnValue({
      ...mockedUseActiveDeals(),
      isLoading: true,
    });
    render(<PriceChart {...defaultProps} />);
    expect(screen.getByText(/finding active deals/i)).toBeInTheDocument();
    // The LoadingSpinner component has a role of 'status'
    expect(screen.getByRole('status')).toBeInTheDocument();
  });

  it('should render a message when there are no deals', () => {
    mockedUseActiveDeals.mockReturnValue({
      ...mockedUseActiveDeals(),
      activeDeals: [],
    });
    render(<PriceChart {...defaultProps} />);
    expect(screen.getByText(/no deals for your watched items/i)).toBeInTheDocument();
  });

  it('should render the table with deal items when data is provided', () => {
    render(<PriceChart {...defaultProps} />);

    // Check for table headers
    expect(screen.getByRole('columnheader', { name: 'Item' })).toBeInTheDocument();
    expect(screen.getByRole('columnheader', { name: 'Store' })).toBeInTheDocument();
    expect(screen.getByRole('columnheader', { name: 'Price' })).toBeInTheDocument();
    expect(screen.getByRole('columnheader', { name: 'Unit Price' })).toBeInTheDocument();

    // Check for content of the first deal
    expect(screen.getByText('Organic Bananas')).toBeInTheDocument();
    expect(screen.getByText('(Bananas)')).toBeInTheDocument(); // Master item name
    expect(screen.getByText('Metro')).toBeInTheDocument();
    expect(screen.getByText('$1.99')).toBeInTheDocument(); // This is the price_display
    expect(screen.getByText('$1.99/lb')).toBeInTheDocument(); // Formatted unit price

    // Check for content of the second deal
    expect(screen.getByText('Milk 2%')).toBeInTheDocument();
    expect(screen.queryByText('(Milk)')).not.toBeInTheDocument(); // No master item name to show
    expect(screen.getByText('Walmart')).toBeInTheDocument();
    expect(screen.getByText('$4.50')).toBeInTheDocument();
    expect(screen.getByText('4L')).toBeInTheDocument();
    expect(screen.getByText('$1.13/L')).toBeInTheDocument(); // Formatted unit price
  });

  it('should format unit price correctly for metric system', () => {
    // Override default props for this specific test
    render(<PriceChart {...defaultProps} unitSystem="metric" />);

    // Bananas: 1.99/lb -> 1.99 / 0.453592 kg -> $4.39/kg
    expect(screen.getByText('$4.39/kg')).toBeInTheDocument();

    // Milk: $1.13/L (already metric)
    expect(screen.getByText('$1.13/L')).toBeInTheDocument();
  });
});