// list.jsx — message list with filter bar, search, unread cursor

function FilterBar({ theme, filters, active, onChange, search, onSearch }) {
  return (
    <div style={{
      borderBottom: `1px solid ${theme.border}`,
      background: theme.bg,
    }}>
      {/* search */}
      <div style={{
        padding: '10px 14px',
        display: 'flex', alignItems: 'center', gap: 8,
        fontFamily: theme.mono,
      }}>
        <span style={{ color: theme.textFaint, fontSize: 12 }}>$</span>
        <input
          value={search}
          onChange={(e) => onSearch(e.target.value)}
          placeholder="grep subject, sender, body…"
          style={{
            all: 'unset', flex: 1,
            fontFamily: theme.mono, fontSize: 12,
            color: theme.text,
          }}
        />
        {search && (
          <button
            onClick={() => onSearch('')}
            style={{
              all: 'unset', cursor: 'pointer',
              fontFamily: theme.mono, fontSize: 11,
              color: theme.textFaint, padding: '2px 6px',
              border: `1px solid ${theme.border}`,
            }}
          >esc</button>
        )}
      </div>
      {/* filter chips */}
      <div style={{
        display: 'flex', gap: 0,
        borderTop: `1px solid ${theme.border}`,
      }}>
        {filters.map((f) => {
          const isActive = active === f.id;
          return (
            <button
              key={f.id}
              onClick={() => onChange(f.id)}
              style={{
                all: 'unset', cursor: 'pointer',
                flex: 1,
                padding: '8px 10px',
                textAlign: 'center',
                fontFamily: theme.mono, fontSize: 11,
                color: isActive ? theme.text : theme.textDim,
                background: isActive ? theme.bg3 : 'transparent',
                borderRight: `1px solid ${theme.border}`,
                letterSpacing: '0.02em',
                position: 'relative',
              }}
            >
              {f.label}
              {f.count != null && (
                <span style={{
                  marginLeft: 6,
                  color: isActive ? theme.textDim : theme.textFaint,
                  fontVariantNumeric: 'tabular-nums',
                }}>{f.count}</span>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

function LabelTag({ theme, label }) {
  const color = theme.label[label.id] || theme.textDim;
  return (
    <span style={{
      fontFamily: theme.mono, fontSize: 10,
      color,
      letterSpacing: '0.02em',
    }}>[{label.label}]</span>
  );
}

function MessageRow({ theme, thread, selected, onSelect, density, accounts, labels, previewLines }) {
  const account = accounts.find(a => a.id === thread.account);
  const last = thread.messages[thread.messages.length - 1];
  const threadLabels = thread.labels.map(id => labels.find(l => l.id === id)).filter(Boolean);
  const unread = thread.unread;
  const count = thread.messages.length;

  return (
    <button
      onClick={onSelect}
      style={{
        all: 'unset', cursor: 'pointer',
        width: '100%', boxSizing: 'border-box',
        padding: `${density.pad}px 14px`,
        display: 'flex', alignItems: 'flex-start', gap: 10,
        background: selected ? theme.bg3 : 'transparent',
        borderLeft: `2px solid ${selected ? theme.text : 'transparent'}`,
        borderBottom: `1px solid ${theme.border}`,
        fontFamily: theme.mono,
        minHeight: density.row,
      }}
    >
      {/* left gutter: account color + cursor */}
      <div style={{
        width: 10, display: 'flex', flexDirection: 'column',
        alignItems: 'center', paddingTop: 3, gap: 4, flexShrink: 0,
      }}>
        <div style={{
          width: 4, height: 4,
          background: `oklch(0.72 0.14 ${account.hue})`,
        }} />
        {unread && (
          <div style={{
            width: 4, height: 4, background: theme.accent2,
          }} />
        )}
      </div>

      {/* main */}
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: density.gap }}>
        {/* line 1: sender + date */}
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 8,
        }}>
          <div style={{
            flex: 1, minWidth: 0,
            fontSize: 12,
            fontWeight: unread ? 700 : 400,
            color: unread ? theme.text : theme.textDim,
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          }}>
            {last.from}
            {count > 1 && (
              <span style={{ color: theme.textFaint, fontWeight: 400 }}> ·{count}</span>
            )}
          </div>
          <div style={{
            fontSize: 10, color: theme.textFaint,
            fontVariantNumeric: 'tabular-nums',
          }}>{last.time}</div>
        </div>

        {/* line 2: subject */}
        <div style={{
          fontSize: 12,
          color: unread ? theme.text : theme.textDim,
          fontWeight: unread ? 500 : 400,
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          {thread.starred && (
            <span style={{ color: theme.accent2, fontSize: 11, flexShrink: 0 }}>★</span>
          )}
          {thread.attachments > 0 && (
            <span style={{ color: theme.textFaint, fontSize: 10, flexShrink: 0 }}>
              ◫{thread.attachments}
            </span>
          )}
          <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {thread.subject}
          </span>
        </div>

        {/* preview */}
        {previewLines > 0 && (
          <div style={{
            fontSize: 11, color: theme.textFaint,
            overflow: 'hidden', textOverflow: 'ellipsis',
            display: '-webkit-box', WebkitLineClamp: previewLines, WebkitBoxOrient: 'vertical',
            lineHeight: 1.4,
          }}>
            {last.body.filter(l => l).slice(0, 3).join(' ')}
          </div>
        )}

        {/* labels */}
        {threadLabels.length > 0 && (
          <div style={{ display: 'flex', gap: 6, marginTop: 2 }}>
            {threadLabels.map(l => <LabelTag key={l.id} theme={theme} label={l} />)}
          </div>
        )}
      </div>
    </button>
  );
}

function MessageList({ theme, threads, selectedId, onSelect, density, accounts, labels, filters, activeFilter, onFilter, search, onSearch, previewLines }) {
  return (
    <div style={{
      flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0,
      background: theme.bg,
      borderRight: `1px solid ${theme.border}`,
      paddingTop: 32, // traffic lights clearance
    }}>
      <FilterBar
        theme={theme}
        filters={filters}
        active={activeFilter}
        onChange={onFilter}
        search={search}
        onSearch={onSearch}
      />
      <div style={{ flex: 1, overflowY: 'auto' }}>
        {threads.length === 0 ? (
          <div style={{
            padding: 40, textAlign: 'center',
            fontFamily: theme.mono, fontSize: 12,
            color: theme.textFaint,
          }}>
            // no messages
          </div>
        ) : threads.map(t => (
          <MessageRow
            key={t.id}
            theme={theme}
            thread={t}
            selected={selectedId === t.id}
            onSelect={() => onSelect(t.id)}
            density={density}
            accounts={accounts}
            labels={labels}
            previewLines={previewLines}
          />
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { MessageList, LabelTag });
