import React from 'react';
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { KanbanBoard } from '@/components/calendar/KanbanBoard';
import type { CalendarEntry } from '@/api/calendar';

function makeTask(id: string, title: string, status: CalendarEntry['status']): CalendarEntry {
  return {
    id,
    calendar_id: 'cal-1',
    entry_type: 'task',
    subtype: 'normal',
    title,
    all_day: false,
    priority: 'medium',
    status,
    created_by: 'u-1',
    due_date: '2026-07-01T00:00:00.000Z',
  };
}

const board = {
  open: [makeTask('t-1', 'Recherche', 'open')],
  in_progress: [makeTask('t-2', 'Implementierung', 'in_progress')],
  done: [makeTask('t-3', 'Tests', 'done')],
  cancelled: [],
};

describe('KanbanBoard', () => {
  it('renders three columns (open / in_progress / done)', () => {
    render(<KanbanBoard board={board} onMove={vi.fn()} />);
    expect(screen.getByTestId('kanban-column-open')).toBeInTheDocument();
    expect(screen.getByTestId('kanban-column-in_progress')).toBeInTheDocument();
    expect(screen.getByTestId('kanban-column-done')).toBeInTheDocument();
  });

  it('renders task cards inside the correct columns', () => {
    render(<KanbanBoard board={board} onMove={vi.fn()} />);
    expect(screen.getByTestId('kanban-card-t-1').textContent).toContain('Recherche');
    expect(screen.getByTestId('kanban-card-t-2').textContent).toContain('Implementierung');
    expect(screen.getByTestId('kanban-card-t-3').textContent).toContain('Tests');
  });

  it('shows column counts', () => {
    render(<KanbanBoard board={board} onMove={vi.fn()} />);
    expect(screen.getByTestId('kanban-count-open').textContent).toBe('1');
    expect(screen.getByTestId('kanban-count-in_progress').textContent).toBe('1');
    expect(screen.getByTestId('kanban-count-done').textContent).toBe('1');
  });

  it('shows empty state when there are no tasks', () => {
    render(
      <KanbanBoard
        board={{ open: [], in_progress: [], done: [], cancelled: [] }}
        onMove={vi.fn()}
      />
    );
    expect(screen.getByTestId('kanban-empty')).toBeInTheDocument();
  });

  it('drag-and-drop into another column fires onMove with target status', () => {
    const onMove = vi.fn();
    render(<KanbanBoard board={board} onMove={onMove} />);
    const card = screen.getByTestId('kanban-card-t-1');
    const targetCol = screen.getByTestId('kanban-column-done');
    const dataTransfer = {
      setData: vi.fn(),
      getData: (k: string) => {
        if (k === 'application/x-kanban-entry') return 't-1';
        if (k === 'application/x-kanban-source') return 'open';
        return '';
      },
      types: ['application/x-kanban-entry', 'application/x-kanban-source'],
      effectAllowed: '',
      dropEffect: '',
    };
    fireEvent.dragStart(card, { dataTransfer });
    fireEvent.dragOver(targetCol, { dataTransfer });
    fireEvent.drop(targetCol, { dataTransfer });
    expect(onMove).toHaveBeenCalledTimes(1);
    const [movedEntry, target] = onMove.mock.calls[0];
    expect(movedEntry.id).toBe('t-1');
    expect(target).toBe('done');
  });

  it('clicking a card fires onSelect', () => {
    const onSelect = vi.fn();
    render(<KanbanBoard board={board} onMove={vi.fn()} onSelect={onSelect} />);
    fireEvent.click(screen.getByTestId('kanban-card-t-2'));
    expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({ id: 't-2' }));
  });
});
