// kanban.jsx — Kanban board with drag-drop status changes + reorder

function KanbanCard({ task, onOpen, onDragStart, onDragOverCard, onDropOnCard, dropIndicator, isDragging, isJustDropped }) {
  const epic = EPICS.find(e => e.id === task.epicId);
  // Type chip — surfaces the task's `type` (task / bug / chore / spike)
  // so the kanban column reads at a glance. Bug rows also get a tinted
  // left border so they stand out even when the card is dense.
  // Bug BG_02E81DCE4B — Nandana asked for a Bug tag on Kanban cards.
  const typeMeta = (typeof taskTypeMeta === "function") ? taskTypeMeta(task) : null;
  const isBug = typeMeta && typeMeta.id === "bug";
  const cls = `k-card${isDragging ? " is-dragging" : ""}${isJustDropped ? " is-just-dropped" : ""}${isBug ? " is-bug" : ""}`;
  return (
    <div
      className={cls}
      style={{
        "--epic-color": epic?.color,
        cursor: isDragging ? "grabbing" : "grab",
        borderTop: dropIndicator === "above" ? "2px solid var(--brand)" : undefined,
        borderBottom: dropIndicator === "below" ? "2px solid var(--brand)" : undefined,
      }}
      draggable
      onDragStart={(e) => {
        e.dataTransfer.effectAllowed = "move";
        e.dataTransfer.setData("text/plain", task.id);
        onDragStart && onDragStart(task);
      }}
      onDragOver={(e) => {
        e.preventDefault();
        e.stopPropagation();
        e.dataTransfer.dropEffect = "move";
        const r = e.currentTarget.getBoundingClientRect();
        const above = (e.clientY - r.top) < r.height / 2;
        onDragOverCard && onDragOverCard(task, above ? "above" : "below");
      }}
      onDrop={(e) => {
        e.preventDefault();
        e.stopPropagation();
        const r = e.currentTarget.getBoundingClientRect();
        const above = (e.clientY - r.top) < r.height / 2;
        onDropOnCard && onDropOnCard(e, task, above ? "above" : "below");
      }}
      onClick={() => onOpen(task)}
    >
      <div className="k-card-head">
        <span className="k-epic-tag">{epic?.title}</span>
        {/* Type chip — only rendered for non-default types so vanilla
            tasks aren't visually cluttered. Bug rows additionally get
            the .is-bug class on the card itself for a tinted left
            border (see kanban.css). */}
        {typeMeta && typeMeta.id !== "task" && (
          <span className={`k-type-tag k-type-${typeMeta.id}`}
                title={typeMeta.label}
                aria-label={`Type ${typeMeta.label}`}>
            <span className="k-type-tag-emoji">{typeMeta.emoji}</span>
            {typeMeta.label}
          </span>
        )}
        <PriorityPill prio={task.prio} fill={false}/>
        {/* Surfaced at the top of the card so it's the first thing
            you notice when scanning a column for blockers. */}
        {typeof OverdueBadge !== "undefined" && <OverdueBadge task={task} size="tiny"/>}
      </div>
      <div className="k-card-title">{task.name}</div>
      <div className="k-card-footer">
        <div className="k-card-meta">
          {task.due !== "—" && (
            <span className={"meta-group" + (typeof isOverdueNow === "function" && isOverdueNow(task) ? " is-overdue" : "")}>
              <Icons.Calendar/>{task.due}
            </span>
          )}
          <span className="meta-group"><Icons.ArrowUp/>{task.points}</span>
          {task.subtasks > 0 && (
            <span className="meta-group"><Icons.GitBranch/>{task.subtasks}</span>
          )}
        </div>
        <AvatarStack ids={task.owners} max={2} size="sm"/>
      </div>
    </div>
  );
}

function KanbanView({ tasks, onOpen, onMove }) {
  const [dragOverCol, setDragOverCol] = React.useState(null);
  const [dropTarget, setDropTarget] = React.useState(null); // { id, side: "above"|"below" }
  const [draggingId, setDraggingId] = React.useState(null);
  const [justDroppedId, setJustDroppedId] = React.useState(null);
  const draggingRef = React.useRef(null);
  const flashTimer = React.useRef(null);

  function handleDragStart(task) {
    draggingRef.current = task;
    setDraggingId(task.id);
    setDropTarget(null);
  }
  function handleDragOverCard(task, side) {
    if (draggingId === task.id) return; // can't drop on self
    setDropTarget({ id: task.id, side });
  }
  function endDrag() {
    setDragOverCol(null);
    setDropTarget(null);
    setDraggingId(null);
    draggingRef.current = null;
  }
  function celebrate(id) {
    setJustDroppedId(id);
    if (flashTimer.current) clearTimeout(flashTimer.current);
    flashTimer.current = setTimeout(() => {
      setJustDroppedId(j => j === id ? null : j);
      flashTimer.current = null;
    }, 700);
  }

  // Drop directly on a card → insert above/below it
  function handleDropOnCard(e, target, side) {
    const sourceId = e.dataTransfer.getData("text/plain") || draggingRef.current?.id;
    endDrag();
    if (!sourceId || sourceId === target.id) return;
    const colTasks = tasks.filter(t => t.status === target.status);
    const colIds = colTasks.map(t => t.id).filter(id => id !== sourceId);
    let idx = colIds.indexOf(target.id);
    if (idx === -1) idx = colIds.length;
    if (side === "below") idx += 1;
    onMove && onMove(sourceId, { status: target.status, position: idx });
    celebrate(sourceId);
  }

  // Drop on the column body (not on a card) → end of column
  function handleDropOnColumn(e, statusId) {
    e.preventDefault();
    const sourceId = e.dataTransfer.getData("text/plain") || draggingRef.current?.id;
    endDrag();
    if (!sourceId) return;
    const t = tasks.find(x => x.id === sourceId);
    if (!t) return;
    const colTasks = tasks.filter(x => x.status === statusId && x.id !== sourceId);
    onMove && onMove(sourceId, { status: statusId, position: colTasks.length });
    celebrate(sourceId);
  }

  return (
    <div className="kanban-scroll" onDragEnd={endDrag}>
      <div className="kanban">
        {STATUSES.map(status => {
          const colTasks = tasks.filter(t => t.status === status.id);
          const isOver = dragOverCol === status.id;
          const receiving = !!draggingId;
          return (
            <div key={status.id}
                 className="kanban-col"
                 onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; if (dragOverCol !== status.id) setDragOverCol(status.id); }}
                 onDragLeave={(e) => { if (e.currentTarget.contains(e.relatedTarget)) return; setDragOverCol(c => c === status.id ? null : c); }}
                 onDrop={(e) => handleDropOnColumn(e, status.id)}
                 style={isOver ? { boxShadow: "inset 0 0 0 2px var(--brand)", borderRadius: 8 } : null}
            >
              <div className="kanban-col-head">
                <span className="kanban-col-swatch" style={{ background: `var(--status-${status.id})` }}/>
                <span className="kanban-col-title">{status.label}</span>
                <span className="kanban-col-count">{colTasks.length}</span>
                <button className="kanban-col-add"><Icons.Plus size={14}/></button>
              </div>
              <div className={`kanban-col-body${receiving ? " is-receiving" : ""}`}>
                {colTasks.map(t => (
                  <KanbanCard key={t.id}
                    task={t}
                    onOpen={onOpen}
                    onDragStart={handleDragStart}
                    onDragOverCard={handleDragOverCard}
                    onDropOnCard={handleDropOnCard}
                    dropIndicator={dropTarget?.id === t.id ? dropTarget.side : null}
                    isDragging={draggingId === t.id}
                    isJustDropped={justDroppedId === t.id}/>
                ))}
                {colTasks.length === 0 && (
                  <div style={{
                    color: isOver ? "var(--brand)" : "var(--ink-faint)",
                    fontSize: 12,
                    padding: "14px 4px",
                    textAlign: "center",
                    border: receiving ? "1.5px dashed " + (isOver ? "var(--brand)" : "var(--border-strong)") : "1.5px dashed transparent",
                    borderRadius: 6,
                    transition: "border-color 0.15s, color 0.15s, background 0.15s",
                    background: isOver ? "rgba(162,93,220,0.06)" : "transparent",
                    fontWeight: isOver ? 600 : 400,
                  }}>
                    {isOver ? "Drop here" : (receiving ? "Drop here to add" : "Nothing here")}
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { KanbanView, KanbanCard });
