import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { FileUpload } from './file-upload';
import React from 'react';

describe('FileUpload', () => {
  it('renders correctly', () => {
    render(<FileUpload />);
    expect(screen.getByText(/click to upload/i)).toBeInTheDocument();
  });

  it('handles file selection via input', () => {
    const onFilesChange = vi.fn();
    const { container } = render(<FileUpload onFilesChange={onFilesChange} />);

    const file = new File(['hello'], 'hello.png', { type: 'image/png' });
    const input = container.querySelector('input[type="file"]') as HTMLInputElement;

    fireEvent.change(input, { target: { files: [file] } });

    expect(onFilesChange).toHaveBeenCalledWith([file]);
    expect(screen.getByText('hello.png')).toBeInTheDocument();
  });

  it('removes a file from the list', () => {
    const { container } = render(<FileUpload />);

    const file = new File(['hello'], 'hello.png', { type: 'image/png' });
    const input = container.querySelector('input[type="file"]') as HTMLInputElement;

    fireEvent.change(input, { target: { files: [file] } });
    expect(screen.getByText('hello.png')).toBeInTheDocument();

    const removeButton = screen.getByRole('button');
    fireEvent.click(removeButton);

    expect(screen.queryByText('hello.png')).not.toBeInTheDocument();
  });

  it('respects maxFiles limit', () => {
    const onFilesChange = vi.fn();
    const { container } = render(<FileUpload maxFiles={1} onFilesChange={onFilesChange} />);

    const file1 = new File(['hello'], 'hello.png', { type: 'image/png' });
    const file2 = new File(['world'], 'world.png', { type: 'image/png' });
    const input = container.querySelector('input[type="file"]') as HTMLInputElement;

    // Upload first file
    fireEvent.change(input, { target: { files: [file1] } });
    // Upload second file (should replace first if maxFiles=1)
    fireEvent.change(input, { target: { files: [file2] } });

    expect(screen.getByText('world.png')).toBeInTheDocument();
    expect(screen.queryByText('hello.png')).not.toBeInTheDocument();
  });

  it('is disabled when disabled prop is true', () => {
    const { container } = render(<FileUpload disabled />);
    const uploadArea = container.querySelector('.cursor-not-allowed');
    expect(uploadArea).toBeInTheDocument();

    const input = container.querySelector('input[type="file"]') as HTMLInputElement;
    expect(input).toBeDisabled();
  });

  it('renders the compact size variant with a horizontal layout', () => {
    const { container } = render(<FileUpload size="compact" />);
    expect(container.querySelector('.flex-row')).toBeInTheDocument();
  });

  it('accepts custom text labels', () => {
    render(
      <FileUpload
        uploadLabel="Clique para enviar"
        dragAndDropLabel="ou arraste e solte"
        singleFileLabel="1 arquivo"
        maxSizeLabel="Máx {size}MB"
      />
    );
    expect(screen.getByText(/clique para enviar/i)).toBeInTheDocument();
    expect(screen.getByText(/ou arraste e solte/i)).toBeInTheDocument();
    expect(screen.getByText(/1 arquivo • Máx 5MB/i)).toBeInTheDocument();
  });

  it('uses a custom size-error label with substituted placeholders', () => {
    const { container } = render(<FileUpload maxSize={10} sizeErrorLabel="Arquivo muito grande: {count} de {size}MB" />);

    const file = new File(['hello world'], 'hello.png', { type: 'image/png' });
    const input = container.querySelector('input[type="file"]') as HTMLInputElement;
    fireEvent.change(input, { target: { files: [file] } });

    expect(screen.getByText('Arquivo muito grande: 1 de 0MB')).toBeInTheDocument();
  });
});
