/**
 * KanbanBoard — three task columns (open / in_progress / done) with
 * drag-and-drop between columns to update task status.
 */

import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import clsx from 'clsx';
import type { CalendarEntry } from '@/api/calendar';
import { formatDateShort } from '@/utils/date';

export type KanbanStatus = 'open' | 'in_progress' | 'done' | 'cancelled';

export interface KanbanBoardProps {
  board: Record<KanbanStatus, CalendarEntry[]>;
  loading?: boolean;
  /** Fired when a card is dropped into a different column. */
  onMove: (entry: CalendarEntry, target: KanbanStatus) => void | Promise<void>;
  /** Fired when a card is clicked (open detail panel). */
  onSelect?: (entry: CalendarEntry) => void;
}

const COLUMNS: KanbanStatus[] = ['open', 'in_progress', 'done'];

function statusKey(s: KanbanStatus): string {
  return `calendar.kanban.${s}`;
}

function priorityBadgeClass(p: string): string {
  switch (p) {
    case 'high':
      return 'bg-danger-100 text-danger-800';
    case 'low':
      return 'bg-secondary-100 text-secondary-700';
    default:
      return 'bg-warning-100 text-warning-800';
  }
}

function fmtDue(entry: CalendarEntry): string | null {
  if (!entry.due_date) return null;
  return formatDateShort(entry.due_date) || null;
}

export function KanbanBoard({ board, loading, onMove, onSelect }: KanbanBoardProps) {
  const { t } = useTranslation();
  const [dragOver, setDragOver] = useState<KanbanStatus | null>(null);

  const handleDragStart = (e: React.DragEvent<HTMLDivElement>, entry: CalendarEntry) => {
    e.dataTransfer.setData('application/x-kanban-entry', entry.id);
    e.dataTransfer.setData('application/x-kanban-source', entry.status);
    e.dataTransfer.effectAllowed = 'move';
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>, status: KanbanStatus) => {
    if (e.dataTransfer.types.includes('application/x-kanban-entry')) {
      e.preventDefault();
      e.dataTransfer.dropEffect = 'move';
      if (dragOver !== status) setDragOver(status);
    }
  };

  const handleDragLeave = (status: KanbanStatus) => {
    setDragOver((cur) => (cur === status ? null : cur));
  };

  const handleDrop = async (e: React.DragEvent<HTMLDivElement>, target: KanbanStatus) => {
    e.preventDefault();
    setDragOver(null);
    const id = e.dataTransfer.getData('application/x-kanban-entry');
    const source = e.dataTransfer.getData('application/x-kanban-source') as KanbanStatus;
    if (!id || source === target) return;
    const allEntries = [...board.open, ...board.in_progress, ...board.done, ...board.cancelled];
    const entry = allEntries.find((x) => x.id === id);
    if (!entry) return;
    await onMove(entry, target);
  };

  if (!loading && board.open.length === 0 && board.in_progress.length === 0 && board.done.length === 0) {
    return (
      <div className="p-8 text-center text-secondary-500" data-testid="kanban-empty">
        {t('calendar.kanban.noTasks')}
      </div>
    );
  }

  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-4" data-testid="kanban-board">
      {COLUMNS.map((status) => {
        const entries = board[status] ?? [];
        const isOver = dragOver === status;
        return (
          <div
            key={status}
            data-testid={`kanban-column-${status}`}
            onDragOver={(e) => handleDragOver(e, status)}
            onDragLeave={() => handleDragLeave(status)}
            onDrop={(e) => handleDrop(e, status)}
            className={clsx(
              'bg-secondary-50 rounded-lg border border-secondary-200 p-3 min-h-[12rem]',
              'transition-colors motion-safe:duration-200',
              isOver && 'ring-2 ring-primary-500 bg-primary-50'
            )}
          >
            <div className="flex items-center justify-between mb-3 px-1">
              <h3 className="text-sm font-semibold text-secondary-800 uppercase tracking-wide">
                {t(statusKey(status))}
              </h3>
              <span
                className="text-xs text-secondary-500 bg-secondary-200 rounded-full px-2 py-0.5"
                data-testid={`kanban-count-${status}`}
              >
                {entries.length}
              </span>
            </div>

            <div className="space-y-2">
              {entries.length === 0 ? (
                <div className="text-xs text-secondary-400 italic px-1">
                  {t('calendar.kanban.empty')}
                </div>
              ) : (
                entries.map((entry) => (
                  <div
                    key={entry.id}
                    draggable
                    onDragStart={(e) => handleDragStart(e, entry)}
                    onClick={() => onSelect?.(entry)}
                    data-testid={`kanban-card-${entry.id}`}
                    className={clsx(
                      'bg-white rounded-md border border-secondary-200 shadow-sm p-3',
                      'cursor-grab active:cursor-grabbing hover:shadow-md hover:border-primary-300',
                      'motion-safe:transition-shadow'
                    )}
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="font-medium text-sm text-secondary-900 line-clamp-2">
                        {entry.title}
                      </div>
                      <span
                        className={clsx(
                          'text-xs px-1.5 py-0.5 rounded font-medium uppercase shrink-0',
                          priorityBadgeClass(entry.priority)
                        )}
                      >
                        {entry.priority}
                      </span>
                    </div>
                    {entry.description && (
                      <div className="mt-1 text-xs text-secondary-600 line-clamp-2">
                        {entry.description}
                      </div>
                    )}
                    <div className="mt-2 flex items-center justify-between text-xs text-secondary-500">
                      <span>{fmtDue(entry) ?? '—'}</span>
                      {(entry.subtasks?.length ?? 0) > 0 && (
                        <span data-testid={`kanban-subtask-count-${entry.id}`}>
                          ✓ {entry.subtasks?.filter((s) => s.done).length ?? 0}/
                          {entry.subtasks?.length ?? 0}
                        </span>
                      )}
                    </div>
                  </div>
                ))
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default KanbanBoard;
