/* global React, PR, PRCover, PRComments, PRCreatives */
const { useState, useEffect, useRef } = React;
const { I, Avatar, StagePill, DecisionPill, RiskDot, formatDate, daysAgo, metricDelta } = PR;
const { Cover } = PRCover;
const { CommentsPanel } = PRComments;
const { CreativesPanel } = PRCreatives;

// ── Pencil icon ───────────────────────────────────────────────────────────────
function PencilIcon() {
  return (
    <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor"
         strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
      <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
    </svg>
  );
}

// ── Cover edit overlay ────────────────────────────────────────────────────────
function CoverEditOverlay({ onSave }) {
  const [open, setOpen]         = useState(false);
  const [uploading, setUploading] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  const [error, setError]       = useState(null);
  const fileInputRef            = useRef(null);
  const panelRef                = useRef(null);

  const uploadFile = async (file) => {
    if (!file || !file.type.startsWith("image/")) { setError("Only images allowed"); return; }
    setUploading(true); setError(null);
    try {
      const form = new FormData();
      form.append("file", file);
      const resp = await fetch("/api/upload", { method: "POST", body: form });
      if (!resp.ok) { const e = await resp.json().catch(() => ({})); throw new Error(e.detail || "Upload failed"); }
      const { url } = await resp.json();
      await onSave(url);
      setOpen(false);
    } catch (e) {
      setError(e.message);
    } finally {
      setUploading(false);
    }
  };

  // Paste anywhere while panel is open
  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      const items = e.clipboardData?.items;
      if (!items) return;
      for (const item of items) {
        if (item.type.startsWith("image/")) { e.preventDefault(); uploadFile(item.getAsFile()); return; }
      }
    };
    document.addEventListener("paste", handler);
    return () => document.removeEventListener("paste", handler);
  }, [open]);

  // Click outside closes panel
  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (panelRef.current && !panelRef.current.contains(e.target)) setOpen(false);
    };
    setTimeout(() => document.addEventListener("mousedown", handler), 0);
    return () => document.removeEventListener("mousedown", handler);
  }, [open]);

  return (
    <div ref={panelRef} className="cover-edit-overlay">
      <button className="cover-edit-btn" onClick={() => { setOpen(v => !v); setError(null); }}>
        {open ? "Cancel" : "Update cover"}
      </button>
      {open && (
        <div className="cover-edit-panel">
          {error && <div style={{ color: "var(--kill)", fontSize: 11, marginBottom: 6 }}>{error}</div>}
          <div
            className={"cover-drop-zone" + (dragOver ? " drag-over" : "") + (uploading ? " uploading" : "")}
            style={{ height: 68, fontSize: 12 }}
            onClick={() => !uploading && fileInputRef.current?.click()}
            onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
            onDragLeave={() => setDragOver(false)}
            onDrop={(e) => { e.preventDefault(); setDragOver(false); const f = e.dataTransfer.files[0]; if (f) uploadFile(f); }}
          >
            {uploading ? "Uploading…" : "Click · drag & drop · Ctrl+V to paste"}
          </div>
          <input ref={fileInputRef} type="file" accept="image/*" style={{ display: "none" }}
            onChange={(e) => { const f = e.target.files[0]; if (f) uploadFile(f); e.target.value = ""; }} />
        </div>
      )}
    </div>
  );
}

// ── Generic inline-editable field ─────────────────────────────────────────────
function InlineField({ value, onSave, type = "text", options = [], placeholder = "Click to edit…", children, rows = 3, style, className = "" }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft]     = useState("");
  const [saving, setSaving]   = useState(false);
  const [error, setError]     = useState(null);
  const mouseDownPos          = useRef(null);
  const inputRef              = useRef(null);

  useEffect(() => {
    if (editing && inputRef.current) {
      inputRef.current.focus();
      const el = inputRef.current;
      if (el.setSelectionRange && el.value) {
        el.setSelectionRange(el.value.length, el.value.length);
      }
    }
  }, [editing]);

  const startEdit = (e) => {
    const sel = window.getSelection();
    if (sel && sel.toString().length > 0) return;
    if (mouseDownPos.current) {
      const dx = Math.abs(e.clientX - mouseDownPos.current.x);
      const dy = Math.abs(e.clientY - mouseDownPos.current.y);
      if (dx > 4 || dy > 4) return;
    }
    setDraft(value ?? "");
    setError(null);
    setEditing(true);
  };

  const save = async () => {
    if (saving) return;
    setSaving(true);
    setError(null);
    try {
      await onSave(draft);
      setEditing(false);
    } catch (err) {
      setError(err.message || "Failed to save");
    } finally {
      setSaving(false);
    }
  };

  const cancel = () => { setEditing(false); setError(null); };

  const handleKeyDown = (e) => {
    if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); cancel(); return; }
    if (type !== "textarea" && e.key === "Enter") { e.preventDefault(); save(); return; }
    if (type === "textarea" && e.key === "Enter" && (e.ctrlKey || e.metaKey)) { e.preventDefault(); save(); return; }
  };

  if (editing) {
    return (
      <div className={"inline-edit-wrap " + className} style={style}>
        {type === "textarea" ? (
          <textarea ref={inputRef} className="form-textarea" value={draft} rows={rows}
            onChange={e => setDraft(e.target.value)} onKeyDown={handleKeyDown} />
        ) : type === "select" ? (
          <select ref={inputRef} className="form-select" value={draft}
            onChange={e => setDraft(e.target.value)} onKeyDown={handleKeyDown}>
            {options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
          </select>
        ) : (
          <input ref={inputRef} className="form-input" value={draft}
            onChange={e => setDraft(e.target.value)} onKeyDown={handleKeyDown} />
        )}
        {error && <div className="inline-edit-error">{error}</div>}
        <div className="inline-edit-actions">
          <button className="btn btn-primary" style={{ height: 26, padding: "0 10px", fontSize: 12 }}
            onClick={save} disabled={saving}>
            {saving ? "Saving…" : "Save"}
          </button>
          <button className="btn btn-ghost" style={{ height: 26, padding: "0 8px", fontSize: 12 }}
            onClick={cancel} disabled={saving}>
            Cancel
          </button>
          {type === "textarea" && (
            <span style={{ fontSize: 11, color: "var(--text-4)", marginLeft: 2 }}>Ctrl+Enter</span>
          )}
        </div>
      </div>
    );
  }

  return (
    <div
      className={"inline-field " + className}
      style={style}
      onMouseDown={e => { mouseDownPos.current = { x: e.clientX, y: e.clientY }; }}
      onClick={startEdit}
    >
      {children != null ? children
        : value ? <span>{value}</span>
        : <span className="inline-field-placeholder">{placeholder}</span>}
      <span className="inline-field-icon"><PencilIcon /></span>
    </div>
  );
}

// ── Inline tag selector ───────────────────────────────────────────────────────
function InlineTagField({ value, allTags, onSave }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft]     = useState([]);
  const [saving, setSaving]   = useState(false);
  const mouseDownPos          = useRef(null);

  const startEdit = (e) => {
    const sel = window.getSelection();
    if (sel && sel.toString().length > 0) return;
    if (mouseDownPos.current) {
      const dx = Math.abs(e.clientX - mouseDownPos.current.x);
      const dy = Math.abs(e.clientY - mouseDownPos.current.y);
      if (dx > 4 || dy > 4) return;
    }
    setDraft([...(value || [])]);
    setEditing(true);
  };

  const toggle = (tag) =>
    setDraft(prev => prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag]);

  const save = async () => {
    setSaving(true);
    try {
      await onSave(draft);
      setEditing(false);
    } finally {
      setSaving(false);
    }
  };

  if (editing) {
    return (
      <div className="inline-edit-wrap">
        <div className="tags-wrap" style={{ marginBottom: 4 }}>
          {draft.map(t => (
            <span key={t} className="tag-chip tag-chip-selected">
              {t}
              <span style={{ cursor: "pointer", marginLeft: 3, opacity: 0.7 }} onClick={() => toggle(t)}>×</span>
            </span>
          ))}
          {(allTags || []).filter(t => !draft.includes(t)).map(t => (
            <span key={t} className="tag-chip" onClick={() => toggle(t)}>{t}</span>
          ))}
        </div>
        <div className="inline-edit-actions">
          <button className="btn btn-primary" style={{ height: 26, padding: "0 10px", fontSize: 12 }}
            onClick={save} disabled={saving}>
            {saving ? "Saving…" : "Save"}
          </button>
          <button className="btn btn-ghost" style={{ height: 26, padding: "0 8px", fontSize: 12 }}
            onClick={() => setEditing(false)}>
            Cancel
          </button>
        </div>
      </div>
    );
  }

  return (
    <div
      className="inline-field"
      onMouseDown={e => { mouseDownPos.current = { x: e.clientX, y: e.clientY }; }}
      onClick={startEdit}
    >
      <span style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
        {value && value.length
          ? value.map(t => <span key={t} className="tag" data-tag={t.toLowerCase().replace(/\s+/g, "-")}>{t}</span>)
          : <span className="inline-field-placeholder">No genre tags</span>}
      </span>
      <span className="inline-field-icon"><PencilIcon /></span>
    </div>
  );
}

// ── Detail / R&D Passport ─────────────────────────────────────────────────────
function PassportView({ data, hypothesisId, onDecide, onAdvance, onRefresh, user, embedded }) {
  const h = data.hypotheses.find(x => x.id === hypothesisId) || data.hypotheses[0];
  const [assets, setAssets]   = useState([]);
  const [history, setHistory] = useState([]);

  useEffect(() => {
    if (!h) return;
    fetch(`/api/hypotheses/${h.id}/assets`).then(r => r.ok ? r.json() : []).then(setAssets);
    fetch(`/api/hypotheses/${h.id}/history`).then(r => r.ok ? r.json() : []).then(setHistory);
  }, [h?.id]);

  if (!h) return <div className="empty-hint">Select a hypothesis to view its passport.</div>;

  const a = data.authors.find(x => x.id === h.author);
  const m = metricDelta(h);

  const stageIdx    = data.stages.findIndex(s => s.id === h.stage);
  const STAGE_ORDER = ["idea", "greybox", "prototype", "coldtest", "decision"];
  const canAdvance  = !h.decision && STAGE_ORDER.includes(h.stage) && STAGE_ORDER.indexOf(h.stage) < STAGE_ORDER.length - 1;
  const canDecide   = h.stage === "decision" && !h.decision;
  const isDecided   = !!h.decision;

  const historyMap = {};
  history.forEach(item => { historyMap[item.to_stage] = item; });

  const deleteAsset = async (id) => {
    await fetch(`/api/hypotheses/${h.id}/assets/${id}`, { method: "DELETE" });
    setAssets(prev => prev.filter(a => a.id !== id));
  };

  const refreshAssets = () => {
    fetch(`/api/hypotheses/${h.id}/assets`).then(r => r.json()).then(setAssets);
  };

  const [assetForm, setAssetForm]     = useState({ name: "", url: "", asset_type: "other" });
  const [addingAsset, setAddingAsset] = useState(false);

  const submitAsset = async (e) => {
    e.preventDefault();
    await fetch(`/api/hypotheses/${h.id}/assets`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(assetForm),
    });
    setAssetForm({ name: "", url: "", asset_type: "other" });
    setAddingAsset(false);
    refreshAssets();
  };

  // ── Inline patch helper ───────────────────────────────────────────────────
  const patchField = async (field, newValue) => {
    const payload = {
      title:         h.title,
      core_loop:     h.coreLoop || "",
      tags:          h.tags || [],
      key_metric:    h.keyMetric !== "TBD" ? (h.keyMetric || "") : "",
      target:        h.target !== "—" ? (h.target || "") : "",
      current_value: h.current !== "—" ? (h.current || "") : "",
      risk:          h.risk || "med",
      summary:       h.summary || "",
      cover_url:     h.coverUrl || "",
      author_id:     parseInt(h.author) || undefined,
    };
    payload[field] = newValue;
    const resp = await fetch(`/api/hypotheses/${h.id}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    if (!resp.ok) {
      const err = await resp.json().catch(() => ({}));
      throw new Error(err.detail || "Failed to save");
    }
    onRefresh && onRefresh();
  };

  return (
    <div className="passport-page">
      {/* Cover */}
      <div style={{ position: "relative" }}>
        <Cover projectId={h.id} coverUrl={h.coverUrl} size="full" />
        <CoverEditOverlay onSave={url => patchField("cover_url", url)} />
      </div>

      {/* Header */}
      <div style={{ padding: "20px 32px 0" }}>
        <div className="passport-id">
          <span>{h.id}</span>
          <span style={{ color: "var(--text-4)" }}>·</span>
          <StagePill stage={h.stage} stages={data.stages} />
          {h.pivotedFrom && (
            <><span style={{ color: "var(--text-4)" }}>·</span>
            <span style={{ fontSize: 11 }}>↳ pivot from {h.pivotedFrom}</span></>
          )}
          {h.decision && (
            <><span style={{ color: "var(--text-4)" }}>·</span>
            <DecisionPill decision={h.decision} /></>
          )}
        </div>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16, marginBottom: 10 }}>
          <InlineField
            value={h.title}
            onSave={v => patchField("title", v)}
            type="text"
            style={{ flex: 1, minWidth: 0 }}
          >
            <h1 className="passport-title" style={{ margin: 0 }}>{h.title}</h1>
          </InlineField>
          <div style={{ display: "flex", gap: 6, flexShrink: 0, paddingTop: 6 }}>
            {canAdvance && (
              <button className="btn btn-primary" style={{ height: 28, padding: "0 12px", fontSize: 12 }}
                onClick={() => onAdvance && onAdvance(h.id, null)}>
                Advance →
              </button>
            )}
            {canDecide && (
              <button className="btn btn-primary" style={{ height: 28, padding: "0 12px", fontSize: 12 }}
                onClick={() => onDecide && onDecide(h.id)}>
                Decide
              </button>
            )}
          </div>
        </div>
        <div className="passport-meta" style={{ marginBottom: 16 }}>
          {a && <div><Avatar author={a} /><span>{a.name}</span></div>}
          <div>{I.clock}<span>Started {formatDate(h.started)}</span></div>
          <div>{I.clock}<span>Updated {daysAgo(h.updated)}</span></div>
          <div><RiskDot risk={h.risk} /></div>
          <div style={{ display: "flex", gap: 4 }}>
            {h.tags.map(t => <span key={t} className="tag" data-tag={t.toLowerCase().replace(/\s+/g, "-")}>{t}</span>)}
          </div>
        </div>
      </div>

      {/* Two-column content */}
      <div className="detail">
        <div className="detail-main">

          <div className="section">
            <div className="section-title">Core loop</div>
            <InlineField
              value={h.coreLoop}
              onSave={v => patchField("core_loop", v)}
              type="textarea"
              placeholder="Describe the core loop: player does X → gets Y → enables Z"
              rows={4}
            >
              <div className="coreloop-box">
                {h.coreLoop || <span style={{ color: "var(--text-4)" }}>Not defined yet.</span>}
              </div>
            </InlineField>
          </div>

          <div className="section">
            <div className="section-title">Summary</div>
            <InlineField
              value={h.summary}
              onSave={v => patchField("summary", v)}
              type="textarea"
              placeholder="One-paragraph description of the concept…"
              rows={3}
            >
              {h.summary
                ? <p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.6, color: "var(--text-2)" }}>{h.summary}</p>
                : <p style={{ margin: 0, fontSize: 13.5, color: "var(--text-4)", fontStyle: "italic" }}>No summary yet. Click to add one.</p>}
            </InlineField>
          </div>

          <div className="section">
            <div className="section-title">Metrics</div>
            <div className="metric-grid">
              <div className="metric-card">
                <div className="label">Primary</div>
                <InlineField
                  value={h.current !== "—" ? h.current : ""}
                  onSave={v => patchField("current_value", v)}
                  placeholder="—"
                >
                  <div className="value">{h.current === "—" ? "—" : h.current}</div>
                </InlineField>
                <div className={"sub " + (m.className === "delta-good" ? "good" : m.className === "delta-bad" ? "bad" : "")}>
                  target&nbsp;
                  <InlineField
                    value={h.target !== "—" ? h.target : ""}
                    onSave={v => patchField("target", v)}
                    placeholder="—"
                    style={{ display: "inline-flex" }}
                  >
                    <span>{h.target}</span>
                  </InlineField>
                  &nbsp;·&nbsp;
                  <InlineField
                    value={h.keyMetric !== "TBD" ? h.keyMetric : ""}
                    onSave={v => patchField("key_metric", v)}
                    placeholder="TBD"
                    style={{ display: "inline-flex" }}
                  >
                    <span>{h.keyMetric}</span>
                  </InlineField>
                </div>
              </div>
              <div className="metric-card">
                <div className="label">Assets</div>
                <div className="value">{assets.length || h.assets}</div>
                <div className="sub">files &amp; links</div>
              </div>
              <div className="metric-card">
                <div className="label">Stage</div>
                <div className="value" style={{ fontSize: 14, marginTop: 8 }}>
                  <StagePill stage={h.stage} stages={data.stages} />
                </div>
              </div>
              <div className="metric-card">
                <div className="label">Risk</div>
                <InlineField
                  value={h.risk}
                  onSave={v => patchField("risk", v)}
                  type="select"
                  options={[
                    { value: "low", label: "Low" },
                    { value: "med", label: "Medium" },
                    { value: "high", label: "High" },
                  ]}
                >
                  <div className="value" style={{ fontSize: 16, marginTop: 8 }}>
                    <RiskDot risk={h.risk} />
                  </div>
                </InlineField>
              </div>
            </div>
          </div>

          <div className="section">
            <div className="section-title">Stage timeline</div>
            <div className="timeline">
              {data.stages.map((s, i) => {
                const status = i < stageIdx ? "done" : i === stageIdx ? "current" : "";
                const item = historyMap[s.id];
                return (
                  <div key={s.id} className={"tl-item " + status}>
                    <div className="tl-head">
                      <span className="tl-stage">{s.label}</span>
                      <span className="tl-date">{item ? item.changed_at.slice(0, 10) : "—"}</span>
                    </div>
                    {item?.notes && <div className="tl-body">{item.notes}</div>}
                    {!item?.notes && status === "current" && (
                      <div className="tl-body" style={{ color: "var(--text-4)" }}>In progress.</div>
                    )}
                    {!item?.notes && status === "" && (
                      <div className="tl-body" style={{ color: "var(--text-4)" }}>Not yet reached.</div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>

          <div className="section">
            <div className="section-title">Creative tests</div>
            <CreativesPanel data={data} hypothesisId={h.id} />
          </div>

          <div className="section">
            <CommentsPanel data={data} hypothesisId={h.id} />
          </div>

        </div>

        {/* Side panel */}
        <aside className="detail-side">
          <div className="side-block">
            <div className="label">Actions</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              {canAdvance && (
                <button className="btn btn-primary" style={{ width: "100%", justifyContent: "center" }}
                  onClick={() => onAdvance && onAdvance(h.id, null)}>
                  Advance stage →
                </button>
              )}
              {canDecide && (
                <button className="btn btn-primary" style={{ width: "100%", justifyContent: "center" }}
                  onClick={() => onDecide && onDecide(h.id)}>
                  Make decision
                </button>
              )}
              {isDecided && (
                <div style={{ fontSize: 12, color: "var(--text-3)", padding: "4px 0" }}>
                  Decision recorded: <DecisionPill decision={h.decision} />
                </div>
              )}
              {!canAdvance && !canDecide && !isDecided && (
                <div style={{ fontSize: 12, color: "var(--text-4)" }}>No actions available.</div>
              )}
            </div>
          </div>

          <div className="side-block">
            <div className="label">Properties</div>
            <div className="kv-row">
              <span className="k">Author</span>
              <span className="v">
                <InlineField
                  value={String(h.author)}
                  onSave={v => patchField("author_id", parseInt(v))}
                  type="select"
                  options={data.authors.map(au => ({ value: String(au.id), label: au.name }))}
                >
                  {a && <span style={{ display: "flex", alignItems: "center", gap: 6 }}><Avatar author={a} />{a.name}</span>}
                </InlineField>
              </span>
            </div>
            <div className="kv-row"><span className="k">Started</span><span className="v">{formatDate(h.started)}</span></div>
            <div className="kv-row"><span className="k">Updated</span><span className="v">{formatDate(h.updated)}</span></div>
            <div className="kv-row">
              <span className="k">Risk</span>
              <span className="v">
                <InlineField
                  value={h.risk}
                  onSave={v => patchField("risk", v)}
                  type="select"
                  options={[
                    { value: "low", label: "Low" },
                    { value: "med", label: "Medium" },
                    { value: "high", label: "High" },
                  ]}
                >
                  <RiskDot risk={h.risk} />
                </InlineField>
              </span>
            </div>
            <div className="kv-row">
              <span className="k">Genre</span>
              <span className="v" style={{ minWidth: 0, overflow: "hidden" }}>
                <InlineTagField
                  value={h.tags}
                  allTags={data.tags}
                  onSave={v => patchField("tags", v)}
                />
              </span>
            </div>
            {h.pivotedFrom && <div className="kv-row"><span className="k">Pivot from</span><span className="v">{h.pivotedFrom}</span></div>}
            {h.pivotedTo && <div className="kv-row"><span className="k">Pivoted to</span><span className="v">{h.pivotedTo}</span></div>}
          </div>

          {(h.stage === "scale" || h.decision === "scale") && (
            <div className="handoff-card">
              <h4>{I.flag}<span>Scale handoff</span></h4>
              <p>Documents to transfer to the procurement system.</p>
              <ul className="handoff-list">
                <li><span className="doc">{I.doc} R&amp;D Passport</span><span className="status-x ok">Ready</span></li>
                <li><span className="doc">{I.doc} Metrics Brief</span><span className="status-x ok">Ready</span></li>
                <li><span className="doc">{I.doc} Tech &amp; Art Assessment</span><span className="status-x">Draft</span></li>
                <li><span className="doc">{I.doc} Resource Request</span><span className="status-x">Pending</span></li>
                <li><span className="doc">{I.doc} Risk Matrix</span><span className="status-x">Pending</span></li>
              </ul>
            </div>
          )}

          {canDecide && (
            <div className="side-block">
              <div className="label">Decision</div>
              <div style={{ display: "flex", gap: 6, marginTop: 4 }}>
                <button className="btn" style={{ flex: 1, color: "var(--kill)", borderColor: "color-mix(in oklch, var(--kill) 25%, var(--border))" }}
                  onClick={() => onDecide && onDecide(h.id)}>Kill</button>
                <button className="btn" style={{ flex: 1, color: "var(--pivot)", borderColor: "color-mix(in oklch, var(--pivot) 25%, var(--border))" }}
                  onClick={() => onDecide && onDecide(h.id)}>Pivot</button>
                <button className="btn btn-primary" style={{ flex: 1.2 }}
                  onClick={() => onDecide && onDecide(h.id)}>Scale →</button>
              </div>
            </div>
          )}

          <div className="side-block">
            <div className="label" style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
              <span>Assets &amp; links</span>
              <span style={{ cursor: "pointer", color: "var(--accent-text)", fontSize: 11, fontWeight: 500 }}
                onClick={() => setAddingAsset(v => !v)}>
                {addingAsset ? "cancel" : "+ add"}
              </span>
            </div>

            {addingAsset && (
              <form onSubmit={submitAsset} style={{ marginBottom: 10 }}>
                <input className="form-input" value={assetForm.name} onChange={e => setAssetForm(f => ({...f, name: e.target.value}))}
                  placeholder="Name" required style={{ marginBottom: 6 }} />
                <input className="form-input" value={assetForm.url} onChange={e => setAssetForm(f => ({...f, url: e.target.value}))}
                  placeholder="https://..." type="url" style={{ marginBottom: 6 }} />
                <div style={{ display: "flex", gap: 6 }}>
                  <select className="form-select" value={assetForm.asset_type}
                    onChange={e => setAssetForm(f => ({...f, asset_type: e.target.value}))} style={{ flex: 1 }}>
                    <option value="build">Build</option>
                    <option value="pitch">Pitch</option>
                    <option value="prompt">Prompt</option>
                    <option value="code">Code</option>
                    <option value="apk">APK</option>
                    <option value="analytics">Analytics</option>
                    <option value="mockup">Mockup</option>
                    <option value="doc">Doc</option>
                    <option value="other">Other</option>
                  </select>
                  <button type="submit" className="btn btn-primary" style={{ flexShrink: 0 }}>Add</button>
                </div>
              </form>
            )}

            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              {assets.length === 0 && !addingAsset && (
                <div style={{ color: "var(--text-4)", fontSize: 12 }}>No assets yet.</div>
              )}
              {assets.map(asset => (
                <div key={asset.id} className="kv-row" style={{ alignItems: "center" }}>
                  <span className="k" style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    {I.link}
                    {asset.url
                      ? <a href={asset.url} target="_blank" rel="noreferrer" style={{ color: "var(--text)", textDecoration: "none" }}>{asset.name}</a>
                      : asset.name
                    }
                  </span>
                  <span style={{ display: "flex", gap: 8, alignItems: "center" }}>
                    {asset.url && <span className="v">↗</span>}
                    <span style={{ cursor: "pointer", color: "var(--kill)", fontSize: 11 }}
                      onClick={() => deleteAsset(asset.id)}>✕</span>
                  </span>
                </div>
              ))}
            </div>
          </div>
        </aside>
      </div>
    </div>
  );
}

window.PRPassport = { PassportView };
