/* Board (kanban) view — modern, soft cards */

function BoardView({ tasks, onSelect, selectedId, onStatusChange, compact = false }) {
  const cols = D.statuses.map(s => ({
    status: s,
    tasks: tasks.filter(t => t.statusId === s.id),
  }));
  const [draggingId, setDraggingId] = React.useState(null);
  const [overCol, setOverCol] = React.useState(null);

  return (
    <div style={{
      flex: 1, overflowX: 'auto', overflowY: 'hidden',
      background: 'rgb(var(--bg))',
      padding: '16px 20px 20px',
    }}>
      <div style={{
        display: 'grid',
        gridAutoFlow: 'column',
        gridAutoColumns: '300px',
        gap: 14,
        height: '100%',
      }}>
        {cols.map(({ status, tasks: ct }) => (
          <BoardColumn key={status.id} status={status} tasks={ct}
            onSelect={onSelect} selectedId={selectedId}
            compact={compact}
            isOver={overCol === status.id}
            onDragOver={(e) => { e.preventDefault(); setOverCol(status.id); }}
            onDragLeave={() => setOverCol(c => c === status.id ? null : c)}
            onDrop={(e) => {
              e.preventDefault();
              const id = parseInt(e.dataTransfer.getData('text/plain'), 10);
              if (id) onStatusChange?.(id, status.id);
              setOverCol(null); setDraggingId(null);
            }}
            onCardDragStart={(id) => setDraggingId(id)}
            onCardDragEnd={() => { setDraggingId(null); setOverCol(null); }}
            draggingId={draggingId}
          />
        ))}
      </div>
    </div>
  );
}

function BoardColumn({ status, tasks, onSelect, selectedId, isOver, onDragOver, onDragLeave, onDrop, onCardDragStart, onCardDragEnd, draggingId, compact = false }) {
  const totalEst = tasks.reduce((s, t) => s + (t.estimateMins || 0), 0);
  return (
    <div onDragOver={onDragOver} onDragLeave={onDragLeave} onDrop={onDrop} style={{
      display: 'flex', flexDirection: 'column',
      background: isOver ? 'rgb(var(--accent-soft) / 0.5)' : 'rgb(var(--paper-2) / 0.5)',
      border: '1px solid ' + (isOver ? 'rgb(var(--accent))' : 'rgb(var(--rule))'),
      borderRadius: 12,
      overflow: 'hidden',
      minHeight: 0,
      transition: 'background-color .14s, border-color .14s',
    }}>
      <div style={{
        padding: '12px 14px',
        display: 'flex', alignItems: 'center', gap: 8,
        background: 'rgb(var(--surface))',
        borderBottom: '1px solid rgb(var(--rule))',
      }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          padding: '3px 10px', background: status.colour + '14', color: status.colour,
          fontSize: 11.5, fontWeight: 700,
          borderRadius: 999,
        }}>
          <span style={{ width: 6, height: 6, background: status.colour, borderRadius: '50%' }} />
          {status.title}
        </span>
        <span className="num" style={{
          fontSize: 11, fontWeight: 600, color: 'rgb(var(--muted))',
          background: 'rgb(var(--paper-2))', padding: '2px 7px',
          borderRadius: 999,
        }}>{tasks.length}</span>
        <span style={{ flex: 1 }} />
        {totalEst > 0 && <span style={{ fontSize: 10.5, color: 'rgb(var(--muted))', fontFamily: 'JetBrains Mono, monospace' }} title="Sum of estimates">{fmtMins(totalEst)}</span>}
        <button title="Add task" style={{
          fontSize: 15, color: 'rgb(var(--muted))', padding: '0 4px', lineHeight: 1,
          borderRadius: 6,
        }}
          onMouseEnter={e => { e.currentTarget.style.color = 'rgb(var(--accent))'; e.currentTarget.style.background = 'rgb(var(--accent-soft))'; }}
          onMouseLeave={e => { e.currentTarget.style.color = 'rgb(var(--muted))'; e.currentTarget.style.background = 'transparent'; }}>+</button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: 10, display: 'flex', flexDirection: 'column', gap: 8 }}>
        {tasks.map(t => <BoardCard key={t.id} task={t}
          onClick={() => onSelect(t.id)}
          selected={selectedId === t.id}
          dragging={draggingId === t.id}
          compact={compact}
          onDragStart={(e) => { e.dataTransfer.setData('text/plain', String(t.id)); e.dataTransfer.effectAllowed = 'move'; onCardDragStart?.(t.id); }}
          onDragEnd={() => onCardDragEnd?.()}
        />)}
        {tasks.length === 0 && (
          <div style={{
            padding: '20px 12px', border: '1.5px dashed rgb(var(--rule-2))',
            color: 'rgb(var(--muted))', fontSize: 12, textAlign: 'center',
            borderRadius: 10, marginTop: 4,
          }}>
            {isOver ? 'Drop here' : 'No tasks yet'}
          </div>
        )}
      </div>
    </div>
  );
}

function BoardCard({ task, onClick, selected, dragging, onDragStart, onDragEnd, compact = false }) {
  const sp = spaceById(task.spaceId);
  if (compact) {
    return (
      <TaskHoverArea task={task}>
        <article onClick={onClick} onDoubleClick={(e) => { e.stopPropagation(); window.__openTaskModal?.(task.id); }} draggable onDragStart={onDragStart} onDragEnd={onDragEnd} data-link style={{
          background: 'rgb(var(--surface))',
          border: selected ? '1.5px solid rgb(var(--accent))' : '1px solid rgb(var(--rule))',
          borderLeft: `3px solid ${sp.colour}`,
          borderRadius: 8,
          padding: '6px 9px',
          display: 'flex', alignItems: 'center', gap: 8,
          cursor: dragging ? 'grabbing' : 'grab',
          opacity: dragging ? 0.4 : 1,
          transition: 'border-color .1s, box-shadow .12s',
          boxShadow: 'var(--sh-sm)',
        }}>
          <PriorityDot p={task.priority} />
          <span style={{
            flex: 1, fontSize: 12.5, fontWeight: 500,
            color: 'rgb(var(--ink))',
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          }}>{task.title}</span>
          {task.assignees.length > 0 && <AvatarStack ids={task.assignees} size={18} max={2} />}
        </article>
      </TaskHoverArea>
    );
  }
  const subs = (task.subtasks || []).length + (task.checklist || []).length;
  const done = (task.subtasks || []).filter(s => s.done).length + (task.checklist || []).filter(c => c.done).length;

  return (
    <article onClick={onClick} onDoubleClick={(e) => { e.stopPropagation(); window.__openTaskModal?.(task.id); }} draggable onDragStart={onDragStart} onDragEnd={onDragEnd} data-link style={{
      background: 'rgb(var(--surface))',
      border: selected ? '1.5px solid rgb(var(--accent))' : '1px solid rgb(var(--rule))',
      borderRadius: 10,
      padding: '11px 12px',
      transition: 'border-color .1s, box-shadow .12s, transform .06s, opacity .1s',
      boxShadow: selected ? '0 0 0 3px rgb(var(--accent) / 0.12), var(--sh-sm)' : 'var(--sh-sm)',
      cursor: dragging ? 'grabbing' : 'grab',
      opacity: dragging ? 0.4 : 1,
    }}
      onMouseEnter={e => { if (!selected && !dragging) e.currentTarget.style.boxShadow = 'var(--sh-md)'; }}
      onMouseLeave={e => { if (!selected) e.currentTarget.style.boxShadow = 'var(--sh-sm)'; }}>

      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ width: 6, height: 6, background: sp.colour, borderRadius: 2 }} />
          <span className="ticket-id">{task.ticket}</span>
        </span>
        <span style={{ flex: 1 }} />
        <PriorityDot p={task.priority} />
        {task.important && <span style={{ color: 'rgb(var(--warm))', fontSize: 12, lineHeight: 1 }}>★</span>}
      </div>

      <h5 style={{
        margin: '0 0 8px',
        fontSize: 13.5, fontWeight: 600, letterSpacing: '-0.01em',
        lineHeight: 1.35,
        color: 'rgb(var(--ink))',
      }}>{task.title}</h5>

      {task.clients.length > 0 && (
        <div style={{ marginBottom: 7, fontSize: 11.5, color: 'rgb(var(--muted))', display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span>◐</span> {task.clients.map(c => clientById(c).name).join(', ')}
        </div>
      )}

      {task.tags.length > 0 && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginBottom: 8 }}>
          {task.tags.map(id => <TagChip key={id} tag={tagById(id)} />)}
        </div>
      )}

      {subs > 0 && (
        <div style={{ marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ flex: 1 }}>
            <ProgressBar value={(done/subs)*100} height={3} colour={done === subs ? 'rgb(var(--forest))' : 'rgb(var(--accent))'} />
          </span>
          <span className="num" style={{ fontSize: 10.5, color: 'rgb(var(--muted))', fontWeight: 500 }}>{done}/{subs}</span>
        </div>
      )}

      <div style={{ display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'space-between', marginTop: 4 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          {task.assignees.length > 0
            ? <AvatarStack ids={task.assignees} max={3} size={22} />
            : <span style={{ fontSize: 10.5, color: 'rgb(var(--muted-2))' }}>unassigned</span>}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {task.comments.length > 0 && <span style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>💬 {task.comments.length}</span>}
          {task.dueDate && <DueChip iso={task.dueDate} />}
        </div>
      </div>
    </article>
  );
}

window.BoardView = BoardView;
