import {
  DndContext, PointerSensor, useSensor, useSensors, closestCorners,
  type DragEndEvent, useDroppable, useDraggable,
} from "@dnd-kit/core";
import type { Lane, ProjectTask } from "@/types";
import { LANE_LABELS, formatDate, classNames } from "@/lib/format";

const LANES: Lane[] = ["todo", "doing", "review", "done"];
const LANE_DOT: Record<Lane, string> = {
  todo: "#98A2B3", doing: "#2E90FA", review: "#7A5AF8", done: "#12B76A",
};

export function Kanban({
  tasks, onMove, onCardClick, readOnly,
}: { tasks: ProjectTask[]; onMove: (taskId: string, lane: Lane) => void; onCardClick?: (t: ProjectTask) => void; readOnly?: boolean }) {
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));

  function onDragEnd(e: DragEndEvent) {
    const lane = e.over?.id as Lane | undefined;
    const taskId = e.active.id as string;
    if (lane && LANES.includes(lane)) {
      const t = tasks.find((x) => x.id === taskId);
      if (t && t.lane !== lane) onMove(taskId, lane);
    }
  }

  return (
    <DndContext sensors={sensors} collisionDetection={closestCorners} onDragEnd={readOnly ? undefined : onDragEnd}>
      <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-3">
        {LANES.map((lane) => (
          <Column key={lane} lane={lane} tasks={tasks.filter((t) => t.lane === lane)} onCardClick={onCardClick} readOnly={readOnly} />
        ))}
      </div>
    </DndContext>
  );
}

function Column({ lane, tasks, onCardClick, readOnly }: { lane: Lane; tasks: ProjectTask[]; onCardClick?: (t: ProjectTask) => void; readOnly?: boolean }) {
  const { setNodeRef, isOver } = useDroppable({ id: lane });
  return (
    <div ref={setNodeRef} className={classNames("rounded-card border bg-canvas/60 min-h-[200px] transition-colors", isOver ? "border-navy bg-navy-subtle/40" : "border-border")}>
      <div className="flex items-center gap-2 px-3 py-2.5 border-b border-border">
        <span className="w-2 h-2 rounded-full" style={{ background: LANE_DOT[lane] }} />
        <span className="text-sm font-semibold text-ink">{LANE_LABELS[lane]}</span>
        <span className="ml-auto text-xs text-ink-muted font-num">{tasks.length}</span>
      </div>
      <div className="p-2 space-y-2">
        {tasks.map((t) => <KanbanCard key={t.id} task={t} onCardClick={onCardClick} readOnly={readOnly} />)}
        {tasks.length === 0 && <div className="text-xs text-ink-muted text-center py-6">비어 있음</div>}
      </div>
    </div>
  );
}

function KanbanCard({ task, onCardClick, readOnly }: { task: ProjectTask; onCardClick?: (t: ProjectTask) => void; readOnly?: boolean }) {
  const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({ id: task.id, disabled: readOnly });
  const style = transform ? { transform: `translate(${transform.x}px, ${transform.y}px)` } : undefined;
  return (
    <div
      ref={setNodeRef} style={style} {...(readOnly ? {} : listeners)} {...attributes}
      onClick={() => { if (!isDragging) onCardClick?.(task); }}
      className={classNames(
        "bg-surface border border-border rounded-control p-3 shadow-card",
        readOnly ? "" : "cursor-pointer active:cursor-grabbing", isDragging && "opacity-60"
      )}
    >
      <div className="text-sm font-medium text-ink">{task.title}</div>
      <div className="flex items-center justify-between mt-2 text-[11px] text-ink-muted">
        <span className="tabular">{formatDate(task.start)}</span>
        <span>{task.assignee ? task.assignee.split("@")[0] : ""}</span>
      </div>
      {task.progress > 0 && (
        <div className="h-1 rounded-pill bg-divider mt-2 overflow-hidden">
          <div className="h-full bg-navy" style={{ width: `${task.progress}%` }} />
        </div>
      )}
    </div>
  );
}
