/* Argus chrome — single component (LeftPaneQueue) is the entire
   navigation surface for the workspace. Legacy Rail / Nav / TopBar /
   StatusBar / CommandPalette were retired in the LPQ-only build. */

const { useState, useEffect, useRef, useMemo } = React;

function profileInitials(name, email) {
  const source = String(name || "").trim() || String(email || "").trim();
  if (!source) return "··";
  const parts = source.includes("@")
    ? [source.slice(0, 1)]
    : source.split(/\s+/).filter(Boolean).slice(0, 2);
  return parts.map(p => p[0]).join("").toUpperCase() || "··";
}

function profileForUser(me) {
  const name = String(me?.name || me?.email || "").trim() || "Local Dev";
  return {
    name,
    role: me?.role || (me?.is_admin ? "Admin" : "Marker"),
    initials: profileInitials(me?.name, me?.email),
  };
}

/* ─────────── LEFT PANE QUEUE ─────────── */
function LeftPaneQueue({ activeEssayId, openEssay, gotoSection, section, isAdmin, me, theme, onThemeToggle, onAnalyseFile }) {
  const [query, setQuery] = useState("");
  const [reports, setReports] = useState(null);
  const [submitting, setSubmitting] = useState(false);
  const [deletingId, setDeletingId] = useState(null);
  const fileInputRef = useRef(null);
  const profile = profileForUser(me);

  // Live wire — caller's own reports. Refresh every 15s so newly
  // submitted essays appear without a manual reload. Falls back to
  // MY_ESSAYS mock only when the API is unreachable (local dev).
  useEffect(() => {
    let cancel = false;
    async function load() {
      const r = await Api.myReports();
      if (cancel) return;
      if (r.ok) {
        setReports((r.data && (r.data.reports || r.data.jobs)) || []);
      } else if (window.MY_ESSAYS && reports === null) {
        const q = window.MY_ESSAYS;
        setReports([
          ...(q.needs_follow_up || []).map(e => ({...e, _mock: true, status: "failed"})),
          ...(q.active          || []).map(e => ({...e, _mock: true, status: "completed"})),
        ]);
      } else {
        setReports([]);
      }
    }
    load();
    const iv = setInterval(load, 15000);
    return () => { cancel = true; clearInterval(iv); };
  }, []);

  const list = reports || [];
  const items = list.map(r => {
    if (r._mock) return { id: r.id, student: r.student, title: r.title, status: r.status, group: r.status === "failed" ? "needs_follow_up" : "active", mock: true };
    const id = r.report_id || r.job_id;
    const title = r.assignment_name || r.title || "Untitled essay";
    const student = r.student_name || "";
    return {
      id, student, title,
      status: r.status,
      group: r.status === "failed" ? "needs_follow_up" : "active",
      created_at: r.completed_at || r.created_at,
    };
  });
  items.sort((a, b) => {
    if ((a.group === "needs_follow_up") !== (b.group === "needs_follow_up")) {
      return a.group === "needs_follow_up" ? -1 : 1;
    }
    return (new Date(b.created_at || 0).getTime()) - (new Date(a.created_at || 0).getTime());
  });

  const matchesQuery = (e) => {
    if (!query.trim()) return true;
    const q = query.toLowerCase();
    return (e.student || "").toLowerCase().includes(q)
        || (e.title   || "").toLowerCase().includes(q);
  };
  const visible = items.filter(matchesQuery);

  async function deleteEssay(essay) {
    if (!essay || !essay.id || deletingId) return;
    const label = essay.title || essay.student || essay.id.slice(0, 8);
    if (!confirm(`Delete "${label}" from your history? This removes the report and cached result.`)) return;

    setDeletingId(essay.id);
    try {
      if (!essay.mock) {
        const r = await Api.deleteReport(essay.id);
        if (!r.ok) {
          alert(r.status === 409
            ? "This analysis is still running. Delete it after it finishes."
            : r.status === 404
              ? "Report not found, or you don't have access to delete it."
              : "Couldn't delete this run. Try again.");
          return;
        }
      }
      setReports(prev => Array.isArray(prev)
        ? prev.filter(r => {
            const id = r._mock ? r.id : (r.report_id || r.job_id);
            return id !== essay.id;
          })
        : prev);
      if (essay.id === activeEssayId && gotoSection) gotoSection("home");
    } finally {
      setDeletingId(null);
    }
  }

  // Admin-only nav entries. Marker functionality lives in the queue
  // and per-essay workspace; no public marker nav surface.
  const nav = isAdmin ? [
    { id: "ops",   icon: <Icon.Activity stroke={1.5} size={14}/>, label: "Command Centre" },
    { id: "admin", icon: <Icon.Folders stroke={1.5} size={14}/>,  label: "Invitations" },
  ] : [];

  return (
    <aside className="lpq" aria-label="Navigation and queue">
      <div className="lpq-brand" style={{cursor: "pointer"}}
           onClick={() => gotoSection && gotoSection("home")}>
        <Icon.Eye size={18} stroke={1.6} style={{color: "var(--accent)"}}/>
        <span className="lpq-brand-mark">Argus</span>
      </div>

      <button className="lpq-cta"
              disabled={submitting}
              onClick={() => fileInputRef.current && fileInputRef.current.click()}>
        <Icon.Plus size={13} stroke={1.8}/> {submitting ? "Submitting…" : "New Essay"}
      </button>
      <input ref={fileInputRef}
             type="file"
             hidden
             accept=".pdf,.docx,.rtf,.odt,.txt,.html"
             onChange={async (e) => {
               const f = e.target.files && e.target.files[0];
               e.target.value = "";
               if (!f || !onAnalyseFile) return;
               setSubmitting(true);
               try { await onAnalyseFile(f); }
               finally { setSubmitting(false); }
             }}/>

      <div className="lpq-search">
        <Icon.Search size={13} stroke={1.6} style={{color: "var(--ink-4)", flexShrink: 0}}/>
        <input value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search essays or students"
          aria-label="Search"/>
      </div>

      {nav.length > 0 && (
        <nav className="lpq-nav" aria-label="App navigation">
          {nav.map(n =>
            <button key={n.id}
                    className={"lpq-nav-item" + (section === n.id ? " is-active" : "")}
                    onClick={() => gotoSection && gotoSection(n.id)}>
              <span className="lpq-nav-icon">{n.icon}</span>
              <span className="lpq-nav-label">{n.label}</span>
            </button>
          )}
        </nav>
      )}

      <div className="lpq-scroll">
        {visible.map(e =>
          <EssayRow key={e.id} essay={e} active={e.id === activeEssayId}
                    deleting={deletingId === e.id}
                    onClick={() => openEssay && openEssay(e.id)}
                    onDelete={deleteEssay}/>
        )}
        {visible.length === 0 && reports !== null && list.length === 0 && (
          <div className="lpq-empty">No essays yet. Drop one onto New Essay.</div>
        )}
        {visible.length === 0 && list.length > 0 && (
          <div className="lpq-empty">No essays match.</div>
        )}
        {reports === null && (
          <div className="lpq-empty">Loading…</div>
        )}
      </div>

      <div className="lpq-profile">
        <div className="lpq-avatar">{profile.initials}</div>
        <div style={{minWidth: 0, lineHeight: 1.2, flex: 1}}>
          <div className="lpq-profile-name">{profile.name}</div>
          <div className="lpq-profile-role">{profile.role}</div>
        </div>
        {onThemeToggle && (
          <button className="lpq-icon-btn"
                  aria-label={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
                  title={theme === "dark" ? "Light mode" : "Dark mode"}
                  onClick={onThemeToggle}>
            <Icon.Theme size={14} stroke={1.5}/>
          </button>
        )}
        <button className="lpq-icon-btn" aria-label="Settings"
                onClick={() => gotoSection && gotoSection("settings")}>
          <Icon.Settings size={14} stroke={1.5}/>
        </button>
      </div>
    </aside>
  );
}

function EssayRow({ essay, active, deleting, onClick, onDelete }) {
  const primary = essay.student && essay.student.trim() ? essay.student : (essay.title || "Untitled essay");
  const secondary = essay.student && essay.title && essay.title !== essay.student ? essay.title : null;
  const failed  = essay.status === "failed";
  const running = essay.status === "running" || essay.status === "queued";
  return (
    <div className={"lpq-row" + (active ? " is-active" : "") + (failed ? " is-archive" : "") + (deleting ? " is-deleting" : "")}
         role="button"
         tabIndex={0}
         onClick={onClick}
         onKeyDown={(e) => {
           if (e.key === "Enter" || e.key === " ") {
             e.preventDefault();
             onClick && onClick();
           }
         }}>
      <div className="lpq-row-main">
        <div className="lpq-row-student" style={{display: "flex", alignItems: "center", gap: 6}}>
          <span style={{flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{primary}</span>
          {failed  && <span style={{fontSize: 10.5, color: "var(--miss)"}}>Failed</span>}
          {running && <span style={{fontSize: 10.5, color: "var(--accent)"}}>Running</span>}
        </div>
        {secondary && <div className="lpq-row-title">{secondary}</div>}
      </div>
      {onDelete && (
        <button className="lpq-row-delete"
                type="button"
                disabled={deleting}
                aria-label={`Delete ${primary}`}
                title="Delete run"
                onClick={(e) => {
                  e.stopPropagation();
                  onDelete(essay);
                }}>
          {deleting ? <Icon.Refresh size={12} stroke={1.7}/> : <Icon.Trash size={12} stroke={1.7}/>}
        </button>
      )}
    </div>
  );
}

Object.assign(window, { LeftPaneQueue });
