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

describe('FormTextarea', () => {
  it('renders textarea element', () => {
    render(<FormTextarea />);
    expect(screen.getByRole('textbox')).toBeInTheDocument();
  });

  it('renders label when provided', () => {
    render(<FormTextarea label="Description" />);
    expect(screen.getByText('Description')).toBeInTheDocument();
  });

  it('shows required indicator when required', () => {
    render(<FormTextarea label="Comments" required />);
    expect(screen.getByText('*')).toBeInTheDocument();
  });

  it('displays error message', () => {
    render(<FormTextarea error="This field is required" />);
    expect(screen.getByText('This field is required')).toBeInTheDocument();
  });

  it('displays hint when provided', () => {
    render(<FormTextarea hint="Max 500 characters" />);
    expect(screen.getByText('Max 500 characters')).toBeInTheDocument();
  });

  it('hides hint when error is shown', () => {
    render(<FormTextarea hint="Enter description" error="Required" />);
    expect(screen.queryByText('Enter description')).not.toBeInTheDocument();
    expect(screen.getByText('Required')).toBeInTheDocument();
  });

  it('applies error styling when error present', () => {
    render(<FormTextarea error="Invalid" />);
    expect(screen.getByRole('textbox')).toHaveClass('border-red-500');
  });

  it('applies disabled styling', () => {
    render(<FormTextarea disabled />);
    expect(screen.getByRole('textbox')).toBeDisabled();
    expect(screen.getByRole('textbox')).toHaveClass('cursor-not-allowed');
  });

  it('applies full width by default', () => {
    render(<FormTextarea />);
    expect(screen.getByRole('textbox')).toHaveClass('w-full');
  });

  it('can disable full width', () => {
    render(<FormTextarea fullWidth={false} />);
    expect(screen.getByRole('textbox')).not.toHaveClass('w-full');
  });

  it('applies custom className', () => {
    render(<FormTextarea className="custom-class" />);
    expect(screen.getByRole('textbox')).toHaveClass('custom-class');
  });

  it('applies custom containerClassName', () => {
    const { container } = render(<FormTextarea containerClassName="container-class" />);
    expect(container.firstChild).toHaveClass('container-class');
  });

  it('handles value changes', () => {
    const handleChange = vi.fn();
    render(<FormTextarea onChange={handleChange} />);
    fireEvent.change(screen.getByRole('textbox'), { target: { value: 'test content' } });
    expect(handleChange).toHaveBeenCalled();
  });

  it('uses provided id', () => {
    render(<FormTextarea id="custom-id" label="Label" />);
    expect(screen.getByRole('textbox')).toHaveAttribute('id', 'custom-id');
  });

  it('uses name as id fallback', () => {
    render(<FormTextarea name="description" label="Label" />);
    expect(screen.getByRole('textbox')).toHaveAttribute('id', 'description');
  });

  it('links label to textarea', () => {
    render(<FormTextarea id="my-textarea" label="My Label" />);
    const textarea = screen.getByRole('textbox');
    const label = screen.getByText('My Label');
    expect(label).toHaveAttribute('for', 'my-textarea');
    expect(textarea).toHaveAttribute('id', 'my-textarea');
  });

  it('forwards ref to textarea element', () => {
    const ref = { current: null as HTMLTextAreaElement | null };
    render(<FormTextarea ref={ref} />);
    expect(ref.current).toBeInstanceOf(HTMLTextAreaElement);
  });

  it('shows character count when enabled', () => {
    render(<FormTextarea showCharCount value="Hello" />);
    expect(screen.getByText('5')).toBeInTheDocument();
  });

  it('shows character count with max chars', () => {
    render(<FormTextarea showCharCount maxChars={100} value="Hello" />);
    expect(screen.getByText('5/100')).toBeInTheDocument();
  });

  it('applies warning style when over max chars', () => {
    render(<FormTextarea showCharCount maxChars={5} value="Hello World" />);
    expect(screen.getByText('11/5')).toHaveClass('text-red-500');
  });

  it('passes through other textarea props', () => {
    render(<FormTextarea placeholder="Enter text" rows={5} />);
    const textarea = screen.getByRole('textbox');
    expect(textarea).toHaveAttribute('placeholder', 'Enter text');
    expect(textarea).toHaveAttribute('rows', '5');
  });
});
