/* positions.jsx — Open Positions tab.
   Left: sortable table of active positions with expandable parser detail.
   Right: Latest Position Events rail (live ticking).
*/

function ActionCell({ action, confidence }) {
  return (
    <div className="flex gap-12" style={{ alignItems: "center" }}>
      <ActionPill kind={action} />
    </div>
  );
}

function ParserDetail({ event }) {
  if (!event) return null;
  return (
    <div className="parser-detail">
      <div>
        <h4>Raw Discord message</h4>
        <div className="raw-msg">{event.raw}</div>
        <div className="meta-row">
          <span>channel <strong>{event.channel}</strong></span>
          <span>msg <strong className="mono">{event.messageId}</strong></span>
          <span>scraped <strong>{fmtTime(event.ts)}</strong></span>
        </div>
        <h4 style={{ marginTop: 18 }}>Why Claude tagged this</h4>
        <div className="reasoning">
          {event.reasoning.summary.split(/("[^"]+")/).map((part, i) =>
            part.startsWith('"') ? <span key={i} className="highlight">{part}</span> : <span key={i}>{part}</span>
          )}
        </div>
      </div>
      <div>
        <h4>Extracted event JSON</h4>
        <pre>{
`{
  `}<span className="k">"ticker"</span>{`:     `}<span className="s">"{event.ticker}"</span>{`,
  `}<span className="k">"action"</span>{`:     `}<span className="s">"{event.action}"</span>{`,
  `}<span className="k">"direction"</span>{`:  `}<span className="s">"{event.direction}"</span>{`,
  `}<span className="k">"contract"</span>{`:   `}<span className="s">{event.contract ? `"${event.contract}"` : "null"}</span>{`,
  `}<span className="k">"price"</span>{`:      `}<span className="n">{event.price == null ? "null" : event.price.toFixed(2)}</span>{`,
  `}<span className="k">"confidence"</span>{`: `}<span className="s">"{event.confidence}"</span>{`,
  `}<span className="k">"raw_note"</span>{`:   `}<span className="s">"{event.raw.length > 60 ? event.raw.slice(0, 57) + "…" : event.raw}"</span>{`,
  `}<span className="k">"matched"</span>{`:    [`}{event.reasoning.matched.map((m, i) => [
            i ? <span key={"c"+i}>, </span> : null,
            <span key={"v"+i} className="s">"{m}"</span>
          ])}{`]
}`}</pre>
        <div className="meta-row">
          <span>model <strong>claude-haiku-4-5</strong></span>
          <span>latency <strong>{(280 + (event.id.charCodeAt(4)*7 % 220))}ms</strong></span>
          <span>tokens <strong>{120 + (event.id.charCodeAt(5) % 80)}</strong></span>
        </div>
      </div>
    </div>
  );
}

// Every interaction with a trade (open / add / trim / close…), in order.
function TradeTimeline({ events }) {
  const ordered = [...events].sort((a, b) => a.ts - b.ts);
  return (
    <div className="trade-timeline">
      {ordered.map((e, i) => {
        // Exits (trim/cut/close) are always a fill ("@"); only an open holding
        // carries a mark ("-> n"). Tolerate older data that mis-filed an "@".
        const exitAction = ["close", "cut", "trim"].includes(e.action);
        const fill = e.price != null ? e.price : (exitAction ? e.currentPrice : null);
        const mark = (!exitAction && e.currentPrice != null) ? e.currentPrice : null;
        return (
          <div key={e.id || i} className="tl-row">
            <span className="tl-time mono">{new Date(e.ts).toLocaleString("en-US", { month: "numeric", day: "numeric", hour: "numeric", minute: "2-digit" })}</span>
            <ActionPill kind={e.action} />
            <span className="tl-detail mono">
              {isOption(e) && contractText(e) ? <span className="contract">{contractText(e)}</span> : <span style={{ color: "var(--fg-3)" }}>shares</span>}
              {fill != null && <span> @ {fmtNum(fill)}</span>}
              {mark != null && <span style={{ color: "var(--fg-2)" }}> → {fmtNum(mark)}</span>}
              {e.avgPrice != null && <span style={{ color: "var(--c-watch)" }}> · avg {fmtNum(e.avgPrice)}</span>}
            </span>
            <span className="tl-note">{e.raw}</span>
          </div>
        );
      })}
    </div>
  );
}

function Positions({ positions, events, analysts, filter, days, minTrades, onPickTicker, onOpenChart, showParser }) {
  const [sort, setSort] = useState({ key: "updatedTs", dir: "desc" });
  const [expanded, setExpanded] = useState(null);
  const [inst, setInst] = useState("all");

  const cutoff = Date.now() - days * 86400000;

  const filteredPositions = useMemo(() => {
    const fl = filter.toLowerCase().trim();
    return positions
      .filter(p => p.status !== "closed" && p.status !== "expired")
      .filter(p => p.updatedTs >= cutoff)
      .filter(p => p.events.length >= minTrades)
      .filter(p => matchesInstrument(p, inst))
      .filter(p => {
        if (!fl) return true;
        return p.analyst.toLowerCase().includes(fl) || p.ticker.toLowerCase().includes(fl);
      });
  }, [positions, filter, cutoff, minTrades, inst]);

  const sorted = useMemo(() => {
    const arr = [...filteredPositions];
    const dir = sort.dir === "asc" ? 1 : -1;
    arr.sort((a, b) => {
      const av = a[sort.key], bv = b[sort.key];
      if (typeof av === "number" && typeof bv === "number") return (av - bv) * dir;
      return String(av || "").localeCompare(String(bv || "")) * dir;
    });
    return arr;
  }, [filteredPositions, sort]);

  function setSortKey(k) {
    setSort(s => s.key === k ? { ...s, dir: s.dir === "asc" ? "desc" : "asc" } : { key: k, dir: "desc" });
  }
  const sortInd = (k) => sort.key === k ? (sort.dir === "asc" ? "↑" : "↓") : "↕";

  return (
    <div className="panel">
      <div className="panel-hdr">
        <div className="panel-title">Open Positions</div>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <InstrumentFilter value={inst} onChange={setInst} />
          <div className="panel-meta">{sorted.length} active</div>
        </div>
      </div>
      <div className="scroll-y">
        <table className="tbl tbl-fixed">
          <colgroup>
            <col style={{ width: "11%" }} />
            <col style={{ width: "7%" }} />
            <col style={{ width: "13%" }} />
            <col style={{ width: "14%" }} />
            <col style={{ width: "10%" }} />
            <col style={{ width: "8%" }} />
            <col style={{ width: "7%" }} />
            <col style={{ width: "26%" }} />
            <col style={{ width: "4%" }} />
          </colgroup>
          <thead>
            <tr>
              <th onClick={() => setSortKey("analyst")} className={cx("sortable", sort.key==="analyst" && "active")}>Analyst <span className="sort-ind">{sortInd("analyst")}</span></th>
              <th onClick={() => setSortKey("ticker")} className={cx("sortable", sort.key==="ticker" && "active")}>Ticker <span className="sort-ind">{sortInd("ticker")}</span></th>
              <th>Instrument</th>
              <th onClick={() => setSortKey("entryPrice")} className={cx("sortable num", sort.key==="entryPrice" && "active")} style={{textAlign:"right"}}>Entry → Now <span className="sort-ind">{sortInd("entryPrice")}</span></th>
              <th onClick={() => setSortKey("updatedTs")} className={cx("sortable", sort.key==="updatedTs" && "active")}>Updated <span className="sort-ind">{sortInd("updatedTs")}</span></th>
              <th onClick={() => setSortKey("lastAction")} className={cx("sortable", sort.key==="lastAction" && "active")}>Action <span className="sort-ind">{sortInd("lastAction")}</span></th>
              <th onClick={() => setSortKey("lastConfidence")} className={cx("sortable", sort.key==="lastConfidence" && "active")}>Conf <span className="sort-ind">{sortInd("lastConfidence")}</span></th>
              <th>Last alert</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {sorted.flatMap(p => {
              const isExpanded = expanded === p.key;
              const lastEvent = p.events[p.events.length-1];
              const rows = [
                <tr key={p.key} className={cx(isExpanded && "expanded")} onClick={() => setExpanded(isExpanded ? null : p.key)}>
                  <td><AnalystChip analyst={p.analyst} analysts={analysts} /></td>
                  <td><span className="ticker">${p.ticker}</span></td>
                  <td><InstrumentCell event={p} /></td>
                  <td className="num" style={{ whiteSpace: "nowrap" }}>
                    {(() => {
                      const basis = p.avgPrice != null ? p.avgPrice : p.entryPrice;
                      if (!basis) return "—";
                      return (
                        <>
                          {fmtNum(basis)}
                          {p.avgPrice != null && <span style={{ fontSize: 10, color: "var(--fg-3)", marginLeft: 3 }}>avg</span>}
                          {p.markPrice != null && (() => {
                            const up = p.markPrice >= basis;
                            const pnl = (p.markPrice - basis) / basis;
                            return (
                              <span style={{ color: up ? "var(--c-up)" : "var(--c-down)", marginLeft: 5 }}>
                                → {fmtNum(p.markPrice)} <span style={{ fontSize: 11 }}>({fmtPct(pnl)})</span>
                              </span>
                            );
                          })()}
                        </>
                      );
                    })()}
                  </td>
                  <td className="muted mono" style={{ whiteSpace: "nowrap" }}>{fmtTime(p.updatedTs, {short:true})}</td>
                  <td><ActionPill kind={p.lastAction} /></td>
                  <td><ConfPill level={p.lastConfidence} /></td>
                  <td className="muted" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.lastNote}</td>
                  <td style={{ textAlign: "center" }}><button className="icon-btn" title="Open chart" onClick={(e) => { e.stopPropagation(); onOpenChart && onOpenChart(p.ticker); }}>{I("chart", { size: 15 })}</button></td>
                </tr>
              ];
              if (isExpanded) {
                rows.push(
                  <tr key={p.key + "_x"} className="expand-row">
                    <td colSpan="9" style={{ padding: 0, borderBottom: "1px solid var(--border-2)" }}>
                      <div className="position-detail">
                        <h4 className="pd-title">All interactions · {p.events.length}</h4>
                        <TradeTimeline events={p.events} />
                      </div>
                      {showParser && <ParserDetail event={lastEvent} />}
                    </td>
                  </tr>
                );
              }
              return rows;
            })}
            {sorted.length === 0 && (
              <tr><td colSpan="9"><Empty msg="No positions match this filter." /></td></tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function EventRail({ events, analysts, onClickEvent }) {
  return (
    <div className="panel">
      <div className="panel-hdr">
        <div className="panel-title">Latest Position Events</div>
        <div className="panel-meta">{events.length} parsed</div>
      </div>
      <div className="scroll-y">
        {events.slice(0, 60).map((e, i) => (
          <div key={e.id} className={cx("event", i === 0 && e.__fresh && "slide-in")} onClick={() => onClickEvent(e)}>
            <div className="e-analyst" style={{ color: analysts.find(a => a.handle === e.analyst)?.color || "var(--accent)" }}>{e.analyst}</div>
            <div className="e-time">{fmtTime(e.ts, {short:true})}</div>
            <div className="e-ticker">${e.ticker}</div>
            <div className="e-pill"><ActionPill kind={e.action} /></div>
            <div className="e-note">{e.contract ? <span className="contract">{e.contract}</span> : null} {e.contract && <span style={{ color: "var(--fg-3)", margin: "0 6px" }}>·</span>}<span style={{ color: "var(--fg-1)" }}>{e.raw}</span></div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Positions, EventRail, ParserDetail, TradeTimeline });
