import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import { ImageUpload, type ImageFile } from '../image-upload';

function createMockImageFile(name = 'test.jpg'): ImageFile {
  const file = new File(['content'], name, { type: 'image/jpeg' });
  return { file, preview: `blob:${name}` };
}

describe('ImageUpload', () => {
  it('renders drop zone with instructions', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} />);
    expect(screen.getByText('Kéo thả ảnh vào đây hoặc nhấp để chọn')).toBeInTheDocument();
  });

  it('renders max files hint', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} maxFiles={10} />);
    expect(screen.getByText(/Tối đa 10 ảnh/)).toBeInTheDocument();
  });

  it('renders default max files hint (20)', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} />);
    expect(screen.getByText(/Tối đa 20 ảnh/)).toBeInTheDocument();
  });

  it('renders image previews when images are provided', () => {
    const images = [createMockImageFile('img1.jpg'), createMockImageFile('img2.jpg')];
    render(<ImageUpload images={images} onChange={vi.fn()} />);
    const imgElements = screen.getAllByRole('img');
    expect(imgElements).toHaveLength(2);
  });

  it('shows "Ảnh bìa" badge on first image', () => {
    const images = [createMockImageFile()];
    render(<ImageUpload images={images} onChange={vi.fn()} />);
    expect(screen.getByText('Ảnh bìa')).toBeInTheDocument();
  });

  it('shows delete button on hover (rendered)', () => {
    const images = [createMockImageFile()];
    render(<ImageUpload images={images} onChange={vi.fn()} />);
    expect(screen.getByText('Xóa')).toBeInTheDocument();
  });

  it('calls onChange when delete button is clicked', async () => {
    const user = userEvent.setup();
    const onChange = vi.fn();
    const images = [createMockImageFile('img1.jpg'), createMockImageFile('img2.jpg')];
    render(<ImageUpload images={images} onChange={onChange} />);

    const deleteButtons = screen.getAllByText('Xóa');
    await user.click(deleteButtons[0]!);
    expect(onChange).toHaveBeenCalled();
  });

  it('has accessible drop zone with aria-label', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} />);
    expect(screen.getByLabelText(/Tải ảnh lên/)).toBeInTheDocument();
  });

  it('renders hidden file input', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} />);
    const fileInput = document.querySelector('input[type="file"]');
    expect(fileInput).toBeInTheDocument();
    expect(fileInput).toHaveClass('hidden');
  });

  it('accepts correct file types', () => {
    render(<ImageUpload images={[]} onChange={vi.fn()} />);
    const fileInput = document.querySelector('input[type="file"]');
    expect(fileInput).toHaveAttribute('accept', 'image/jpeg,image/png,image/webp');
  });
});
