import { useState, useEffect } from "react";
import { Plus, ChevronDown, ChevronRight } from "lucide-react";
import { COLORS, FONT, STATE_COLOR } from "./theme";
import type { Group, WorkspaceView, SurfaceState } from "./layoutTypes";
import type { DaemonHealth } from "./socketBridge";

function fmtUptime(startedMs: number): string {
  const s = Math.max(0, Math.floor((Date.now() - startedMs) / 1000));
  if (s < 60) return `${s}s`;
  if (s < 3600) return `${Math.floor(s / 60)}m`;
  if (s < 86400) return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
  return `${Math.floor(s / 86400)}d ${Math.floor((s % 86400) / 3600)}h`;
}

function aggregate(w: WorkspaceView): SurfaceState | "stopped" {
  const order: SurfaceState[] = ["error", "wait", "work", "done", "idle"];
  const running = Object.values(w.surfaces).filter((s) => s.running);
  if (running.length === 0) return "stopped";
  for (const st of order) {
    if (running.some((s) => s.state === st)) return st;
  }
  return "idle";
}

export function Sidebar({
  groups, workspaces, activeId, onSelect, onNew, health, connected,
}: {
  groups: Group[];
  workspaces: WorkspaceView[];
  activeId: string | null;
  onSelect: (id: string) => void;
  onNew: () => void;
  health: DaemonHealth | null;
  connected: boolean;
}) {
  const [collapsed, setCollapsed] = useState<Record<string, boolean>>({});
  const [, setTick] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setTick((n) => n + 1), 30000);
    return () => clearInterval(t);
  }, []);
  const byGroup = (gid: string | null) => workspaces.filter((w) => (w.group_id ?? null) === gid).sort((a, b) => a.order - b.order);
  const ungrouped = byGroup(null);

  const row = (w: WorkspaceView) => {
    const isActive = w.id === activeId;
    return (
      <div key={w.id} onClick={() => onSelect(w.id)}
        style={{
          display: "flex", alignItems: "center", gap: 10, height: 34, padding: "0 8px", borderRadius: 6, cursor: "pointer",
          background: isActive ? COLORS.bgElevated : "transparent", fontFamily: FONT.ui, fontSize: 13,
          color: isActive ? COLORS.textPrimary : COLORS.textSecondary,
        }}>
        <span style={{ width: 10, height: 10, borderRadius: "50%", border: `2px solid ${STATE_COLOR[aggregate(w)]}`, boxSizing: "border-box", flex: "0 0 10px" }} />
        <span style={{ flex: 1, fontWeight: isActive ? 600 : 400, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{w.name}</span>
        {w.unread && <span style={{ width: 7, height: 7, borderRadius: "50%", background: COLORS.accent, flex: "0 0 7px" }} />}
        <span style={{ display: "flex", alignItems: "center", justifyContent: "center", height: 18, minWidth: 18, padding: "0 6px", borderRadius: 9, background: COLORS.bgApp, fontFamily: FONT.mono, fontSize: 11, color: COLORS.textSecondary }}>
          {Object.keys(w.surfaces).length}
        </span>
      </div>
    );
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", width: 248, flex: "0 0 248px", background: COLORS.bgSidebar, height: "100%", padding: 14, boxSizing: "border-box" }}>
      <button onClick={onNew}
        style={{
          display: "flex", alignItems: "center", justifyContent: "center", gap: 8, width: "100%", height: 34, marginBottom: 16,
          background: COLORS.bgElevated, color: COLORS.textPrimary, border: `1px solid ${COLORS.borderStrong}`, borderRadius: 7,
          fontFamily: FONT.ui, fontSize: 13, fontWeight: 600,
        }}>
        <Plus size={15} />
        New workspace
        <span style={{ fontFamily: FONT.mono, fontSize: 11, color: COLORS.textMuted }}>⌘N</span>
      </button>

      <div style={{ flex: 1, overflowY: "auto", display: "flex", flexDirection: "column", gap: 2, minHeight: 0 }}>
        {groups.sort((a, b) => a.order - b.order).map((g) => {
          const open = !collapsed[g.id];
          return (
            <div key={g.id} style={{ marginBottom: 8 }}>
              <div onClick={() => setCollapsed((c) => ({ ...c, [g.id]: open }))}
                style={{ display: "flex", alignItems: "center", gap: 7, height: 24, padding: "0 4px", cursor: "pointer" }}>
                {open ? <ChevronDown size={13} color={COLORS.textMuted} /> : <ChevronRight size={13} color={COLORS.textMuted} />}
                <span style={{ width: 8, height: 8, borderRadius: 2, background: g.color }} />
                <span style={{ fontFamily: FONT.ui, fontSize: 11, fontWeight: 700, letterSpacing: 0.5, color: COLORS.textSecondary }}>{g.name.toUpperCase()}</span>
              </div>
              {open && byGroup(g.id).map(row)}
            </div>
          );
        })}
        {ungrouped.length > 0 && <div style={{ marginTop: 4, display: "flex", flexDirection: "column", gap: 2 }}>{ungrouped.map(row)}</div>}
      </div>

      <div title={health ? `spaceshd v${health.version} · pid ${health.pid}` : "daemon offline"}
        style={{ display: "flex", alignItems: "center", gap: 8, height: 30, marginTop: 10, padding: "0 6px", borderRadius: 6, background: COLORS.bgPanel }}>
        <span style={{ width: 7, height: 7, borderRadius: "50%", background: connected ? COLORS.stDone : COLORS.textMuted, flex: "0 0 7px" }} />
        <span style={{ fontFamily: FONT.mono, fontSize: 11, color: COLORS.textSecondary }}>{connected ? "spaceshd · live" : "spaceshd · offline"}</span>
        <span style={{ flex: 1 }} />
        <span style={{ fontFamily: FONT.mono, fontSize: 11, color: COLORS.textMuted }}>{health ? fmtUptime(health.started_at_ms) : ""}</span>
      </div>
    </div>
  );
}
