import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { ProjectCard } from '../ProjectCard';
import { Project } from '../../types/project';

// Mock date-fns
vi.mock('date-fns', () => ({
  formatDistanceToNow: vi.fn(() => '2 天前'),
}));

vi.mock('date-fns/locale', () => ({
  zhCN: {},
}));

const mockProject: Project = {
  id: '1',
  name: 'Test Project',
  path: '/path/to/project',
  description: 'Test description',
  created_at: '2023-01-01T00:00:00Z',
  updated_at: '2023-01-02T00:00:00Z',
  is_active: true,
};

const mockProps = {
  project: mockProject,
  onOpen: vi.fn(),
  onEdit: vi.fn(),
  onDelete: vi.fn(),
};

describe('ProjectCard', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders project information correctly', () => {
    render(<ProjectCard {...mockProps} />);
    
    expect(screen.getByText('Test Project')).toBeInTheDocument();
    expect(screen.getByText('Test description')).toBeInTheDocument();
    expect(screen.getByText('project')).toBeInTheDocument();
    expect(screen.getByText('2 天前')).toBeInTheDocument();
  });

  it('calls onOpen when open button is clicked', () => {
    render(<ProjectCard {...mockProps} />);
    
    const openButton = screen.getByText('打开');
    fireEvent.click(openButton);
    
    expect(mockProps.onOpen).toHaveBeenCalledWith(mockProject);
  });

  it('calls onEdit when edit button is clicked', () => {
    render(<ProjectCard {...mockProps} />);
    
    const editButton = screen.getByText('编辑');
    fireEvent.click(editButton);
    
    expect(mockProps.onEdit).toHaveBeenCalledWith(mockProject);
  });

  it('renders without description', () => {
    const projectWithoutDescription = { ...mockProject, description: undefined };
    render(<ProjectCard {...mockProps} project={projectWithoutDescription} />);
    
    expect(screen.getByText('Test Project')).toBeInTheDocument();
    expect(screen.queryByText('Test description')).not.toBeInTheDocument();
  });

  it('shows menu when more button is clicked', () => {
    render(<ProjectCard {...mockProps} />);

    // 找到更多按钮并点击 - 使用更通用的选择器
    const moreButtons = screen.getAllByRole('button');
    const moreButton = moreButtons.find(button =>
      button.querySelector('svg') && !button.textContent?.includes('编辑') && !button.textContent?.includes('打开')
    );

    if (moreButton) {
      fireEvent.click(moreButton);

      // 检查菜单项是否显示
      expect(screen.getByText('打开项目')).toBeInTheDocument();
      expect(screen.getAllByText('编辑')).toHaveLength(2); // 一个在菜单中，一个在按钮中
      expect(screen.getByText('删除')).toBeInTheDocument();
    }
  });

  it('calls onDelete when delete menu item is clicked', () => {
    render(<ProjectCard {...mockProps} />);

    // 打开菜单
    const moreButtons = screen.getAllByRole('button');
    const moreButton = moreButtons.find(button =>
      button.querySelector('svg') && !button.textContent?.includes('编辑') && !button.textContent?.includes('打开')
    );

    if (moreButton) {
      fireEvent.click(moreButton);

      // 点击删除
      const deleteButton = screen.getByText('删除');
      fireEvent.click(deleteButton);

      expect(mockProps.onDelete).toHaveBeenCalledWith(mockProject.id);
    }
  });

  it('extracts directory name correctly', () => {
    const projectWithWindowsPath = {
      ...mockProject,
      path: 'C:\\Users\\test\\MyProject',
    };
    
    render(<ProjectCard {...mockProps} project={projectWithWindowsPath} />);
    expect(screen.getByText('MyProject')).toBeInTheDocument();
  });
});
