// The three islands: ListsIsland, TasksIsland, DetailsIsland
const { useState, useEffect, useRef, useMemo } = React;

// ---------- Helpers ----------
const fmtDate = (iso) => {
  if (!iso) return null;
  const d = new Date(iso);
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const target = new Date(d.getFullYear(), d.getMonth(), d.getDate());
  const diff = Math.round((target - today) / 86400000);
  if (diff === 0) return 'Today';
  if (diff === 1) return 'Tomorrow';
  if (diff === -1) return 'Yesterday';
  if (diff < 0) return `${Math.abs(diff)}d overdue`;
  if (diff < 7) return d.toLocaleDateString(undefined, { weekday: 'short' });
  return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
};
const isToday = (iso) => {
  if (!iso) return false;
  const d = new Date(iso); const n = new Date();
  return d.getFullYear() === n.getFullYear() && d.getMonth() === n.getMonth() && d.getDate() === n.getDate();
};
const isOverdue = (iso) => {
  if (!iso) return false;
  const d = new Date(iso); const n = new Date();
  return d < new Date(n.getFullYear(), n.getMonth(), n.getDate());
};

const STATUS_LABEL = {
  idle: 'Idle', queued: 'Queued', running: 'Running',
  review: 'Review', done: 'Done', error: 'Error',
};

const relTime = (iso) => {
  if (!iso) return '';
  const diff = Math.max(0, Date.now() - new Date(iso).getTime());
  const s = Math.floor(diff / 1000);
  if (s < 60) return s + 's ago';
  const m = Math.floor(s / 60);
  if (m < 60) return m + 'm ago';
  const h = Math.floor(m / 60);
  if (h < 24) return h + 'h ago';
  return Math.floor(h / 24) + 'd ago';
};

const logTime = (iso) => {
  const d = new Date(iso);
  return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
};

// ---------- Checkbox ----------
const Checkbox = ({ done, onToggle, size }) => (
  <div
    className={`check ${done ? 'done' : ''}`}
    style={size ? { width: size, height: size } : undefined}
    onClick={(e) => { e.stopPropagation(); onToggle(); }}
    role="checkbox"
    aria-checked={done}
  >
    <svg viewBox="0 0 24 24"><path d="M5 12l4.5 4.5L19 7"/></svg>
  </div>
);

// ---------- Lists Island ----------
const ListsIsland = ({ activeList, setActiveList, counts, search, setSearch }) => {
  return (
    <div className="island">
      <div className="island-header">
        <div className="island-eyebrow"><span className="dot"/><span>Navigator</span></div>
        <h2 className="island-title">Lists</h2>
      </div>

      <div className="search-wrap">
        <Icon name="search" size={14} />
        <input
          placeholder="Search tasks…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
        <span className="kbd">⌘K</span>
      </div>

      <div className="island-body">
        <div className="list-section-label">Smart lists</div>
        {SEED_LISTS.map((l) => (
          <div
            key={l.id}
            className={`list-item ${activeList === l.id ? 'active' : ''}`}
            onClick={() => setActiveList(l.id)}
          >
            <div className="icon"><Icon name={l.icon} size={15} /></div>
            <div className="label">{l.name}</div>
            <div className="count">{counts[l.id] ?? ''}</div>
          </div>
        ))}

        <div className="list-section-label">My lists</div>
        {SEED_USER_LISTS.map((l) => (
          <div
            key={l.id}
            className={`list-item ${activeList === l.id ? 'active' : ''}`}
            onClick={() => setActiveList(l.id)}
          >
            <div className="swatch" style={{ background: l.color }} />
            <div className="label">{l.name}</div>
            <div className="count">{counts[l.id] ?? ''}</div>
          </div>
        ))}

        <button className="new-list-btn">
          <Icon name="plus" size={14} />
          <span>New list</span>
        </button>
      </div>

      <div className="island-footer" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 28, height: 28, borderRadius: '50%',
          background: 'linear-gradient(135deg, var(--moss), var(--sage))',
          display: 'grid', placeItems: 'center',
          fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--deep)', fontWeight: 600
        }}>AK</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12, color: 'var(--text)' }}>Aoife Kelly</div>
          <div style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--text-faint)' }}>rider.island / local</div>
        </div>
        <button className="icon-btn" style={{ width: 26, height: 26 }} title="Settings">
          <Icon name="more" size={14} />
        </button>
      </div>
    </div>
  );
};

// ---------- Tasks Island ----------
const TaskRow = ({ task, selected, onSelect, onToggle, onStar, leaving, entering }) => {
  const [starPulse, setStarPulse] = useState(false);
  const handleStar = (e) => {
    e.stopPropagation();
    setStarPulse(true);
    setTimeout(() => setStarPulse(false), 400);
    onStar();
  };
  const list = SEED_USER_LISTS.find((l) => l.id === task.list);
  const overdue = isOverdue(task.due) && !task.done;
  const today = isToday(task.due);

  return (
    <div
      className={`task ${task.done ? 'done' : ''} ${selected ? 'selected' : ''} ${leaving ? 'leaving' : ''} ${entering ? 'entering' : ''}`}
      onClick={onSelect}
    >
      <Checkbox done={task.done} onToggle={onToggle} />
      <div className="task-body">
        <div className="task-title">{task.title}</div>
        <div className="task-meta">
          {task.agent && (
            <span className={`status-chip ${task.agent.status}`}>
              <span className={`status-dot ${task.agent.status}`} />
              {STATUS_LABEL[task.agent.status]}
            </span>
          )}
          {list && (
            <span className="chip" style={{ color: list.color }}>
              <span style={{ width: 6, height: 6, borderRadius: 2, background: list.color, display: 'inline-block' }} />
              {list.name}
            </span>
          )}
          {task.agent?.branch && (
            <span className="chip" title={task.agent.branch}>
              <Icon name="branch" size={10} /> {task.agent.branch.replace('agent/', '')}
            </span>
          )}
          {task.agent?.diff && task.agent.diff.files > 0 && (
            <span className="chip">
              <span className="diff-stats">
                <span className="add">+{task.agent.diff.additions}</span>
                <span className="del">−{task.agent.diff.deletions}</span>
              </span>
            </span>
          )}
          {task.due && !task.agent && (
            <span className={`chip ${overdue ? 'overdue' : today ? 'due-today' : ''}`}>
              <Icon name="calendar" size={10} /> {fmtDate(task.due)}
            </span>
          )}
          {task.subtasks && task.subtasks.length > 0 && (
            <span className="subcount">
              {task.subtasks.filter((s) => s.done).length}/{task.subtasks.length} steps
            </span>
          )}
          {task.tags && task.tags.map((t) => <span key={t} className="tag">{t}</span>)}
        </div>
        {task.agent && task.agent.status === 'running' && task.agent.log && task.agent.log.length > 0 && (() => {
          const last = task.agent.log[task.agent.log.length - 1];
          return (
            <div className="task-agent-line">
              <span className="prompt">›</span>
              <span className="txt">{last.m}</span>
              <span className="mini-cursor" />
            </div>
          );
        })()}
      </div>
      <button
        className={`star-btn ${task.starred ? 'on' : ''} ${starPulse ? 'pulse' : ''}`}
        onClick={handleStar}
        title={task.starred ? 'Unstar' : 'Mark important'}
      >
        <Icon name={task.starred ? 'star-filled' : 'star'} size={15} />
      </button>
    </div>
  );
};

const TasksIsland = ({
  tasks, selectedId, setSelected,
  onToggle, onStar, onAdd,
  leavingIds, enteringIds,
  activeList, showCompleted, setShowCompleted,
}) => {
  const [newTitle, setNewTitle] = useState('');
  const inputRef = useRef(null);

  const now = new Date();
  const dateLine = now.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' });

  const activeTasks = tasks.filter((t) => !t.done);
  const doneTasks = tasks.filter((t) => t.done);
  const overdueTasks = activeTasks.filter((t) => isOverdue(t.due));
  const todayTasks = activeTasks.filter((t) => !isOverdue(t.due));

  const listMeta = SEED_LISTS.find((l) => l.id === activeList) || SEED_USER_LISTS.find((l) => l.id === activeList);
  const title = activeList === 'myday' ? 'My Day' : (listMeta?.name || 'Tasks');
  const eyebrow = activeList === 'myday' ? dateLine : `${activeTasks.length} open · ${doneTasks.length} done`;

  const handleSubmit = (e) => {
    e.preventDefault();
    if (newTitle.trim()) {
      onAdd(newTitle.trim());
      setNewTitle('');
    }
  };

  return (
    <div className="island">
      <div className="tasks-head">
        <div className="tasks-meta">
          <div>
            <div className="tasks-date">{activeList === 'myday' ? 'My Day' : 'List'}</div>
            <h1 className="tasks-title">{title}</h1>
            <div className="tasks-subtitle">
              {activeList === 'myday' ? dateLine : eyebrow}
              <span className="sep">·</span>
              {activeTasks.length} open
            </div>
          </div>
        </div>
        <div className="tasks-actions">
          <button className="icon-btn" title="Sort"><Icon name="sort" size={15} /></button>
          <button className={`icon-btn ${showCompleted ? 'active' : ''}`} onClick={() => setShowCompleted((v) => !v)} title="Show completed">
            <Icon name="eye" size={15} />
          </button>
          <button className="icon-btn" title="More"><Icon name="more" size={15} /></button>
        </div>
      </div>

      <form className="add-task" onSubmit={handleSubmit}>
        <div className="plus">+</div>
        <input
          ref={inputRef}
          placeholder="Add a task…"
          value={newTitle}
          onChange={(e) => setNewTitle(e.target.value)}
        />
        <span className="hint">ENTER</span>
      </form>

      <div className="island-body">
        {overdueTasks.length > 0 && (
          <>
            <div className="tasks-group-label" style={{ color: 'var(--blood)' }}>Overdue</div>
            {overdueTasks.map((t) => (
              <TaskRow
                key={t.id}
                task={t}
                selected={selectedId === t.id}
                onSelect={() => setSelected(t.id)}
                onToggle={() => onToggle(t.id)}
                onStar={() => onStar(t.id)}
                leaving={leavingIds.includes(t.id)}
                entering={enteringIds.includes(t.id)}
              />
            ))}
          </>
        )}

        {todayTasks.length > 0 && (
          <>
            {overdueTasks.length > 0 && <div className="tasks-group-label">Tasks</div>}
            {todayTasks.map((t) => (
              <TaskRow
                key={t.id}
                task={t}
                selected={selectedId === t.id}
                onSelect={() => setSelected(t.id)}
                onToggle={() => onToggle(t.id)}
                onStar={() => onStar(t.id)}
                leaving={leavingIds.includes(t.id)}
                entering={enteringIds.includes(t.id)}
              />
            ))}
          </>
        )}

        {activeTasks.length === 0 && (
          <div style={{ padding: '40px 24px', textAlign: 'center', color: 'var(--text-faint)' }}>
            <div style={{ fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase' }}>
              All clear
            </div>
            <div style={{ fontSize: 12, marginTop: 6 }}>The harbor is calm. Add a task above.</div>
          </div>
        )}

        {showCompleted && doneTasks.length > 0 && (
          <>
            <div className="tasks-group-label">Completed · {doneTasks.length}</div>
            {doneTasks.map((t) => (
              <TaskRow
                key={t.id}
                task={t}
                selected={selectedId === t.id}
                onSelect={() => setSelected(t.id)}
                onToggle={() => onToggle(t.id)}
                onStar={() => onStar(t.id)}
                leaving={leavingIds.includes(t.id)}
                entering={enteringIds.includes(t.id)}
              />
            ))}
          </>
        )}
      </div>
    </div>
  );
};

// ---------- Worktree + Terminal sub-components ----------
const WorktreeCard = ({ agent, onOpenDiff, onOpenWorktree }) => {
  if (!agent) return null;
  return (
    <div className="worktree-card">
      <div className="row">
        <span className="k">Worktree</span>
        <span className="v path" title={agent.worktree}>{agent.worktree}</span>
        <button className="copy-btn" title="Copy path"><Icon name="copy" size={12} /></button>
      </div>
      <div className="row">
        <span className="k">Branch</span>
        <span className="v">
          <span className="branch"><Icon name="branch" size={11} /> {agent.branch}</span>
          <span style={{ color: 'var(--text-faint)', marginLeft: 8 }}>← {agent.baseBranch}</span>
        </span>
      </div>
      <div className="row">
        <span className="k">Diff</span>
        <span className="v">
          {agent.diff.files > 0 ? (
            <span className="diff-stats">
              <span>{agent.diff.files} files</span>
              <span className="add">+{agent.diff.additions}</span>
              <span className="del">−{agent.diff.deletions}</span>
              <span className="bars">
                {Array.from({ length: 5 }).map((_, i) => {
                  const total = agent.diff.additions + agent.diff.deletions || 1;
                  const addShare = Math.round((agent.diff.additions / total) * 5);
                  return <span key={i} className={i < addShare ? 'add' : 'del'} />;
                })}
              </span>
            </span>
          ) : <span style={{ color: 'var(--text-faint)' }}>No changes yet</span>}
        </span>
      </div>
      {agent.commits > 0 && (
        <div className="row">
          <span className="k">Commits</span>
          <span className="v">{agent.commits} on branch</span>
        </div>
      )}
      <div className="action-row">
        <button className="btn primary grow" onClick={onOpenDiff} disabled={agent.diff.files === 0}>
          <Icon name="diff" size={12} /> Open diff
        </button>
        <button className="btn" onClick={onOpenWorktree} title="Open worktree folder">
          <Icon name="folder-open" size={12} /> Worktree
        </button>
        <button className="btn icon-only" title="Open in editor">
          <Icon name="external" size={12} />
        </button>
      </div>
    </div>
  );
};

const SessionTerminal = ({ agent, onInput }) => {
  const bodyRef = useRef(null);
  const [draft, setDraft] = useState('');

  useEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [agent?.log?.length]);

  if (!agent) return null;
  const running = agent.status === 'running';
  const statusLabel = running ? 'LIVE' : STATUS_LABEL[agent.status];

  return (
    <div className="terminal">
      <div className="terminal-head">
        <div className="dots"><span className="r"/><span className="y"/><span className="g"/></div>
        <span className="lbl">claude-session · {agent.branch}</span>
        {running
          ? <span className="live"><span className="d"/>LIVE</span>
          : <span className="live" style={{ color: 'var(--text-faint)' }}>{statusLabel}</span>}
      </div>
      <div className="terminal-body" ref={bodyRef}>
        {(agent.log || []).map((l, i) => (
          <div key={i} className={`log-line ${l.k}`}>
            <span className="ts">{logTime(l.t)}</span>
            <span className="tag">{l.k === 'msg' ? 'claude' : l.k === 'tool' ? 'tool' : l.k === 'sys' ? 'sys' : l.k === 'stdout' ? 'out' : l.k === 'stderr' ? 'err' : l.k}</span>
            <span className="m">{l.m}</span>
          </div>
        ))}
        {running && (
          <div className="log-line msg">
            <span className="ts">{logTime(new Date().toISOString())}</span>
            <span className="tag">claude</span>
            <span className="m"><span className="cursor-block"/></span>
          </div>
        )}
      </div>
      <div style={{ display: 'flex', gap: 6, padding: '8px 10px', borderTop: '1px solid var(--line)', background: 'var(--surface-2)' }}>
        <span style={{ fontFamily: 'var(--mono)', color: 'var(--accent)', fontSize: 11, alignSelf: 'center' }}>›</span>
        <input
          placeholder={running ? 'Send a message to the agent…' : 'Agent not running'}
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={(e) => { if (e.key === 'Enter' && draft.trim()) { onInput(draft); setDraft(''); } }}
          disabled={!running}
          style={{ flex: 1, fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text)' }}
        />
        <button className="btn icon-only" disabled={!draft.trim()}><Icon name="send" size={12} /></button>
      </div>
    </div>
  );
};

// ---------- Details Island ----------
const DetailsIsland = ({ task, onUpdate, onDelete, onToggle, onStar, onAgentAction, onOpenDiff, onOpenWorktree, onAgentInput }) => {
  if (!task) {
    return (
      <div className="island">
        <div className="details-empty">
          <div>
            <div className="glyph"><Icon name="note" size={22} /></div>
            <div className="label">No task selected</div>
            <div className="hint">Pick a task from the middle<br/>to see its details here.</div>
          </div>
        </div>
      </div>
    );
  }

  const list = SEED_USER_LISTS.find((l) => l.id === task.list);
  const created = task.created ? new Date(task.created).toLocaleDateString(undefined, { month: 'short', day: 'numeric' }) : '—';
  const due = task.due ? new Date(task.due).toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' }) : 'None';

  const toggleSub = (sid) => {
    const next = task.subtasks.map((s) => s.id === sid ? { ...s, done: !s.done } : s);
    onUpdate({ ...task, subtasks: next });
  };
  const addSub = (title) => {
    if (!title.trim()) return;
    const next = [...(task.subtasks || []), { id: 's' + Date.now(), title: title.trim(), done: false }];
    onUpdate({ ...task, subtasks: next });
  };
  const [subDraft, setSubDraft] = useState('');

  return (
    <div className="island">
      <div className="island-header" style={{ paddingBottom: 10 }}>
        <div className="island-eyebrow">
          <span className="dot" />
          <span>Logbook</span>
          <span style={{ marginLeft: 'auto', color: 'var(--text-faint)' }}>#{task.id}</span>
        </div>
        <h2 className="island-title" style={{ fontSize: 14, fontWeight: 500, color: 'var(--text-dim)' }}>
          {task.agent ? 'Agent task' : 'Task details'}
        </h2>
      </div>

      {task.agent && (
        <div className="agent-strip">
          <span className={`status-chip ${task.agent.status}`}>
            <span className={`status-dot ${task.agent.status}`} />
            {STATUS_LABEL[task.agent.status]}
          </span>
          <div className="meta">
            <Icon name="cpu" size={10} /> {task.agent.model}
            <span className="sep">·</span>
            {task.agent.turns} turns
            <span className="sep">·</span>
            {(task.agent.tokens / 1000).toFixed(1)}k tok
            {task.agent.startedAt && <><span className="sep">·</span>{relTime(task.agent.startedAt)}</>}
          </div>
          {task.agent.status === 'running' ? (
            <button className="btn danger icon-only" onClick={() => onAgentAction(task.id, 'stop')} title="Stop agent"><Icon name="stop" size={12} /></button>
          ) : task.agent.status === 'idle' || task.agent.status === 'error' || task.agent.status === 'queued' ? (
            <button className="btn primary" onClick={() => onAgentAction(task.id, 'start')}><Icon name="play" size={12} /> {task.agent.status === 'error' ? 'Retry' : 'Dispatch'}</button>
          ) : null}
        </div>
      )}

      <div className="island-body">
        <div className="details-title-row">
          <Checkbox done={task.done} onToggle={() => onToggle(task.id)} />
          <textarea
            className="details-title"
            value={task.title}
            onChange={(e) => onUpdate({ ...task, title: e.target.value })}
            rows={2}
          />
          <button
            className={`star-btn ${task.starred ? 'on' : ''}`}
            style={{ opacity: 1 }}
            onClick={() => onStar(task.id)}
          >
            <Icon name={task.starred ? 'star-filled' : 'star'} size={16} />
          </button>
        </div>

        {task.agent && (
          <div className="details-section">
            <div className="details-section-label">Worktree</div>
            <WorktreeCard
              agent={task.agent}
              onOpenDiff={() => onOpenDiff(task.id)}
              onOpenWorktree={() => onOpenWorktree(task.id)}
            />
          </div>
        )}

        {task.agent && (
          <div className="details-section">
            <div className="details-section-label">
              Session output
              <span style={{ marginLeft: 'auto', float: 'right', color: 'var(--text-mute)', fontFamily: 'var(--mono)', fontSize: 10 }}>
                {(task.agent.log || []).length} lines
              </span>
            </div>
            <SessionTerminal
              agent={task.agent}
              onInput={(msg) => onAgentInput(task.id, msg)}
            />
          </div>
        )}

        {(task.subtasks || []).length > 0 && (
          <div className="details-section">
            <div className="details-section-label">Steps · {task.subtasks.filter(s => s.done).length}/{task.subtasks.length}</div>
            {task.subtasks.map((s) => (
              <div key={s.id} className={`subtask-row ${s.done ? 'done' : ''}`}>
                <Checkbox done={s.done} onToggle={() => toggleSub(s.id)} />
                <div className="label">{s.title}</div>
              </div>
            ))}
            <div className="subtask-add">
              <div className="check" style={{ width: 16, height: 16, borderStyle: 'dashed' }} />
              <input
                placeholder="Add step"
                value={subDraft}
                onChange={(e) => setSubDraft(e.target.value)}
                onKeyDown={(e) => { if (e.key === 'Enter') { addSub(subDraft); setSubDraft(''); } }}
              />
            </div>
          </div>
        )}

        <div className="details-section">
          <div className="meta-row">
            <span className="key">List</span>
            <span className="val" style={{ color: list?.color || 'var(--text)' }}>
              {list ? list.name : '—'}
            </span>
          </div>
          <div className="meta-row">
            <span className="key">Due</span>
            <span className={`val ${isOverdue(task.due) && !task.done ? 'peat' : isToday(task.due) ? 'accent' : 'muted'}`}>{due}</span>
          </div>
          {!task.agent && (
            <div className="meta-row">
              <span className="key">Reminder</span>
              <span className="val muted">{task.reminder || 'None'}</span>
            </div>
          )}
          <div className="meta-row">
            <span className="key">Important</span>
            <span className={`val ${task.starred ? 'peat' : 'muted'}`}>{task.starred ? 'Starred' : 'No'}</span>
          </div>
        </div>

        <div className="details-section">
          <div className="details-section-label">Notes</div>
          <textarea
            className="notes-area"
            placeholder="Add a note for the agent…"
            value={task.notes || ''}
            onChange={(e) => onUpdate({ ...task, notes: e.target.value })}
          />
        </div>

        {(task.tags || []).length > 0 && (
          <div className="details-section" style={{ borderBottom: 0 }}>
            <div className="details-section-label">Tags</div>
            <div>
              {task.tags.map((t) => <span key={t} className="tag-chip">{t}</span>)}
              <span className="tag-chip" style={{ borderStyle: 'dashed', cursor: 'pointer' }}>+ add</span>
            </div>
          </div>
        )}
      </div>

      <div className="island-footer" style={{ display: 'flex', gap: 8, justifyContent: 'space-between' }}>
        <button className="icon-btn" title="Delete" onClick={() => onDelete(task.id)}>
          <Icon name="trash" size={14} />
        </button>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--text-faint)', alignSelf: 'center' }}>
          Created {created}
        </div>
        <button className="icon-btn" title="Close">
          <Icon name="x" size={14} />
        </button>
      </div>
    </div>
  );
};

window.ListsIsland = ListsIsland;
window.TasksIsland = TasksIsland;
window.DetailsIsland = DetailsIsland;
