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

describe('Card', () => {
  it('renders children', () => {
    render(<Card>Card content</Card>);
    expect(screen.getByText('Card content')).toBeInTheDocument();
  });

  it('applies base card styling', () => {
    const { container } = render(<Card>Content</Card>);
    expect(container.firstChild).toHaveClass('bg-white', 'rounded-lg', 'shadow-sm');
  });

  it('applies bordered style by default', () => {
    const { container } = render(<Card>Content</Card>);
    expect(container.firstChild).toHaveClass('border');
  });

  it('can remove border', () => {
    const { container } = render(<Card bordered={false}>Content</Card>);
    expect(container.firstChild).not.toHaveClass('border');
  });

  it('applies medium padding by default', () => {
    const { container } = render(<Card>Content</Card>);
    expect(container.firstChild).toHaveClass('p-4');
  });

  it('applies no padding', () => {
    const { container } = render(<Card padding="none">Content</Card>);
    expect(container.firstChild).not.toHaveClass('p-3', 'p-4', 'p-6');
  });

  it('applies small padding', () => {
    const { container } = render(<Card padding="sm">Content</Card>);
    expect(container.firstChild).toHaveClass('p-3');
  });

  it('applies large padding', () => {
    const { container } = render(<Card padding="lg">Content</Card>);
    expect(container.firstChild).toHaveClass('p-6');
  });

  it('applies hoverable styling when hoverable', () => {
    const { container } = render(<Card hoverable>Content</Card>);
    expect(container.firstChild).toHaveClass('hover:shadow-md', 'cursor-pointer');
  });

  it('is not hoverable by default', () => {
    const { container } = render(<Card>Content</Card>);
    expect(container.firstChild).not.toHaveClass('cursor-pointer');
  });

  it('handles click events', () => {
    const handleClick = vi.fn();
    render(<Card onClick={handleClick}>Content</Card>);
    fireEvent.click(screen.getByText('Content'));
    expect(handleClick).toHaveBeenCalled();
  });

  it('has button role when clickable', () => {
    render(<Card onClick={() => {}}>Content</Card>);
    expect(screen.getByRole('button')).toBeInTheDocument();
  });

  it('has tabIndex when clickable', () => {
    render(<Card onClick={() => {}}>Content</Card>);
    expect(screen.getByRole('button')).toHaveAttribute('tabIndex', '0');
  });

  it('does not have button role when not clickable', () => {
    render(<Card>Content</Card>);
    expect(screen.queryByRole('button')).not.toBeInTheDocument();
  });

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

describe('CardHeader', () => {
  it('renders children', () => {
    render(<CardHeader>Header content</CardHeader>);
    expect(screen.getByText('Header content')).toBeInTheDocument();
  });

  it('applies header styling', () => {
    const { container } = render(<CardHeader>Header</CardHeader>);
    expect(container.firstChild).toHaveClass('flex', 'items-center', 'justify-between');
  });

  it('applies border bottom', () => {
    const { container } = render(<CardHeader>Header</CardHeader>);
    expect(container.firstChild).toHaveClass('border-b');
  });

  it('renders actions when provided', () => {
    render(<CardHeader actions={<button>Action</button>}>Header</CardHeader>);
    expect(screen.getByText('Action')).toBeInTheDocument();
  });

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

  it('applies font styling to header text', () => {
    const { container } = render(<CardHeader>Header</CardHeader>);
    const headerText = container.querySelector('.font-semibold');
    expect(headerText).toBeInTheDocument();
  });
});

describe('CardBody', () => {
  it('renders children', () => {
    render(<CardBody>Body content</CardBody>);
    expect(screen.getByText('Body content')).toBeInTheDocument();
  });

  it('applies body styling', () => {
    const { container } = render(<CardBody>Body</CardBody>);
    expect(container.firstChild).toHaveClass('py-4');
  });

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

describe('CardFooter', () => {
  it('renders children', () => {
    render(<CardFooter>Footer content</CardFooter>);
    expect(screen.getByText('Footer content')).toBeInTheDocument();
  });

  it('applies footer styling', () => {
    const { container } = render(<CardFooter>Footer</CardFooter>);
    expect(container.firstChild).toHaveClass('pt-4', 'border-t');
  });

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

describe('Card composition', () => {
  it('renders complete card with all parts', () => {
    render(
      <Card>
        <CardHeader actions={<button>Edit</button>}>Title</CardHeader>
        <CardBody>Main content here</CardBody>
        <CardFooter>Footer content</CardFooter>
      </Card>
    );
    expect(screen.getByText('Title')).toBeInTheDocument();
    expect(screen.getByText('Edit')).toBeInTheDocument();
    expect(screen.getByText('Main content here')).toBeInTheDocument();
    expect(screen.getByText('Footer content')).toBeInTheDocument();
  });
});
