import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { Checkbox } from './checkbox';

describe('Checkbox Component', () => {
  it('renders checkbox', () => {
    render(<Checkbox />);

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toBeInTheDocument();
    expect(checkbox).not.toBeChecked();
  });

  it('renders with label', () => {
    render(<Checkbox label="Accept terms" />);

    const label = screen.getByText('Accept terms');
    expect(label).toBeInTheDocument();

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toBeInTheDocument();
  });

  it('handles onCheckedChange callback', () => {
    const handleCheckedChange = vi.fn();
    render(<Checkbox onCheckedChange={handleCheckedChange} />);

    const checkbox = screen.getByRole('checkbox');
    fireEvent.click(checkbox);

    expect(handleCheckedChange).toHaveBeenCalledWith(true);
    expect(checkbox).toBeChecked();
  });

  it('handles onChange event', () => {
    const handleChange = vi.fn();
    render(<Checkbox onChange={handleChange} />);

    const checkbox = screen.getByRole('checkbox');
    fireEvent.click(checkbox);

    expect(handleChange).toHaveBeenCalledTimes(1);
  });

  it('handles checked state', () => {
    render(<Checkbox checked />);

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toBeChecked();
  });

  it('handles disabled state', () => {
    render(<Checkbox disabled label="Disabled checkbox" />);

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toBeDisabled();

    // The opacity-50 is on the wrapping label element, not the text span
    const label = screen.getByText('Disabled checkbox').closest('label');
    expect(label).toHaveClass('opacity-50');
  });

  it('toggles checked state on click', () => {
    render(<Checkbox label="Toggle me" />);

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).not.toBeChecked();

    fireEvent.click(checkbox);
    expect(checkbox).toBeChecked();

    fireEvent.click(checkbox);
    expect(checkbox).not.toBeChecked();
  });

  it('applies custom className', () => {
    render(<Checkbox className="custom-checkbox" />);

    const label = screen.getByRole('checkbox').closest('label');
    expect(label).toHaveClass('custom-checkbox');
  });

  // === Bug #11 Regression: no hardcoded "Checkbox" aria-label ===

  it('[Bug #11] should not have hardcoded "Checkbox" aria-label when no label provided', () => {
    render(<Checkbox id="test-cb" />);

    const checkbox = screen.getByRole('checkbox');
    const ariaLabel = checkbox.getAttribute('aria-label');
    // Should NOT be the hardcoded string "Checkbox"
    expect(ariaLabel).not.toBe('Checkbox');
  });

  it('[Bug #11] should use explicit aria-label when provided', () => {
    render(<Checkbox aria-label="Enable notifications" />);

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toHaveAttribute('aria-label', 'Enable notifications');
  });

  it('[Bug #11] should get accessible name from associated label via htmlFor', () => {
    render(
      <>
        <label htmlFor="my-cb">Email notifications</label>
        <Checkbox id="my-cb" />
      </>,
    );

    const checkbox = screen.getByRole('checkbox', { name: /email notifications/i });
    expect(checkbox).toBeInTheDocument();
  });
});
