/* Main task list view — modern, friendly, scannable */

function ListView({ tasks, selectedId, onSelect, groupBy = 'status', onQuickAdd, hero, actions = {}, compact = false }) {

  const groups = React.useMemo(() => {
    if (groupBy === 'status') {
      return D.statuses.map(s => ({
        key: 'st-' + s.id,
        title: s.title,
        colour: s.colour,
        tasks: tasks.filter(t => t.statusId === s.id),
      })).filter(g => g.tasks.length > 0);
    }
    if (groupBy === 'space') {
      return D.spaces.map(sp => ({
        key: 'sp-' + sp.id,
        title: sp.name,
        colour: sp.colour,
        tasks: tasks.filter(t => t.spaceId === sp.id),
      })).filter(g => g.tasks.length > 0);
    }
    if (groupBy === 'priority') {
      const order = [['urgent','Urgent', '#EF4444'],['high','High','#F97316'],['medium','Medium','#F59E0B'],['low','Low','#94A3B8']];
      return order.map(([p, label, c]) => ({
        key: 'p-' + p, title: label, colour: c,
        tasks: tasks.filter(t => t.priority === p),
      })).filter(g => g.tasks.length > 0);
    }
    return [{ key: 'all', title: 'All tasks', colour: 'rgb(var(--accent))', tasks }];
  }, [tasks, groupBy]);

  const [collapsed, setCollapsed] = React.useState({});

  return (
    <div style={{ flex: 1, overflowY: 'auto', background: 'rgb(var(--bg))', padding: '14px 20px 60px' }}>
      {hero}
      {groups.map(g => {
        const isCollapsed = collapsed[g.key];
        return (
          <section key={g.key} style={{ marginBottom: 14 }}>
            {/* Group header */}
            <div style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '8px 12px',
              borderRadius: 10,
              marginBottom: 6,
              cursor: 'pointer',
            }}
              onClick={() => setCollapsed(c => ({ ...c, [g.key]: !c[g.key] }))}
              onMouseEnter={e => e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.6)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
            >
              <span style={{
                fontSize: 10, color: 'rgb(var(--muted))',
                transform: isCollapsed ? 'rotate(-90deg)' : 'none',
                transition: 'transform .15s',
                width: 10, display: 'inline-block', textAlign: 'center',
              }}>▾</span>
              <span style={{ width: 10, height: 10, background: g.colour, borderRadius: 3 }} />
              <h3 style={{ margin: 0, fontSize: 14, fontWeight: 700, color: 'rgb(var(--ink))', letterSpacing: '-0.01em' }}>{g.title}</h3>
              <span className="num" style={{
                fontSize: 11, fontWeight: 600, padding: '2px 8px',
                background: 'rgb(var(--paper-2))', color: 'rgb(var(--muted))',
                borderRadius: 999,
              }}>{g.tasks.length}</span>
              <span style={{ flex: 1 }} />
            </div>

            {/* Task rows */}
            {!isCollapsed && (
              <>
                <div style={{
                  background: 'rgb(var(--surface))',
                  border: '1px solid rgb(var(--rule))',
                  borderRadius: 12,
                  overflow: 'hidden',
                  boxShadow: 'var(--sh-sm)',
                  marginBottom: 8,
                }}>
                  {g.tasks.map((t, i) => (
                    <TaskRow key={t.id} task={t}
                      selected={t.id === selectedId}
                      onClick={() => onSelect(t.id)}
                      last={i === g.tasks.length - 1}
                      actions={actions}
                      compact={compact}
                    />
                  ))}
                </div>
                {onQuickAdd && groupBy === 'status' && g.key.startsWith('st-') && (
                  <QuickAddRow
                    placeholder={`Add a task to ${g.title}…`}
                    onAdd={(title) => onQuickAdd(title, { statusId: parseInt(g.key.slice(3), 10) })}
                  />
                )}
              </>
            )}
          </section>
        );
      })}

      {tasks.length === 0 && (
        <EmptyState />
      )}
    </div>
  );
}

function EmptyState() {
  return (
    <div style={{
      margin: '40px auto', maxWidth: 480, textAlign: 'center',
      padding: '40px 24px',
      background: 'rgb(var(--surface))',
      border: '1px solid rgb(var(--rule))',
      borderRadius: 16,
      boxShadow: 'var(--sh-sm)',
    }}>
      <div style={{
        width: 64, height: 64, margin: '0 auto 14px',
        background: 'linear-gradient(135deg, rgb(var(--accent-soft)), rgb(var(--forest-soft)))',
        borderRadius: '50%',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 30,
      }}>🌤</div>
      <h3 style={{ margin: 0, fontSize: 18, fontWeight: 700, color: 'rgb(var(--ink))', letterSpacing: '-0.02em' }}>Inbox zero.</h3>
      <p style={{ margin: '6px 0 0', fontSize: 13.5, color: 'rgb(var(--muted))', lineHeight: 1.55 }}>
        Nothing matches your current filters.<br />Want to plan tomorrow, or clear filters and see everything?
      </p>
      <div style={{ marginTop: 16, display: 'flex', gap: 8, justifyContent: 'center' }}>
        <button className="btn btn-secondary" style={{ fontSize: 12 }}>Clear filters</button>
        <button className="btn btn-accent" style={{ fontSize: 12 }}>+ Plan tomorrow</button>
      </div>
    </div>
  );
}

function TaskRowCompact({ task, selected, onClick, last, actions = {} }) {
  const sp = spaceById(task.spaceId);
  const st = statusById(task.statusId);
  const done = task.statusId === 6;
  const inBulk = actions.selectedSet?.has(task.id);

  return (
    <TaskHoverArea task={task}>
      <article data-link
        onClick={() => onClick()}
        onDoubleClick={(e) => { e.stopPropagation(); actions.onOpenModal?.(task.id); }}
        style={{
          display: 'grid',
          gridTemplateColumns: '24px 18px 1fr auto auto auto',
          gap: 10, alignItems: 'center',
          padding: '6px 14px',
          borderBottom: last ? 'none' : '1px solid rgb(var(--rule) / 0.6)',
          background: inBulk ? 'rgb(var(--accent-soft) / 0.6)' : selected ? 'rgb(var(--accent-soft) / 0.4)' : 'transparent',
          cursor: 'pointer',
          transition: 'background-color .12s',
        }}
        onMouseEnter={e => { if (!selected && !inBulk) e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.4)'; }}
        onMouseLeave={e => { if (!selected && !inBulk) e.currentTarget.style.background = 'transparent'; }}>
        <span style={{ display: 'flex', justifyContent: 'center' }}>
          <Checkbox checked={done} onClick={(e) => { e.stopPropagation(); actions.onStatusChange?.(task.id, done ? 1 : 6); }} />
        </span>
        <PriorityDot p={task.priority} />
        <span style={{
          fontSize: 13, fontWeight: 500,
          color: done ? 'rgb(var(--muted))' : 'rgb(var(--ink))',
          textDecoration: done ? 'line-through' : 'none',
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
        }}>{task.title}</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 10.5, color: sp.colour, fontWeight: 600 }}>
          <span style={{ width: 5, height: 5, background: sp.colour, borderRadius: 2 }} />{sp.prefix}
        </span>
        <span className="pip" style={{ background: st.colour, width: 6, height: 6 }} title={st.title} />
        {task.dueDate ? <DueChip iso={task.dueDate} /> : <span style={{ fontSize: 11, color: 'rgb(var(--muted-2))', fontFamily: 'JetBrains Mono, monospace' }}>—</span>}
      </article>
    </TaskHoverArea>
  );
}

function TaskRow({ task, selected, onClick, last, actions = {}, compact = false }) {
  if (compact) return <TaskRowCompact task={task} selected={selected} onClick={onClick} last={last} actions={actions} />;
  const sp = spaceById(task.spaceId);
  const subs = task.subtasks || [];
  const checks = task.checklist || [];
  const subsDone = subs.filter(s => s.done).length;
  const checksDone = checks.filter(c => c.done).length;
  const totalSubItems = subs.length + checks.length;
  const doneSubItems = subsDone + checksDone;
  const progress = totalSubItems ? (doneSubItems / totalSubItems) * 100 : 0;
  const inBulk = actions.selectedSet?.has(task.id);
  const bulkMode = (actions.selectedSet?.size || 0) > 0;

  return (
    <article
      data-link
      onClick={(e) => {
        if (bulkMode) {
          e.stopPropagation();
          actions.onBulkToggle?.(task.id, e.shiftKey);
        } else {
          onClick();
        }
      }}
      onDoubleClick={(e) => {
        if (bulkMode) return;
        e.stopPropagation();
        actions.onOpenModal?.(task.id);
      }}
      title="Double-click to open as modal"
      style={{
        display: 'grid',
        gridTemplateColumns: '36px 26px 1fr auto',
        gap: 0,
        padding: '12px 16px 12px 0',
        borderBottom: last ? 'none' : '1px solid rgb(var(--rule) / 0.7)',
        background: inBulk ? 'rgb(var(--accent-soft) / 0.6)' : selected ? 'rgb(var(--accent-soft) / 0.4)' : 'transparent',
        cursor: 'pointer',
        transition: 'background-color .12s',
        position: 'relative',
      }}
      onMouseEnter={e => { if (!selected && !inBulk) e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.5)'; }}
      onMouseLeave={e => { if (!selected && !inBulk) e.currentTarget.style.background = 'transparent'; }}
    >
      {/* selection accent bar */}
      <div style={{
        background: inBulk ? 'rgb(var(--accent))' : selected ? 'rgb(var(--accent))' : 'transparent',
        marginRight: 16, width: 3,
      }} />

      {/* selection / complete column */}
      <div className="row-leading" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: 3 }}>
        <RowLeading task={task} inBulk={inBulk} bulkMode={bulkMode} actions={actions} />
      </div>

      {/* main */}
      <div style={{ minWidth: 0, paddingRight: 16 }}>
        {/* line 1 — ticket, type, space */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 5 }}>
          <span className="ticket-id">{task.ticket}</span>
          <Sep />
          <TypeBadge type={task.type} />
          <Sep />
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
            <span style={{ width: 6, height: 6, background: sp.colour, borderRadius: 2 }} />
            <span style={{ fontSize: 11, fontWeight: 600, color: 'rgb(var(--ink-2))' }}>{sp.name}</span>
          </span>
          {task.queueId && (() => {
            const q = queueById(task.queueId);
            if (!q) return null;
            return (
              <>
                <Sep />
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 10.5, fontWeight: 600, color: q.colour, padding: '1px 7px', background: q.colour + '12', borderRadius: 999 }}>
                  <span style={{ width: 5, height: 5, background: q.colour, borderRadius: '50%' }} />{q.name}
                </span>
              </>
            );
          })()}
          {task.important && <span style={{ color: 'rgb(var(--warm))', fontSize: 12 }} title="Important">★</span>}
          {task.myDay && (
            <span style={{
              fontSize: 10, fontWeight: 600,
              color: 'rgb(var(--warm))', background: 'rgb(var(--warm-soft))',
              padding: '1px 7px', borderRadius: 999,
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}>☀ My Day</span>
          )}
        </div>

        {/* line 2 — title (inline-editable) */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
          <InlinePriority priority={task.priority} onChange={(p) => actions.onUpdatePriority?.(task.id, p)} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <InlineTitle
              value={task.title}
              done={task.statusId === 6}
              onSave={(v) => actions.onUpdateTitle?.(task.id, v)}
            />
          </div>
        </div>

        {/* line 3 — meta */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
          <InlineStatus statusId={task.statusId} onChange={(id) => actions.onStatusChange?.(task.id, id)} />

          {task.clients.length > 0 && (
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              fontSize: 11.5, color: 'rgb(var(--ink-2))',
              padding: '2px 8px', background: 'rgb(var(--paper-2))',
              borderRadius: 999,
            }}>
              <span style={{ fontSize: 9, color: 'rgb(var(--muted))' }}>◐</span>
              <span style={{ fontWeight: 500 }}>{task.clients.map(c => clientById(c).name).join(', ')}</span>
            </span>
          )}

          {task.tags.length > 0 && task.tags.map(id => <TagChip key={id} tag={tagById(id)} />)}

          {totalSubItems > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
              <span style={{ width: 50 }}>
                <ProgressBar value={progress} height={4} colour={progress === 100 ? 'rgb(var(--forest))' : 'rgb(var(--accent))'} />
              </span>
              <span className="num" style={{ fontSize: 11, color: 'rgb(var(--muted))', fontWeight: 500 }}>{doneSubItems}/{totalSubItems}</span>
            </span>
          )}

          {task.comments.length > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, fontSize: 11, color: 'rgb(var(--muted))' }}>
              💬 {task.comments.length}
            </span>
          )}
          {task.attachments.length > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, fontSize: 11, color: 'rgb(var(--muted))' }}>
              📎 {task.attachments.length}
            </span>
          )}
        </div>
      </div>

      {/* right column */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 16,
        paddingRight: 4,
      }}>
        <div style={{ minHeight: 24 }}>
          {task.assignees.length > 0
            ? <span onClick={(e) => { e.stopPropagation(); actions.onPersonClick?.(task.assignees[0]); }}><AvatarStack ids={task.assignees} size={24} /></span>
            : <span style={{ fontSize: 11, color: 'rgb(var(--muted-2))' }}>unassigned</span>}
        </div>
        <div style={{ textAlign: 'right', minWidth: 130 }}>
          <InlineDue iso={task.dueDate} onChange={(iso) => actions.onReschedule?.(task.id, iso)} />
          {task.estimateMins > 0 && (
            <div style={{ marginTop: 3, fontSize: 10.5, color: 'rgb(var(--muted))', fontFamily: 'JetBrains Mono, monospace' }}>
              {fmtMins(task.estimateMins)}{task.actualMins > 0 ? ` · ${fmtMins(task.actualMins)}` : ''}
            </div>
          )}
        </div>
      </div>
    </article>
  );
}

function RowLeading({ task, inBulk, bulkMode, actions }) {
  // In bulk mode, always show the bulk checkbox. Otherwise: hover shows bulk checkbox, complete shows the done checkbox.
  const done = task.statusId === 6;
  if (bulkMode) {
    return (
      <span onClick={(e) => { e.stopPropagation(); actions.onBulkToggle?.(task.id, e.shiftKey); }} style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: 18, height: 18, borderRadius: 5,
        background: inBulk ? 'rgb(var(--accent))' : 'rgb(var(--surface))',
        border: '1.5px solid ' + (inBulk ? 'rgb(var(--accent))' : 'rgb(var(--rule-2))'),
        cursor: 'pointer',
      }}>
        {inBulk && <span style={{ color: 'white', fontSize: 11, lineHeight: 1, fontWeight: 700 }}>✓</span>}
      </span>
    );
  }
  return (
    <span style={{ position: 'relative' }} className="row-leading-inner">
      <Checkbox checked={done} onClick={(e) => { e.stopPropagation(); actions.onStatusChange?.(task.id, done ? 1 : 6); }} />
      <button
        onClick={(e) => { e.stopPropagation(); actions.onBulkToggle?.(task.id, e.shiftKey); }}
        title="Select for bulk action"
        style={{
          position: 'absolute', inset: 0, opacity: 0,
          transition: 'opacity .14s',
        }}
        onMouseEnter={e => e.currentTarget.style.opacity = '1'}
        onMouseLeave={e => e.currentTarget.style.opacity = '0'}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          width: 18, height: 18, borderRadius: 5,
          background: 'rgb(var(--surface))',
          border: '1.5px dashed rgb(var(--accent))',
          color: 'rgb(var(--accent))', fontSize: 9, fontWeight: 700,
        }}>+</span>
      </button>
    </span>
  );
}

function Checkbox({ checked, onClick }) {
  return (
    <span onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: 18, height: 18, borderRadius: 6,
      background: checked ? 'rgb(var(--forest))' : 'rgb(var(--surface))',
      border: '1.5px solid ' + (checked ? 'rgb(var(--forest))' : 'rgb(var(--rule-2))'),
      cursor: 'pointer',
      transition: 'all .12s',
    }}>
      {checked && <span style={{ color: 'white', fontSize: 11, lineHeight: 1, fontWeight: 700 }}>✓</span>}
    </span>
  );
}

function Sep() {
  return <span style={{ width: 3, height: 3, background: 'rgb(var(--rule-2))', borderRadius: '50%' }} />;
}

window.ListView = ListView;
window.Checkbox = Checkbox;
