import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import type { PropertyMedia } from '@/lib/listings-api';
import { ImageGallery } from '../image-gallery';

// Mock next/image
vi.mock('next/image', () => ({
  default: (props: Record<string, unknown>) => <img {...props} />,
}));

// Mock scrollIntoView (not available in jsdom)
Element.prototype.scrollIntoView = vi.fn();

// Mock ImageLightbox
vi.mock('@/components/listings/image-lightbox', () => ({
  ImageLightbox: ({ open }: { open: boolean }) =>
    open ? <div data-testid="lightbox">Lightbox</div> : null,
}));

// Mock image-blur
vi.mock('@/lib/image-blur', () => ({
  shimmerBlurDataURL: () => 'data:image/svg+xml;base64,mock',
}));

function makeMedia(count: number): PropertyMedia[] {
  return Array.from({ length: count }, (_, i) => ({
    id: `media-${i}`,
    type: 'image' as const,
    url: `https://example.com/img${i}.jpg`,
    order: i,
    caption: i === 0 ? 'Main photo' : null,
  }));
}

describe('ImageGallery', () => {
  it('shows "Chưa có hình ảnh" when no media', () => {
    render(<ImageGallery media={[]} />);
    expect(screen.getByText('Chưa có hình ảnh')).toBeInTheDocument();
  });

  it('renders main image when media exists', () => {
    render(<ImageGallery media={makeMedia(1)} />);
    const img = screen.getByRole('img');
    expect(img).toBeInTheDocument();
  });

  it('does not render thumbnails for single image', () => {
    render(<ImageGallery media={makeMedia(1)} />);
    // Single image - no thumbnail strip
    const imgs = screen.getAllByRole('img');
    expect(imgs).toHaveLength(1); // Only the main image
  });

  it('renders thumbnails for multiple images', () => {
    render(<ImageGallery media={makeMedia(3)} />);
    // 1 main + 3 thumbnails = 4 images
    const imgs = screen.getAllByRole('img');
    expect(imgs.length).toBeGreaterThanOrEqual(4);
  });

  it('renders navigation arrows for multiple images', () => {
    render(<ImageGallery media={makeMedia(3)} />);
    expect(screen.getByLabelText('Ảnh trước')).toBeInTheDocument();
    expect(screen.getByLabelText('Ảnh tiếp')).toBeInTheDocument();
  });

  it('does not render navigation arrows for single image', () => {
    render(<ImageGallery media={makeMedia(1)} />);
    expect(screen.queryByLabelText('Ảnh trước')).not.toBeInTheDocument();
    expect(screen.queryByLabelText('Ảnh tiếp')).not.toBeInTheDocument();
  });

  it('shows image counter', () => {
    render(<ImageGallery media={makeMedia(5)} />);
    expect(screen.getByText('1 / 5')).toBeInTheDocument();
  });

  it('navigates to next image when arrow is clicked', async () => {
    const user = userEvent.setup();
    render(<ImageGallery media={makeMedia(3)} />);

    await user.click(screen.getByLabelText('Ảnh tiếp'));
    expect(screen.getByText('2 / 3')).toBeInTheDocument();
  });

  it('navigates to previous image', async () => {
    const user = userEvent.setup();
    render(<ImageGallery media={makeMedia(3)} />);

    // Go forward then back
    await user.click(screen.getByLabelText('Ảnh tiếp'));
    await user.click(screen.getByLabelText('Ảnh trước'));
    expect(screen.getByText('1 / 3')).toBeInTheDocument();
  });

  it('wraps around to last image when pressing prev on first', async () => {
    const user = userEvent.setup();
    render(<ImageGallery media={makeMedia(3)} />);

    await user.click(screen.getByLabelText('Ảnh trước'));
    expect(screen.getByText('3 / 3')).toBeInTheDocument();
  });

  it('shows fullscreen button', () => {
    render(<ImageGallery media={makeMedia(2)} />);
    expect(screen.getByLabelText('Xem ảnh toàn màn hình')).toBeInTheDocument();
  });

  it('opens lightbox on fullscreen button click', async () => {
    const user = userEvent.setup();
    render(<ImageGallery media={makeMedia(2)} />);

    await user.click(screen.getByLabelText('Xem ảnh toàn màn hình'));
    expect(screen.getByTestId('lightbox')).toBeInTheDocument();
  });

  it('filters out non-image media', () => {
    const media: PropertyMedia[] = [
      { id: 'img-1', type: 'image', url: 'https://example.com/img.jpg', order: 0, caption: null },
      { id: 'vid-1', type: 'video' as PropertyMedia['type'], url: 'https://example.com/vid.mp4', order: 1, caption: null },
    ];
    render(<ImageGallery media={media} />);
    // Should only render 1 image (main), no nav arrows for single image
    expect(screen.queryByLabelText('Ảnh trước')).not.toBeInTheDocument();
  });
});
