// views.jsx — Base Camp dashboard + Project detail
// Depends on globals: TopoSVG, EVEREST_DATA

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

// Static fields from seed data (user identity, date display, weather).
// The three context panels (schedule, inbox, news) fetch their own live data.
const { WEATHER, TODAY_STR, TODAY_SHORT, DAY_OF_EXPEDITION, USER } = window.EVEREST_DATA;

// ─── Shared bits ─────────────────────────────────────────────────────
function Eyebrow({ children }) {
  return <div className="eyebrow">{children}</div>;
}

function EmptyState({ title, sub, action, large }) {
  return (
    <div className={"empty" + (large ? " lg" : "")}>
      <div className="ttl">{title}</div>
      <div className="sub">{sub}</div>
      {action && <div style={{ marginTop: 14 }}>{action}</div>}
    </div>
  );
}

// ─── Topbar ──────────────────────────────────────────────────────────
function Topbar({ onHome, view, onNav, onLogout, currentUser }) {
  const NAV = [
    { id: "dashboard", label: "Base Camp" },
    { id: "notes",     label: "Notes"     },
    { id: "receipts",  label: "Receipts"  },
    { id: "symphony",  label: "Symphony"  },
  ];
  return (
    <div className="topbar">
      <div className="topbar-row">
        <div className="brand" onClick={onHome}>
          <svg className="brand-mark" viewBox="0 0 32 32" fill="none">
            <path d="M2 26 L11 10 L16 18 L22 7 L30 26 Z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round" fill="none"/>
            <path d="M11 10 L13.5 14 M22 7 L20 11" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          </svg>
          <div className="brand-name">EVEREST<em>.</em></div>
        </div>
        <div className="topbar-meta">
          <span>{TODAY_SHORT}</span>
          <span className="dot"></span>
          <span>{WEATHER}</span>
          <span className="dot"></span>
          <span>{DAY_OF_EXPEDITION}</span>
          <div className="user-chip">
            <span style={{ fontSize: 11, letterSpacing: "0.12em" }}>
              {currentUser ? (currentUser.name || currentUser.email).toUpperCase() : USER.name.toUpperCase()}
            </span>
            <span className="avatar">
              {currentUser
                ? (currentUser.name || currentUser.email).slice(0, 2).toUpperCase()
                : USER.initials}
            </span>
          </div>
        </div>
      </div>
      <nav className="topbar-nav">
        {NAV.map(n => (
          <button key={n.id} className={"nav-item" + (view === n.id || (view === "project" && n.id === "dashboard") ? " active" : "")}
            onClick={() => onNav(n.id)}>{n.label}</button>
        ))}
        <span style={{ flex: 1 }} />
        <button className="nav-item nav-icon" title="Appearance"
          onClick={() => window.postMessage({ type: "__activate_edit_mode" }, "*")}>
          ⚙ Tweaks
        </button>
        <button className="nav-item nav-icon" title="Sign out" onClick={onLogout}>
          Sign out
        </button>
      </nav>
    </div>
  );
}

// ─── Pinned expedition card ──────────────────────────────────────────
function PinnedExpeditionCard({ project, onOpen, onMarkWorked }) {
  return (
    <div className="card exp-pinned is-hot" onClick={() => onOpen(project.id)}>
      <div className="topo-panel">
        <TopoSVG seed={project.id} width={500} height={400} rings={15} />
        <div className="badge">
          <span className="dot"></span>
          <span>{project.status}</span>
        </div>
        <div className="elev">
          <div className="num">{project.elevation}</div>
          <div className="lbl">FT · ELEV</div>
        </div>
        <div className="coords">
          <span>{project.coords}</span>
          <span>{project.codename.split('·')[0].trim()}</span>
        </div>
      </div>
      <div className="meta-panel">
        <div>
          <div className="codename">{project.codename}</div>
          <h3>{project.name}</h3>
          <div className="vision" style={{ marginTop: 6, fontSize: 13.5 }}>{project.description}</div>
        </div>

        <div style={{ marginTop: 4 }}>
          <div className="row">
            <span>Last ascended</span>
            <b>{project.last_worked}</b>
          </div>
          <div className="row">
            <span>Summit ETA</span>
            <b>{project.end_date || "Not set"}</b>
          </div>
          <div className="row">
            <span>Progress</span>
            <b>{Math.round(project.progress * 100)}%</b>
          </div>
        </div>

        <div className="footer-row">
          <button
            className="btn tiny primary"
            onClick={(e) => { e.stopPropagation(); onMarkWorked(project.id); }}
          >
            {project.last_worked === "Worked today"
              ? <span className="check">✓ Worked today</span>
              : "Mark as worked today"}
          </button>
          <button className="btn tiny ghost" onClick={(e) => { e.stopPropagation(); onOpen(project.id); }}>
            Open camp →
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Compact expedition row ──────────────────────────────────────────
function ExpeditionRow({ project, onOpen }) {
  return (
    <div className="exp-row" onClick={() => onOpen(project.id)}>
      <div className="codename">{project.codename.split('·')[0].trim()}</div>
      <div className="name">
        {project.name}
        <span className="desc">{project.description}</span>
      </div>
      <div className="last">
        <b>{project.last_worked}</b><br/>
        <span style={{ opacity: .7 }}>{project.elevation} ft</span>
      </div>
      <span className="arrow">→</span>
    </div>
  );
}

// ─── Field notes ─────────────────────────────────────────────────────
function FieldNotes({ notes, onAdd, onDelete }) {
  const [text, setText] = useState("");
  const submit = () => {
    const t = text.trim();
    if (!t) return;
    onAdd(t);
    setText("");
  };
  return (
    <>
      <div className="notes-input">
        <textarea
          placeholder="Jot a quick note — coordinates, observations, blockers…"
          value={text}
          onChange={(e) => setText(e.target.value)}
          onKeyDown={(e) => {
            if ((e.metaKey || e.ctrlKey) && e.key === "Enter") submit();
          }}
        />
        <button className="btn primary" onClick={submit}>Log entry</button>
      </div>
      {notes.length === 0 ? (
        <EmptyState
          title="The journal is blank."
          sub="Every expedition begins with a first entry. Press ⌘↵ to log."
        />
      ) : (
        <div className="notes-list">
          {notes.map((n) => (
            <div className="note-entry" key={n.id}>
              <div className="ts">{new Date(n.created_at).toLocaleString()}</div>
              <div className="body">{n.text}</div>
              {onDelete && <button className="remove-btn" style={{ marginLeft: 'auto' }} onClick={() => onDelete(n.id)} title="Delete">×</button>}
            </div>
          ))}
        </div>
      )}
    </>
  );
}

// ─── Detail Drawer ───────────────────────────────────────────────────
function DetailDrawer({ item, type, onClose }) {
  useEffect(() => {
    if (!item) return;
    const handler = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", handler);
    return () => document.removeEventListener("keydown", handler);
  }, [item, onClose]);

  const open = !!item;
  let typeLabel = "", title = "", meta = [], preview = "", links = [];

  if (item) {
    if (type === "dispatch") {
      typeLabel = "Dispatch";
      title = item.subject;
      meta = [
        { label: "From", value: item.from },
        { label: "Received", value: item.time },
        ...(item.important ? [{ label: "Priority", value: "Flagged", accent: true }] : []),
      ];
      preview = item.preview;
      const q = encodeURIComponent(`subject:${item.subject} from:${item.from}`);
      links = [{ icon: "✉", label: "Open in Gmail", url: `https://mail.google.com/mail/#search/${q}` }];
    } else if (type === "news") {
      typeLabel = "From the Wire";
      title = item.title;
      meta = [
        { label: "Source", value: item.source },
        ...(item.time ? [{ label: "Published", value: item.time }] : []),
      ];
      if (item.url) links = [{ icon: "⛰", label: "Read article", url: item.url }];
    } else if (type === "event") {
      typeLabel = "Today's Traverse";
      title = item.title;
      meta = [
        { label: "Time", value: item.time },
        ...(item.sub ? [{ label: "Details", value: item.sub }] : []),
        ...(item.now ? [{ label: "Status", value: "Happening now", accent: true }] : []),
      ];
      links = [{ icon: "📅", label: "Open Google Calendar", url: "https://calendar.google.com/calendar/r" }];
    }
  }

  return (
    <>
      <div className={"detail-drawer-overlay" + (open ? " open" : "")} onClick={onClose} />
      <div className={"detail-drawer" + (open ? " open" : "")}>
        <div className="detail-drawer-head">
          <div style={{ flex: 1, minWidth: 0 }}>
            <div className="drawer-eyebrow">{typeLabel}</div>
            <div className="drawer-head-title">{title}</div>
          </div>
          <button className="detail-drawer-close" onClick={onClose} title="Close">✕</button>
        </div>
        <div className="detail-drawer-body">
          <div className="drawer-meta">
            {meta.map((m, i) => (
              <div className="drawer-meta-row" key={i}>
                <span className="drawer-meta-label">{m.label}</span>
                <span className="drawer-meta-value" style={m.accent ? { color: "var(--accent)" } : {}}>{m.value}</span>
              </div>
            ))}
          </div>
          {preview && <div className="drawer-preview">{preview}</div>}
          {links.length > 0 && (
            <div className="drawer-actions">
              {links.map((l, i) => (
                <a key={i} href={l.url} target="_blank" rel="noopener noreferrer" className="drawer-link">
                  <span className="drawer-link-ic">{l.icon}</span>
                  <span className="drawer-link-text">{l.label}</span>
                  <span className="drawer-link-arrow">↗</span>
                </a>
              ))}
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// ─── Schedule panel ──────────────────────────────────────────────────
function SchedulePanel({ data: initialData }) {
  const [data, setData] = useState(initialData || null);
  const [selected, setSelected] = useState(null);

  useEffect(() => {
    if (initialData) { setData(initialData); return; }
    fetch('/api/v1/context/calendar')
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(setData)
      .catch(err => {
        console.error('Failed to load calendar:', err);
        const fallback = window.EVEREST_DATA && window.EVEREST_DATA.TODAY_EVENTS;
        if (fallback) {
          setData({ events: fallback.map(e => ({
            time: e.time, title: e.title, sub: e.sub, now: e.now || false,
          }))});
        }
      });
  }, [initialData]);

  if (!data) return null;

  const events = data.events || [];
  return (
    <div className="panel">
      <div className="panel-head">
        <h3>Today's traverse</h3>
        <span className="meta">{events.length} events</span>
      </div>
      {events.map((e, i) => (
        <div
          className={"sched-item clickable" + (e.now ? " now" : "")}
          key={i}
          onClick={() => setSelected(e)}
        >
          <div className="time">{e.time}</div>
          <div>
            <div className="title">{e.title}</div>
            <div className="sub">{e.sub}</div>
          </div>
          <span className="item-arrow">→</span>
        </div>
      ))}
      <DetailDrawer item={selected} type="event" onClose={() => setSelected(null)} />
    </div>
  );
}

// ─── Inbox panel ─────────────────────────────────────────────────────
function InboxPanel({ data: initialData }) {
  const [data, setData] = useState(initialData || null);
  const [selected, setSelected] = useState(null);

  useEffect(() => {
    if (initialData) { setData(initialData); return; }
    fetch('/api/v1/context/inbox')
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(setData)
      .catch(err => {
        console.error('Failed to load inbox:', err);
        const fallback = window.EVEREST_DATA && window.EVEREST_DATA.INBOX;
        if (fallback) {
          setData({ messages: fallback.map(m => ({
            from: m.from, subject: m.subj, preview: m.prev,
            time: m.when, important: m.urgent || false,
          }))});
        }
      });
  }, [initialData]);

  if (!data) return null;

  const messages = data.messages || [];
  const important = messages.filter(m => m.important);
  const rest = messages.filter(m => !m.important);
  return (
    <div className="panel">
      <div className="panel-head">
        <h3>Dispatches</h3>
        <span className="meta">{important.length} flagged</span>
      </div>
      {[...important, ...rest].map((m, i) => (
        <div
          className={"mail-item clickable" + (m.important ? " urgent" : "")}
          key={i}
          onClick={() => setSelected(m)}
        >
          <div className="from">
            <b>{m.from}</b>
            <span className="when">{m.time}</span>
          </div>
          <div className="subj">{m.subject}</div>
          <div className="prev">{m.preview}</div>
        </div>
      ))}
      <DetailDrawer item={selected} type="dispatch" onClose={() => setSelected(null)} />
    </div>
  );
}

// ─── News panel ──────────────────────────────────────────────────────
function NewsPanel() {
  const [data, setData] = useState(null);
  const [selected, setSelected] = useState(null);

  useEffect(() => {
    fetch('/api/v1/context/news')
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(setData)
      .catch(err => {
        console.error('Failed to load news:', err);
        const fallback = window.EVEREST_DATA && window.EVEREST_DATA.NEWS;
        if (fallback) {
          setData({ headlines: fallback.map(n => ({
            title: n.head, source: n.src, time: null, url: null,
          }))});
        }
      });
  }, []);

  if (!data) return null;

  const headlines = data.headlines || [];
  return (
    <div className="panel">
      <div className="panel-head">
        <h3>From the wire</h3>
        <span className="meta">{TODAY_SHORT}</span>
      </div>
      {headlines.map((n, i) => (
        <div className="news-item clickable" key={i} onClick={() => setSelected(n)}>
          <div className="src">{n.source}</div>
          <div className="head">{n.title}</div>
        </div>
      ))}
      <DetailDrawer item={selected} type="news" onClose={() => setSelected(null)} />
    </div>
  );
}

// ─── Supply drop (receipts) ─────────────────────────────────────────
// onUpload(file, projectId) — async callback defined in app.jsx that POSTs to /api/receipts/upload
function SupplyDropPanel({ projects, receipts, onUpload }) {
  const [over, setOver] = useState(false);
  const [pending, setPending] = useState(null); // { file, fname }
  const inputRef = useRef(null);

  const handleFiles = (files) => {
    if (!files || files.length === 0) return;
    const f = files[0];
    setPending({ file: f, fname: f.name });
  };

  const onDrop = (e) => {
    e.preventDefault();
    setOver(false);
    handleFiles(e.dataTransfer.files);
  };

  const onPick = (projectId) => {
    if (!pending) return;
    onUpload(pending.file, projectId);
    setPending(null);
  };

  return (
    <div className="panel">
      <div className="panel-head">
        <h3>Supply cache</h3>
        <span className="meta">{receipts.length} on file</span>
      </div>
      <div
        className={"dropzone" + (over ? " is-over" : "")}
        onClick={() => inputRef.current?.click()}
        onDragOver={(e) => { e.preventDefault(); setOver(true); }}
        onDragLeave={() => setOver(false)}
        onDrop={onDrop}
      >
        <div className="ic">⛰</div>
        <div className="ttl">Drop receipts here</div>
        <div className="hint">PDF · JPG · PNG — classify by project after drop</div>
        <input
          ref={inputRef}
          type="file"
          accept="image/*,application/pdf"
          style={{ display: 'none' }}
          onChange={(e) => handleFiles(e.target.files)}
        />
      </div>

      {pending && (
        <div className="receipt-pending">
          <div className="lbl">Classify supply</div>
          <div className="fname">{pending.fname}</div>
          <div className="picker">
            {projects.map((p) => (
              <button key={p.id} onClick={() => onPick(p.id)}>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--accent)', letterSpacing: '.14em', marginRight: 8 }}>
                  {p.codename.split('·')[0].trim()}
                </span>
                {p.name}
              </button>
            ))}
            <button onClick={() => onPick(null)} style={{ color: 'var(--ink-3)' }}>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, letterSpacing: '.14em', marginRight: 8 }}>—</span>
              Unfiled
            </button>
          </div>
        </div>
      )}

      {receipts.length > 0 && (
        <div style={{ marginTop: 14 }}>
          {receipts.slice().reverse().map((r) => {
            const proj = projects.find(p => p.id === r.project_id);
            return (
              <div className="receipt-logged" key={r.id}>
                <span><b>{r.fname}</b></span>
                <span className="tag">{proj ? proj.codename.split('·')[0].trim() : 'UNFILED'}</span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ─── Dashboard view ──────────────────────────────────────────────────
function Dashboard({ projects, notes, receipts, onOpen, onMarkWorked, onAddNote, onUploadReceipt, onCreateProject, onDeleteNote }) {
  const [showNewCamp, setShowNewCamp] = useState(false);
  const [newName, setNewName] = useState("");
  const [newDesc, setNewDesc] = useState("");
  const [newFolder, setNewFolder] = useState("");
  const [calendarData, setCalendarData] = useState(null);
  const [inboxData, setInboxData] = useState(null);
  const pinned = projects.find(p => p.pinned) || projects[0] || null;
  const rest = pinned ? projects.filter(p => p.id !== pinned.id) : [];
  const greetingTime = (() => {
    const h = new Date().getHours();
    if (h < 5) return "Still up";
    if (h < 12) return "Good morning";
    if (h < 18) return "Good afternoon";
    return "Good evening";
  })();

  useEffect(() => {
    fetch('/api/v1/context/calendar')
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(setCalendarData)
      .catch(() => {
        const fb = window.EVEREST_DATA && window.EVEREST_DATA.TODAY_EVENTS;
        if (fb) setCalendarData({ events: fb.map(e => ({ time: e.time, title: e.title, sub: e.sub, now: e.now || false })) });
      });
    fetch('/api/v1/context/inbox')
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(setInboxData)
      .catch(() => {
        const fb = window.EVEREST_DATA && window.EVEREST_DATA.INBOX;
        if (fb) setInboxData({ messages: fb.map(m => ({ from: m.from, subject: m.subj, preview: m.prev, time: m.when, important: m.urgent || false })) });
      });
  }, []);

  return (
    <>
      <section className="briefing">
        <div>
          <Eyebrow>Base Camp · {TODAY_STR}</Eyebrow>
          <div className="greeting" style={{ marginTop: 14 }}>
            {greetingTime},<br/>
            <em>{USER.name.split(' ')[0]}.</em>
          </div>
        </div>
        <div className="briefing-meta">
          <div className="stat">
            <Eyebrow>On the rope</Eyebrow>
            <div className="v">{projects.length}</div>
            <div className="sub">active expeditions</div>
          </div>
          <div className="stat">
            <Eyebrow>Today</Eyebrow>
            <div className="v">{calendarData ? calendarData.events.length : "—"}</div>
            <div className="sub">events today</div>
          </div>
          <div className="stat">
            <Eyebrow>Conditions</Eyebrow>
            <div className="v" style={{ fontSize: 22 }}>
              {inboxData
                ? inboxData.messages.filter(m => m.important).length === 0 ? "Clear"
                  : inboxData.messages.filter(m => m.important).length <= 2 ? "Flagged"
                  : "Heavy"
                : "—"}
            </div>
            <div className="sub">
              {inboxData ? `${inboxData.messages.filter(m => m.important).length} flagged` : "loading…"}
            </div>
          </div>
        </div>
      </section>

      <div className="main-grid">
        <div>
          {/* Expeditions */}
          <section className="section">
            <div className="section-head">
              <div className="left">
                <h2>Expeditions</h2>
                <span className="count">{projects.length} · ALL CAMPS</span>
              </div>
              <button className="action" onClick={() => setShowNewCamp(true)}>+ New camp</button>
            </div>
            {showNewCamp && (
              <div className="slide-panel" style={{ marginBottom: 16 }}>
                <div className="slide-panel-title">New expedition</div>
                <div className="slide-panel-row">
                  <label>Name</label>
                  <input type="text" value={newName} onChange={e => setNewName(e.target.value)} placeholder="Project name" autoFocus />
                </div>
                <div className="slide-panel-row">
                  <label>Description</label>
                  <input type="text" value={newDesc} onChange={e => setNewDesc(e.target.value)} placeholder="One-line summary" />
                </div>
                <div className="slide-panel-row">
                  <label>Folder</label>
                  <input type="text" value={newFolder} onChange={e => setNewFolder(e.target.value)} placeholder="~/work/project-name/" />
                </div>
                <div className="inline-editor-actions" style={{ marginTop: 12 }}>
                  <button className="btn primary tiny" onClick={() => {
                    if (!newName.trim()) return;
                    onCreateProject({ name: newName.trim(), description: newDesc.trim(), folder: newFolder.trim() });
                    setShowNewCamp(false); setNewName(""); setNewDesc(""); setNewFolder("");
                  }}>Create camp</button>
                  <button className="btn tiny" onClick={() => setShowNewCamp(false)}>Cancel</button>
                </div>
              </div>
            )}
            {pinned ? (
              <>
                <PinnedExpeditionCard
                  project={pinned}
                  onOpen={onOpen}
                  onMarkWorked={onMarkWorked}
                />
                <div className="exp-list">
                  {rest.map((p) => (
                    <ExpeditionRow key={p.id} project={p} onOpen={onOpen} />
                  ))}
                </div>
              </>
            ) : (
              <EmptyState
                large
                title="No expeditions yet."
                sub="You have no active camps. Create one to start tracking your ascent."
                action={<button className="btn primary tiny" onClick={() => setShowNewCamp(true)}>+ New camp</button>}
              />
            )}
          </section>

          {/* Field notes */}
          <section className="section">
            <div className="section-head">
              <div className="left">
                <h2>Field notes</h2>
                <span className="count">{notes.length} · TIMESTAMPED</span>
              </div>
            </div>
            <FieldNotes notes={notes} onAdd={onAddNote} onDelete={onDeleteNote} />
          </section>
        </div>

        <div>
          <SchedulePanel data={calendarData} />
          <InboxPanel data={inboxData} />
          <NewsPanel />
          <SupplyDropPanel projects={projects} receipts={receipts} onUpload={onUploadReceipt} />
        </div>
      </div>
    </>
  );
}

Object.assign(window, { Dashboard, EmptyState, Eyebrow, Topbar });


// ─── Notes view ──────────────────────────────────────────────────────
function NotesView({ notes, onAdd, onDelete }) {
  const [text, setText] = React.useState("");
  const submit = (e) => {
    e.preventDefault();
    const t = text.trim(); if (!t) return;
    onAdd(t, null); setText("");
  };
  const fmt = (ts) => ts ? new Date(ts).toLocaleString(undefined, { month:"short", day:"numeric", hour:"2-digit", minute:"2-digit" }) : "";
  return (
    <div className="view-shell">
      <div className="view-header">
        <div className="eyebrow">Field Notes</div>
        <h2>All Notes</h2>
      </div>
      <form className="notes-composer" onSubmit={submit}>
        <textarea className="notes-textarea" rows={3} placeholder="Write a note…" value={text}
          onChange={e => setText(e.target.value)}
          onKeyDown={e => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) submit(e); }} />
        <div style={{ display:"flex", justifyContent:"flex-end", marginTop:8 }}>
          <button className="btn small primary" type="submit" disabled={!text.trim()}>Add note</button>
        </div>
      </form>
      {notes.length === 0
        ? <div className="empty lg"><div className="ttl">No notes yet</div><div className="sub">Notes you add will appear here.</div></div>
        : <div className="notes-list">
            {notes.map(n => (
              <div key={n.id} className="note-card">
                <div className="note-body">{n.text || n.content}</div>
                <div className="note-foot">
                  <span className="note-meta">{fmt(n.created_at)}{n.project_id ? ` · ${n.project_id}` : ""}</span>
                  {onDelete && <button className="note-del" onClick={() => onDelete(n.id)} title="Delete">✕</button>}
                </div>
              </div>
            ))}
          </div>
      }
    </div>
  );
}

// ─── Receipts view ───────────────────────────────────────────────────
function ReceiptsView({ receipts, projects, onUpload }) {
  const [dragOver, setDragOver] = React.useState(false);
  const [projectId, setProjectId] = React.useState("");
  const inputRef = React.useRef();
  const fmt = (ts) => ts ? new Date(ts).toLocaleDateString(undefined, { month:"short", day:"numeric", year:"numeric" }) : "";
  const fmtSize = (b) => b < 1024 ? b + " B" : b < 1048576 ? (b/1024).toFixed(1) + " KB" : (b/1048576).toFixed(1) + " MB";

  const handleFiles = (files) => {
    const f = files[0]; if (!f) return;
    onUpload(f, projectId || null);
  };
  const onDrop = (e) => {
    e.preventDefault(); setDragOver(false);
    handleFiles(e.dataTransfer.files);
  };

  return (
    <div className="view-shell">
      <div className="view-header">
        <div className="eyebrow">Cache</div>
        <h2>All Receipts</h2>
      </div>
      <div className={"drop-zone" + (dragOver ? " drag-over" : "")}
        onDragOver={e => { e.preventDefault(); setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onDrop={onDrop}
        onClick={() => inputRef.current?.click()}>
        <input ref={inputRef} type="file" accept=".pdf,.jpg,.jpeg,.png,.webp"
          style={{ display:"none" }} onChange={e => handleFiles(e.target.files)} />
        <div style={{ fontSize:28, marginBottom:8 }}>📎</div>
        <div style={{ fontWeight:600 }}>Drop a receipt here or click to upload</div>
        <div style={{ fontSize:12, color:"var(--ink-3)", marginTop:4 }}>PDF, JPG, PNG, WEBP · max 10 MB</div>
        {projects.length > 0 && (
          <select className="drop-zone-select" value={projectId} onClick={e => e.stopPropagation()}
            onChange={e => setProjectId(e.target.value)}>
            <option value="">No project</option>
            {projects.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
        )}
      </div>
      {receipts.length === 0
        ? <div className="empty lg"><div className="ttl">No receipts yet</div><div className="sub">Drop files above to classify them to a project.</div></div>
        : <div className="receipts-grid">
            {receipts.map(r => (
              <div key={r.id} className="receipt-card">
                <div className="receipt-icon">{r.fname?.endsWith(".pdf") ? "📄" : "🖼"}</div>
                <div className="receipt-info">
                  <div className="receipt-name">{r.fname}</div>
                  <div className="receipt-meta">{fmtSize(r.size)} · {fmt(r.created_at)}{r.project_id ? ` · ${r.project_id}` : ""}</div>
                </div>
              </div>
            ))}
          </div>
      }
    </div>
  );
}

// ─── Symphony view ───────────────────────────────────────────────────
function SymphonyView() {
  const [health, setHealth] = React.useState(null);
  const [state, setState] = React.useState(null);
  const [metrics, setMetrics] = React.useState(null);
  const [err, setErr] = React.useState("");

  React.useEffect(() => {
    const load = async () => {
      try {
        const [h, s, m] = await Promise.all([
          fetch("/api/v1/symphony/healthz").then(r => r.json()),
          fetch("/api/v1/symphony/state").then(r => r.json()),
          fetch("/api/v1/symphony/metrics").then(r => r.json()),
        ]);
        setHealth(h); setState(s); setMetrics(m);
      } catch(e) { setErr("Symphony layer unavailable — check server logs."); }
    };
    load();
  }, []);

  return (
    <div className="view-shell">
      <div className="view-header">
        <div className="eyebrow">Agent Layer</div>
        <h2>Symphony</h2>
      </div>
      {err ? <div className="empty lg"><div className="ttl">Unavailable</div><div className="sub">{err}</div></div> : (
        <div className="sym-grid">
          <div className="sym-card">
            <div className="sym-label">Status</div>
            <div className={"sym-value sym-status " + (health?.paused ? "paused" : "ok")}>
              {health ? (health.paused ? "⏸ Paused" : "✓ Running") : "…"}
            </div>
          </div>
          <div className="sym-card">
            <div className="sym-label">Active runs</div>
            <div className="sym-value">{state ? state.active_attempts : "…"}</div>
          </div>
          <div className="sym-card">
            <div className="sym-label">Retry queue</div>
            <div className="sym-value">{state ? state.retry_queue_size : "…"}</div>
          </div>
          <div className="sym-card">
            <div className="sym-label">Recent attempts</div>
            <div className="sym-value">{metrics ? metrics.recent_attempts : "…"}</div>
          </div>
          <div className="sym-card">
            <div className="sym-label">Success / Failed</div>
            <div className="sym-value">{metrics ? `${metrics.succeeded} / ${metrics.failed}` : "…"}</div>
          </div>
          <div className="sym-card">
            <div className="sym-label">Total cost (recent)</div>
            <div className="sym-value">{metrics ? `$${metrics.total_cost_usd.toFixed(4)}` : "…"}</div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { NotesView, ReceiptsView, SymphonyView });
