/**
 * ItemCard Component Tests
 *
 * Tests for the ItemCard component focusing on image display,
 * fallback handling, and URL construction.
 */

import React from 'react';
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import ItemCard from '../../components/ItemCard';
import { Item } from '../../types';
import { getPublicImageUrl } from '../../services/uploadService';

// Mock the uploadService
jest.mock('../../services/uploadService', () => ({
  getPublicImageUrl: jest.fn(),
}));

const mockedGetPublicImageUrl = getPublicImageUrl as jest.MockedFunction<typeof getPublicImageUrl>;

// Helper to render with Router
const renderWithRouter = (component: React.ReactElement) => {
  return render(<BrowserRouter>{component}</BrowserRouter>);
};

// Set up mock implementation before each test
beforeEach(() => {
  mockedGetPublicImageUrl.mockImplementation((imagePath: string | null | undefined) => {
    if (!imagePath) return '';
    if (imagePath.startsWith('https://')) return imagePath;
    return `https://test-bucket.s3.us-east-1.amazonaws.com/${imagePath}`;
  });
});

afterEach(() => {
  jest.clearAllMocks();
});

// Mock item data
const createMockItem = (overrides: Partial<Item> = {}): Item => ({
  id: '1',
  name: 'Test Item',
  description: 'A test item description',
  pricePerDay: 25.99,
  pricePerHour: null,
  pricePerWeek: null,
  pricePerMonth: null,
  city: 'New York',
  state: 'NY',
  zipCode: '10001',
  imageFilenames: [],
  isAvailable: true,
  ownerId: 'owner-123',
  owner: {
    id: 'owner-123',
    firstName: 'John',
    lastName: 'Doe',
  },
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString(),
  ...overrides,
});

describe('ItemCard', () => {
  describe('Image Display', () => {
    it('should display image when imageFilenames is present', () => {
      const item = createMockItem({
        imageFilenames: ['items/550e8400-e29b-41d4-a716-446655440000.jpg'],
      });

      renderWithRouter(<ItemCard item={item} />);

      const img = screen.getByRole('img', { name: 'Test Item' });
      expect(img).toBeInTheDocument();
      // The src is constructed by getPublicImageUrl which is mocked
      expect(img.getAttribute('src')).toContain('items/550e8400-e29b-41d4-a716-446655440000.jpg');
    });

    it('should display first image when multiple imageFilenames are present', () => {
      const item = createMockItem({
        imageFilenames: [
          'items/first-uuid.jpg',
          'items/second-uuid.jpg',
          'items/third-uuid.jpg',
        ],
      });

      renderWithRouter(<ItemCard item={item} />);

      const img = screen.getByRole('img', { name: 'Test Item' });
      // The mock returns the S3 URL for the first image
      expect(img.getAttribute('src')).toContain('items/first-uuid.jpg');
    });

    it('should display placeholder when imageFilenames is empty array', () => {
      const item = createMockItem({
        imageFilenames: [],
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.queryByRole('img')).not.toBeInTheDocument();
      // Check for placeholder icon
      const placeholder = document.querySelector('.bi-image');
      expect(placeholder).toBeInTheDocument();
    });

    it('should display placeholder when imageFilenames is undefined', () => {
      const item = createMockItem({
        imageFilenames: undefined,
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.queryByRole('img')).not.toBeInTheDocument();
      const placeholder = document.querySelector('.bi-image');
      expect(placeholder).toBeInTheDocument();
    });

    it('should display placeholder when imageFilenames is null', () => {
      const item = createMockItem({
        imageFilenames: null as any,
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.queryByRole('img')).not.toBeInTheDocument();
    });

    it('should set correct alt text for image', () => {
      const item = createMockItem({
        name: 'Custom Item Name',
        imageFilenames: ['items/uuid.jpg'],
      });

      renderWithRouter(<ItemCard item={item} />);

      const img = screen.getByRole('img');
      expect(img).toHaveAttribute('alt', 'Custom Item Name');
    });
  });

  describe('Image Styling', () => {
    it('should apply standard height for default variant', () => {
      const item = createMockItem({
        imageFilenames: ['items/uuid.jpg'],
      });

      renderWithRouter(<ItemCard item={item} />);

      const img = screen.getByRole('img');
      expect(img).toHaveStyle({ height: '200px' });
    });

    it('should apply compact height for compact variant', () => {
      const item = createMockItem({
        imageFilenames: ['items/uuid.jpg'],
      });

      renderWithRouter(<ItemCard item={item} variant="compact" />);

      const img = screen.getByRole('img');
      expect(img).toHaveStyle({ height: '150px' });
    });

    it('should apply object-fit contain for proper image display', () => {
      const item = createMockItem({
        imageFilenames: ['items/uuid.jpg'],
      });

      renderWithRouter(<ItemCard item={item} />);

      const img = screen.getByRole('img');
      expect(img).toHaveStyle({ objectFit: 'contain' });
    });
  });

  describe('Item Information', () => {
    it('should display item name', () => {
      const item = createMockItem({
        name: 'Camping Tent',
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.getByText('Camping Tent')).toBeInTheDocument();
    });

    it('should display price per day', () => {
      const item = createMockItem({
        pricePerDay: 25.99,
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.getByText('$25/day')).toBeInTheDocument();
    });

    it('should display location', () => {
      const item = createMockItem({
        city: 'San Francisco',
        state: 'CA',
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.getByText('San Francisco, CA')).toBeInTheDocument();
    });

    it('should link to item detail page', () => {
      const item = createMockItem({
        id: 'item-123',
      });

      renderWithRouter(<ItemCard item={item} />);

      const link = screen.getByRole('link');
      expect(link).toHaveAttribute('href', '/items/item-123');
    });
  });

  describe('Multiple Pricing Tiers', () => {
    it('should display multiple pricing tiers', () => {
      const item = createMockItem({
        pricePerHour: 5,
        pricePerDay: 25,
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.getByText(/\$5\/hr/)).toBeInTheDocument();
      expect(screen.getByText(/\$25\/day/)).toBeInTheDocument();
    });

    it('should display "Free to Borrow" when no prices set', () => {
      const item = createMockItem({
        pricePerHour: null,
        pricePerDay: null,
        pricePerWeek: null,
        pricePerMonth: null,
      });

      renderWithRouter(<ItemCard item={item} />);

      expect(screen.getByText('Free to Borrow')).toBeInTheDocument();
    });
  });
});
