// src/features/flyer/FlyerDisplay.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { FlyerDisplay } from './FlyerDisplay';
import { createMockStore } from '../../tests/utils/mockFactories';

const mockStore = createMockStore({
  store_id: 1,
  name: 'SuperMart',
  logo_url: 'https://example.com/logo.png',
});

const mockOnOpenCorrectionTool = vi.fn();

const defaultProps = {
  imageUrl: 'https://example.com/flyer.jpg',
  store: mockStore,
  validFrom: '2023-10-26',
  validTo: '2023-11-01',
  storeAddress: '123 Main St, Anytown',
  onOpenCorrectionTool: mockOnOpenCorrectionTool,
};

describe('FlyerDisplay', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should render all elements when all props are provided', () => {
    render(<FlyerDisplay {...defaultProps} />);

    // Check for store info
    expect(screen.getByRole('heading', { name: 'SuperMart' })).toBeInTheDocument();
    expect(screen.getByAltText('SuperMart Logo')).toHaveAttribute('src', mockStore.logo_url);
    expect(screen.getByText('123 Main St, Anytown')).toBeInTheDocument();

    // Check for date range
    expect(
      screen.getByText('Deals valid from October 26, 2023 to November 1, 2023'),
    ).toBeInTheDocument();

    // Check for flyer image
    expect(screen.getByAltText('Grocery Flyer')).toHaveAttribute('src', defaultProps.imageUrl);
  });

  it('should render a placeholder when imageUrl is null', () => {
    render(<FlyerDisplay {...defaultProps} imageUrl={null} />);
    expect(screen.getByText('Flyer image will be displayed here')).toBeInTheDocument();
  });

  it('should not render the header if store and date info are missing', () => {
    render(
      <FlyerDisplay
        imageUrl={defaultProps.imageUrl}
        onOpenCorrectionTool={mockOnOpenCorrectionTool}
      />,
    );
    expect(screen.queryByRole('heading')).not.toBeInTheDocument();
  });

  it('should render without a logo if store.logo_url is not provided', () => {
    render(<FlyerDisplay {...defaultProps} store={{ ...mockStore, logo_url: null }} />);
    expect(screen.getByRole('heading', { name: 'SuperMart' })).toBeInTheDocument();
    expect(screen.queryByAltText('SuperMart Logo')).not.toBeInTheDocument();
  });

  it('should use fallback alt text when store has logo_url but no name', () => {
    const storeWithoutName = { ...mockStore, name: undefined };
    render(<FlyerDisplay {...defaultProps} store={storeWithoutName as any} />);
    expect(screen.getByAltText('Store Logo')).toBeInTheDocument();
  });

  it('should format a single day validity correctly', () => {
    render(<FlyerDisplay {...defaultProps} validFrom="2023-10-26" validTo="2023-10-26" />);
    expect(screen.getByText('Valid on October 26, 2023')).toBeInTheDocument();
  });

  it('should format correctly with only a start date', () => {
    render(<FlyerDisplay {...defaultProps} validTo={null} />);
    expect(screen.getByText('Deals start October 26, 2023')).toBeInTheDocument();
  });

  it('should format correctly with only an end date', () => {
    render(<FlyerDisplay {...defaultProps} validFrom={null} />);
    expect(screen.getByText('Deals end November 1, 2023')).toBeInTheDocument();
  });

  it('should apply dark mode image styles', () => {
    render(<FlyerDisplay {...defaultProps} />);
    const image = screen.getByAltText('Grocery Flyer');
    expect(image).toHaveClass('dark:invert');
    expect(image).toHaveClass('dark:hue-rotate-180');
  });

  describe('"Correct Data" Button', () => {
    it('should be visible when the header is rendered', () => {
      render(<FlyerDisplay {...defaultProps} />);
      expect(screen.getByRole('button', { name: /correct data/i })).toBeInTheDocument();
    });

    it('should not be visible when the header is not rendered', () => {
      render(
        <FlyerDisplay
          imageUrl={defaultProps.imageUrl}
          onOpenCorrectionTool={mockOnOpenCorrectionTool}
        />,
      );
      expect(screen.queryByRole('button', { name: /correct data/i })).not.toBeInTheDocument();
    });

    it('should call onOpenCorrectionTool when clicked', () => {
      render(<FlyerDisplay {...defaultProps} />);
      fireEvent.click(screen.getByRole('button', { name: /correct data/i }));
      expect(mockOnOpenCorrectionTool).toHaveBeenCalledTimes(1);
    });
  });

  describe('Image Source Logic', () => {
    it('should use the imageUrl directly if it is a full URL', () => {
      render(<FlyerDisplay {...defaultProps} imageUrl="https://cdn.example.com/flyer.png" />);
      const image = screen.getByAltText('Grocery Flyer');
      expect(image).toHaveAttribute('src', 'https://cdn.example.com/flyer.png');
    });

    it('should use the imageUrl directly if it is an absolute path', () => {
      render(<FlyerDisplay {...defaultProps} imageUrl="/assets/flyers/flyer.png" />);
      const image = screen.getByAltText('Grocery Flyer');
      expect(image).toHaveAttribute('src', '/assets/flyers/flyer.png');
    });

    it('should prepend the path for a relative imageUrl from the database', () => {
      render(<FlyerDisplay {...defaultProps} imageUrl="flyer-from-db.jpg" />);
      const image = screen.getByAltText('Grocery Flyer');
      expect(image).toHaveAttribute('src', '/flyer-images/flyer-from-db.jpg');
    });
  });

  describe('Date Formatting Robustness', () => {
    it('should handle invalid date strings gracefully by not displaying them', () => {
      render(
        <FlyerDisplay {...defaultProps} validFrom="invalid-date" validTo="another-bad-date" />,
      );
      expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/valid on/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/deals start/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/deals end/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument(); // Ensure no "Invalid Date" text
    });

    it('should handle a mix of valid and invalid date strings gracefully (start date valid)', () => {
      render(<FlyerDisplay {...defaultProps} validFrom="2023-10-26" validTo="invalid-date" />);
      expect(screen.getByText('Deals start October 26, 2023')).toBeInTheDocument();
      expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/deals end/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument();
    });

    it('should handle a mix of valid and invalid date strings gracefully (end date valid)', () => {
      render(<FlyerDisplay {...defaultProps} validFrom="another-bad-date" validTo="2023-11-01" />);
      expect(screen.getByText('Deals end November 1, 2023')).toBeInTheDocument();
      expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/deals start/i)).not.toBeInTheDocument();
      expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument();
    });
  });
});
