import React, { useEffect, useMemo, useState } from "react";
import { FolderOpen, FileClock, X, Search, ChevronRight, ChevronDown, HardDrive } from "lucide-react";
import { C, FD, FM } from "../theme.js";
import { fetchSessions } from "../useAnalysis.js";

// Multi-session browser. Walks the REAL ~/.claude/projects via the local engine
// API (cwd read from inside each file, never the lossy folder name — NN#5) and
// lets the user open ANY session, not just the bundled POC. Deepest-folder-wins
// grouping is by the true cwd the engine reports.

function fmtBytes(n) {
  if (!n) return "0B";
  if (n >= 1e6) return (n / 1e6).toFixed(1) + "MB";
  if (n >= 1e3) return Math.round(n / 1e3) + "KB";
  return n + "B";
}
function fmtAge(sec) {
  if (!sec) return "";
  const d = Date.now() / 1000 - sec;
  if (d < 3600) return Math.max(1, Math.round(d / 60)) + "m ago";
  if (d < 86400) return Math.round(d / 3600) + "h ago";
  return Math.round(d / 86400) + "d ago";
}
// Real session START datetime — the whole point of Shripal's ask: "couldn't tell
// which session was which." Renders local like "Jun 04, 21:30". Accepts an ISO
// string (session.startedAt, read from inside the file) OR epoch-ms (the mtime
// fallback). Invalid/empty input renders nothing rather than "Invalid Date".
const _MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
function fmtDateTime(iso_or_ms) {
  if (!iso_or_ms) return "";
  const dt = new Date(iso_or_ms);
  if (isNaN(dt.getTime())) return "";
  const mon = _MONTHS[dt.getMonth()];
  const day = String(dt.getDate()).padStart(2, "0");
  const hh = String(dt.getHours()).padStart(2, "0");
  const mm = String(dt.getMinutes()).padStart(2, "0");
  return `${mon} ${day}, ${hh}:${mm}`;
}

export default function SessionBrowser({ current, onPick, onOpenProject, onClose }) {
  const [state, setState] = useState({ status: "loading", data: null, error: null });
  const [open, setOpen] = useState({});
  const [q, setQ] = useState("");

  useEffect(() => {
    let alive = true;
    (async () => {
      try {
        const data = await fetchSessions();
        if (alive) {
          setState({ status: "ready", data, error: null });
          // auto-expand the project containing the current session
          if (data.projects && data.projects.length) {
            const first = {};
            data.projects.slice(0, 1).forEach((p) => (first[p.cwd] = true));
            setOpen(first);
          }
        }
      } catch (e) {
        if (alive) setState({ status: "error", data: null, error: String(e) });
      }
    })();
    return () => { alive = false; };
  }, []);

  const projects = useMemo(() => {
    const ps = state.data?.projects || [];
    if (!q.trim()) return ps;
    const needle = q.toLowerCase();
    return ps
      .map((p) => ({
        ...p,
        sessions: p.sessions.filter(
          (s) =>
            p.cwd.toLowerCase().includes(needle) ||
            (s.sessionId || "").toLowerCase().includes(needle)
        ),
      }))
      .filter((p) => p.cwd.toLowerCase().includes(needle) || p.sessions.length);
  }, [state.data, q]);

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(15,14,13,.72)", zIndex: 50, display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "6vh 20px" }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "min(820px,94vw)", maxHeight: "84vh", background: C.panel, border: `1px solid ${C.border}`, borderRadius: 12, display: "flex", flexDirection: "column", boxShadow: "0 24px 60px rgba(0,0,0,.5)" }}>
        {/* header */}
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 16px", borderBottom: `1px solid ${C.borderSoft}` }}>
          <FolderOpen size={18} color={C.orange} />
          <div style={{ fontFamily: FD, fontWeight: 700, fontSize: 16 }}>Browse sessions</div>
          <span style={{ fontFamily: FM, fontSize: 11, color: C.muted }}>
            {state.data ? `${state.data.total} sessions · ${state.data.projectCount} projects · ~/.claude/projects` : ""}
          </span>
          <div style={{ flex: 1 }} />
          <div className="row lift" onClick={onClose} style={{ cursor: "pointer", padding: 6, borderRadius: 7 }}><X size={16} color={C.text2} /></div>
        </div>

        {/* search */}
        <div style={{ padding: "10px 16px", borderBottom: `1px solid ${C.borderSoft}` }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, background: C.black, border: `1px solid ${C.borderSoft}`, borderRadius: 8, padding: "7px 10px" }}>
            <Search size={14} color={C.muted} />
            <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="filter by path or session id…" style={{ flex: 1, background: "transparent", border: "none", outline: "none", color: C.text, fontFamily: FM, fontSize: 12.5 }} />
          </div>
        </div>

        {/* body */}
        <div style={{ overflowY: "auto", padding: "8px 10px 14px" }}>
          {state.status === "loading" && <div style={{ padding: 24, color: C.muted, fontFamily: FM, fontSize: 12 }}>reading ~/.claude/projects…</div>}
          {state.status === "error" && (
            <div style={{ padding: 24, color: C.red, fontFamily: FM, fontSize: 12 }}>
              could not reach the engine API — start it with: <br />
              <span style={{ color: C.amber }}>python3 server/app.py</span> (then reload)
              <div style={{ color: C.muted, marginTop: 6 }}>{state.error}</div>
            </div>
          )}
          {state.status === "ready" && projects.map((p) => {
            const isOpen = open[p.cwd] ?? false;
            return (
              <div key={p.cwd} style={{ marginBottom: 4 }}>
                <div className="row" onClick={() => setOpen((o) => ({ ...o, [p.cwd]: !isOpen }))} style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 10px", borderRadius: 8, cursor: "pointer" }}>
                  {isOpen ? <ChevronDown size={15} color={C.muted} /> : <ChevronRight size={15} color={C.muted} />}
                  <HardDrive size={14} color={C.cyan} />
                  <span style={{ fontFamily: FM, fontSize: 12.5, color: C.text, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.cwd}</span>
                  {onOpenProject && (
                    <span className="lift" onClick={(ev) => { ev.stopPropagation(); onOpenProject(p.cwd); }} title="open the project view (changelog, entities, all sessions)" style={{ fontFamily: FM, fontSize: 9.5, color: C.orange, border: `1px solid ${C.orangeBd}`, borderRadius: 5, padding: "2px 8px" }}>project →</span>
                  )}
                  <span style={{ fontFamily: FM, fontSize: 10.5, color: C.muted, background: C.black, border: `1px solid ${C.borderSoft}`, borderRadius: 20, padding: "1px 9px" }}>{p.count}</span>
                </div>
                {isOpen && p.sessions.map((s) => {
                  const active = current === s.path;
                  return (
                    <div key={s.path} className="row lift" onClick={() => onPick(s.path)} style={{ display: "flex", alignItems: "center", gap: 9, margin: "3px 0 3px 26px", padding: "8px 11px", borderRadius: 8, cursor: "pointer", background: active ? C.card : "transparent", border: `1px solid ${active ? C.orangeBd : "transparent"}`, borderLeft: `3px solid ${active ? C.orange : C.borderSoft}` }}>
                      <FileClock size={14} color={active ? C.orange : C.text2} />
                      <span style={{ fontFamily: FM, fontSize: 12, color: active ? C.text : C.text2 }}>{(s.sessionId || "?").slice(0, 8)}</span>
                      {/* real START datetime — the signal that tells sessions apart */}
                      {fmtDateTime(s.startedAt || (s.mtime ? s.mtime * 1000 : 0)) && (
                        <span style={{ fontFamily: FM, fontSize: 11, color: active ? C.orange : C.text2, fontWeight: 600 }}>
                          {fmtDateTime(s.startedAt || (s.mtime ? s.mtime * 1000 : 0))}
                        </span>
                      )}
                      <span style={{ flex: 1 }} />
                      <span style={{ fontFamily: FM, fontSize: 10, color: C.muted }}>{fmtBytes(s.sizeBytes)}</span>
                      <span style={{ fontFamily: FM, fontSize: 10, color: C.muted, minWidth: 56, textAlign: "right" }}>{fmtAge(s.mtime)}</span>
                    </div>
                  );
                })}
              </div>
            );
          })}
          {state.status === "ready" && projects.length === 0 && (
            <div style={{ padding: 24, color: C.muted, fontFamily: FM, fontSize: 12 }}>no sessions match “{q}”.</div>
          )}
        </div>

        <div style={{ padding: "9px 16px", borderTop: `1px solid ${C.borderSoft}`, fontFamily: FM, fontSize: 10.5, color: C.muted }}>
          cwd is read from inside each file, never the encoded folder name · pick a session to analyze it live
        </div>
      </div>
    </div>
  );
}
