// ============ TaskQuest — Kanban board, tiles, drag & drop ============
const { useState, useEffect, useRef } = React;
const { ROLES: R4, PROJECTS: P4, COLUMNS: COLS4 } = window.TQ;

function needsModal(from, to) {
  if (from === to) return null;
  if (to === "unhappy") return "date";
  if (to === "onhold") return "hold";
  if (to === "done") return "done";
  return null; // free move (e.g. back to happy)
}

function TaskTile({ task, role, showAssignee, showProject, layout, delivName, onClick, onDragStart, onDragEnd, dragging }) {
  const { daysUntil, relDue, fmtDate } = window.TQ;
  const overdue = task.status !== "done" && daysUntil(task.due) < 0;
  const proj = P4[task.project];
  const draggable = task.status !== "done";
  const hasBar = layout === "bar";
  const barColor = COLS4.find(c => c.key === task.status).color;

  return (
    <div
      className={`tile ${layout} ${hasBar ? "has-bar" : ""} ${dragging ? "dragging" : ""}`}
      draggable={draggable}
      onClick={() => onClick(task)}
      onDragStart={(e) => { e.dataTransfer.effectAllowed = "move"; onDragStart(task); }}
      onDragEnd={onDragEnd}>
      {hasBar && <span className="tile-bar" style={{ background: barColor }} />}

      {showProject && (
        <div className="tile-project" style={{ marginBottom: 7 }}>
          <span className="pdot" style={{ background: proj.color }} />{proj.name}
        </div>
      )}

      {delivName && (
        <div className="tile-deliv"><Ic.Layers size={11} />{delivName}</div>
      )}

      <div className="tile-title">{task.name}</div>

      <div className="tile-meta">
        <span className="tile-id">{task.id}</span>
        <span className="tile-spacer" />
        {showAssignee && <Avatar who={task.assignee} size="xs" />}
        <span className={`tile-due ${overdue ? "overdue" : ""}`}>
          <Ic.Calendar size={12} />{overdue ? relDue(task.due) : fmtDate(task.due)}
        </span>
      </div>

      {(overdue || (task.request && task.request.status === "pending") || (task.completion && task.completion.status === "pending") || (task.status === "done" && task.completion)) && (
        <div className="tile-chips">
          {overdue && <span className="badge overdue"><Ic.Alert size={11} />Overdue</span>}
          {task.request && task.request.status === "pending" && <span className="badge pending"><Ic.Clock size={11} />Approval pending</span>}
          {task.completion && task.completion.status === "pending" && <span className="badge pending"><Ic.Clock size={11} />Needs sign-off</span>}
          {task.status === "done" && task.completion && task.completion.status === "approved" && (
            task.completion.onTime
              ? <span className="badge ontime"><Ic.Check size={11} />On time · +10</span>
              : <span className="badge late">Late · +0</span>
          )}
        </div>
      )}
    </div>
  );
}

function Column({ col, tasks, role, showAssignee, showProject, layout, delivMap, onTileClick, drag, onDropTask }) {
  const [over, setOver] = useState(false);
  const dragTask = drag.task;
  const modalKind = dragTask ? needsModal(dragTask.status, col.key) : null;
  const sameCol = dragTask && dragTask.status === col.key;
  const canDrop = dragTask && !sameCol;

  return (
    <div
      className={`column ${over && canDrop ? "drag-over" : ""}`}
      onDragOver={(e) => { if (canDrop) { e.preventDefault(); setOver(true); } }}
      onDragLeave={() => setOver(false)}
      onDrop={(e) => { e.preventDefault(); setOver(false); if (canDrop) onDropTask(dragTask, col.key); }}>
      <div className="col-head">
        <span className="col-dot" style={{ background: col.color }} />
        <span className="col-name">{col.name}</span>
        <span className="col-count">{tasks.length}</span>
      </div>
      <div className="col-list">
        {tasks.length === 0 && <div className="col-empty">{over && canDrop ? "Drop here" : "No tasks"}</div>}
        {tasks.map(t => (
          <TaskTile key={t.id} task={t} role={role} showAssignee={showAssignee} showProject={showProject}
            layout={layout} delivName={delivMap ? delivMap[t.deliverable] : null} onClick={onTileClick}
            dragging={drag.task && drag.task.id === t.id}
            onDragStart={drag.start} onDragEnd={drag.end} />
        ))}
      </div>
    </div>
  );
}

function KanbanBoard({ role, project, tasks, layout, deliverables = [], filterAssignee = "", onTileClick, onMove }) {
  const r = R4[role];
  const showAssignee = r.type === "pm" || r.type === "dm";
  const scope = r.type === "dm" ? project : project;
  const showProject = scope === "all";
  const [drag, setDrag] = useState({ task: null });

  const delivMap = {};
  deliverables.forEach(d => { delivMap[d.id] = d.name; });

  // visible tasks
  let visible = tasks;
  if (r.type === "consultant") visible = visible.filter(t => t.assignee === role);
  else if (scope !== "all") visible = visible.filter(t => t.project === scope);
  if (filterAssignee) visible = visible.filter(t => t.assignee === filterAssignee);

  const dragApi = {
    task: drag.task,
    start: (t) => setDrag({ task: t }),
    end: () => setDrag({ task: null }),
  };

  function handleDrop(task, toCol) {
    setDrag({ task: null });
    onMove(task, toCol);
  }

  const byCol = {};
  COLS4.forEach(c => { byCol[c.key] = visible.filter(t => t.status === c.key); });

  return (
    <div className="board">
      {COLS4.map(col => (
        <Column key={col.key} col={col} tasks={byCol[col.key]} role={role}
          showAssignee={showAssignee} showProject={showProject} layout={layout} delivMap={delivMap}
          onTileClick={onTileClick} drag={dragApi} onDropTask={handleDrop} />
      ))}
    </div>
  );
}

window.KanbanBoard = KanbanBoard;
window.needsModal = needsModal;
