/* Manual price editor — v2 elevated layout.
   Same data model; only the visual shell changes. */

const { useState: useStateP, useMemo: useMemoP, useEffect: useEffectP } = React;

function PricesPanel({ ctx, sheetPrices, manualPrices, setManualPrices, currency, webhookUrl, feedState, refreshFromSheet }) {
  const sp = sheetPrices || ctx.prices;
  const [search, setSearch] = useStateP('');
  const [filter, setFilter] = useStateP('missing'); // missing | overridden | all
  const [edits, setEdits] = useStateP({});
  const [writeStatus, setWriteStatus] = useStateP({});
  const [writeError, setWriteError] = useStateP({});

  const usageList = useMemoP(() => {
    const usage = new Map();
    const names = new Map();
    for (const r of ctx.recipes) {
      for (const m of r.materials) {
        usage.set(m.itemType, (usage.get(m.itemType) || 0) + 1);
        names.set(m.itemType, m.name);
      }
    }
    let list = [];
    for (const [id, count] of usage.entries()) {
      const hasHard = window.HARDCODED_PRICES[id] != null;
      const hasSheet = sp[id] != null;
      const hasManual = manualPrices[id] != null;
      list.push({
        id, count,
        name: names.get(id) || `Item ${id}`,
        sheet: sp[id],
        manual: manualPrices[id],
        volume: ctx.volumes ? ctx.volumes[id] : null,
        hardcoded: hasHard,
        missing: !hasSheet && !hasManual && !hasHard,
        overridden: hasManual,
      });
    }
    list.sort((a, b) => b.count - a.count);
    return list;
  }, [ctx, sp, manualPrices]);

  const filtered = useMemoP(() => {
    const s = search.trim().toLowerCase();
    return usageList.filter(item => {
      if (filter === 'missing' && !item.missing) return false;
      if (filter === 'overridden' && !item.overridden) return false;
      if (s && !item.name.toLowerCase().includes(s) && !item.id.toString().includes(s)) return false;
      return true;
    });
  }, [usageList, search, filter]);

  const missingCount  = useMemoP(() => usageList.filter(x => x.missing).length, [usageList]);
  const overrideCount = useMemoP(() => usageList.filter(x => x.overridden).length, [usageList]);
  const sheetCount    = useMemoP(() => usageList.filter(x => x.sheet != null).length, [usageList]);
  const coverage      = usageList.length > 0
    ? Math.round((usageList.length - missingCount) / usageList.length * 100)
    : 100;

  const [shown, setShown] = useStateP(80);
  useEffectP(() => setShown(80), [search, filter]);

  async function commit(id, raw, name) {
    const v = raw === '' || raw == null ? null : parseFloat(raw);
    if (v == null) {
      setManualPrices(prev => { const c = { ...prev }; delete c[id]; return c; });
      setEdits(e => { const c = { ...e }; delete c[id]; return c; });
      return;
    }
    if (!Number.isFinite(v) || v < 0) return;
    setManualPrices(prev => ({ ...prev, [id]: v }));
    setEdits(e => { const c = { ...e }; delete c[id]; return c; });
    if (webhookUrl && webhookUrl.trim()) {
      setWriteStatus(prev => ({ ...prev, [id]: 'pending' }));
      setWriteError(prev => { const c = { ...prev }; delete c[id]; return c; });
      try {
        await window.writePriceToSheet(webhookUrl, id, name, v);
        setWriteStatus(prev => ({ ...prev, [id]: 'ok' }));
      } catch (err) {
        setWriteStatus(prev => ({ ...prev, [id]: 'error' }));
        setWriteError(prev => ({ ...prev, [id]: err.message }));
      }
    }
  }

  function clearAll() {
    if (confirm(`Clear all ${overrideCount} manual prices? This cannot be undone.`)) {
      setManualPrices({});
    }
  }

  return (
    <main className="detail prices-view v2">
      <div className="fade-in">

        {/* ── Page hero ─────────────────────────────────────────────── */}
        <div className="page-hero">
          <div className="page-hero-crest" aria-hidden>⚖</div>
          <div className="page-hero-meta">
            <div className="page-hero-eyebrow">Manual Ledger</div>
            <h1 className="page-hero-title">
              Price <em>Entry</em>
            </h1>
            <div className="page-hero-tags">
              <span><strong style={{color:'var(--parch)'}}>{usageList.length.toLocaleString()}</strong>&nbsp;unique items in recipes</span>
              <span className="dot" />
              {feedState && feedState.state === 'live' ? (
                <span className="pill" style={{color: 'var(--emerald)', borderColor: 'rgba(111,185,106,0.4)'}}>
                  ● Live · {feedState.lastUpdated || 'just synced'}
                </span>
              ) : feedState && feedState.state === 'loading' ? (
                <span className="pill" style={{color: 'var(--gold)'}}>⟳ {feedState.msg || 'Loading…'}</span>
              ) : (
                <span className="pill" style={{color: 'var(--garnet)', borderColor: 'rgba(213,106,106,0.4)'}}>
                  ⚠ {(feedState && feedState.msg) || 'Sheet unreachable'}
                </span>
              )}
              {webhookUrl && webhookUrl.trim() && (
                <>
                  <span className="dot" />
                  <span className="pill" style={{color: 'var(--sapphire)'}}>↑ Writeback on</span>
                </>
              )}
            </div>
          </div>
          <div className="page-hero-aside">
            <div className="hero-aside-card">
              <div className="hero-aside-label">Coverage</div>
              <div className="hero-aside-value">
                <span>{coverage}</span>
                <span className="unit">%</span>
              </div>
              <div className={`hero-aside-foot ${coverage >= 90 ? 'pos' : coverage >= 50 ? '' : 'neg'}`}>
                {missingCount === 0
                  ? 'every recipe input is priced'
                  : `${missingCount.toLocaleString()} item${missingCount === 1 ? '' : 's'} still missing`}
              </div>
            </div>
          </div>
        </div>

        {/* ── Hero metric strip ────────────────────────────────────── */}
        <div className="metric-strip">
          <div className="metric-cell hero accent">
            <div className="ms-label">Coverage</div>
            <div className="ms-value">
              <span>{usageList.length - missingCount}</span>
              <span className="unit">/&thinsp;{usageList.length}</span>
            </div>
            <div className="ms-sub">items with any price</div>
          </div>
          <div className={`metric-cell ${missingCount > 0 ? 'neg' : 'pos'}`}>
            <div className="ms-label">Missing</div>
            <div className="ms-value">
              <span>{missingCount.toLocaleString()}</span>
              <span className="unit">unpriced</span>
            </div>
            <div className="ms-sub">{missingCount === 0 ? '✓ complete' : 'enter values below'}</div>
          </div>
          <div className="metric-cell">
            <div className="ms-label">From sheet</div>
            <div className="ms-value">
              <span>{sheetCount.toLocaleString()}</span>
              <span className="unit">items</span>
            </div>
            <div className="ms-sub">7-day average feed</div>
          </div>
          <div className="metric-cell">
            <div className="ms-label">Your overrides</div>
            <div className="ms-value">
              <span>{overrideCount}</span>
              <span className="unit">manual</span>
            </div>
            <div className="ms-sub">stored locally{webhookUrl && webhookUrl.trim() ? ' · synced to sheet' : ''}</div>
          </div>
        </div>

        {/* ── Filter & search bar ──────────────────────────────────── */}
        <div className="modebar-v2">
          <div className="toggle-stack" style={{flex: 1, minWidth: 280}}>
            <div className="toggle-stack-label">Search</div>
            <div className="sb-search-field" style={{position: 'relative'}}>
              <span className="sb-search-icon">
                <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
                  <circle cx="7" cy="7" r="5" />
                  <line x1="11" y1="11" x2="14" y2="14" />
                </svg>
              </span>
              <input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Search by name or item ID…"
                style={{
                  width: '100%', background: 'var(--bg-night)', border: '1px solid var(--line-strong)',
                  color: 'var(--parch)', fontFamily: 'var(--sans)', fontSize: 13,
                  padding: '10px 36px 10px 36px', borderRadius: 4, outline: 'none', height: 36
                }}
              />
              {search && (
                <button type="button" className="sb-search-clear" onClick={() => setSearch('')} aria-label="Clear search" title="Clear search">✕</button>
              )}
            </div>
          </div>
          <div className="toggle-stack">
            <div className="toggle-stack-label">Filter</div>
            <div className="chip-row" style={{height: 36, alignItems: 'center'}}>
              <button className={`chip ${filter === 'missing' ? 'on' : ''}`} onClick={() => setFilter('missing')}>
                Missing <span className="chip-count">· {missingCount}</span>
              </button>
              <button className={`chip ${filter === 'overridden' ? 'on' : ''}`} onClick={() => setFilter('overridden')}>
                Yours <span className="chip-count">· {overrideCount}</span>
              </button>
              <button className={`chip ${filter === 'all' ? 'on' : ''}`} onClick={() => setFilter('all')}>
                All <span className="chip-count">· {usageList.length.toLocaleString()}</span>
              </button>
            </div>
          </div>
          <div className="toggle-stack">
            <div className="toggle-stack-label">Actions</div>
            <div className="chip-row" style={{height: 36, alignItems: 'center'}}>
              {refreshFromSheet && (
                <button className="chip" onClick={refreshFromSheet} title="Re-fetch live prices from the shared sheet">↻ Refresh</button>
              )}
              {overrideCount > 0 && (
                <button className="chip" onClick={clearAll}>Clear local</button>
              )}
            </div>
          </div>
        </div>

        {/* ── Framed ledger table ──────────────────────────────────── */}
        <div className="framed-section">
          <div className="framed-section-head">
            <span className="fs-eyebrow">Ledger</span>
            <span className="fs-title">
              {filter === 'missing'    ? 'Missing prices'
              : filter === 'overridden' ? 'Your overrides'
              :                            'All recipe inputs'}
            </span>
            <span className="fs-rule" />
            <span className="fs-aside">{filtered.length.toLocaleString()} of {usageList.length.toLocaleString()} · most-used first</span>
          </div>

          <div className="framed-section-body">
            <div className="prices-table">
              <div className="prices-row prices-head">
                <div>Item</div>
                <div className="num">ID</div>
                <div className="num">Used in</div>
                <div className="num">Volume/day</div>
                <div className="num">Sheet ({currency})</div>
                <div className="num">Your price ({currency})</div>
                <div className="num">Effective</div>
              </div>
              {filtered.slice(0, shown).map(item => {
                const effective = window.HARDCODED_PRICES[item.id] != null
                  ? window.HARDCODED_PRICES[item.id]
                  : (item.manual != null ? item.manual : item.sheet);
                const editing = edits[item.id];
                const display = editing != null ? editing : (item.manual != null ? String(item.manual) : '');
                return (
                  <div className={`prices-row ${item.missing ? 'missing' : ''} ${item.overridden ? 'overridden' : ''}`} key={item.id}>
                    <div className="pri-name">
                      <window.ItemIcon itemType={item.id} name={item.name} size="sm" />
                      <div>
                        <div className="ing-label">{item.name}</div>
                        <div className="ing-meta">
                          {item.hardcoded  && <span className="tag-hard">Fixed · system</span>}
                          {item.missing    && <span className="nomarket">no price recorded</span>}
                          {item.overridden && <span className="craftable">your override</span>}
                        </div>
                      </div>
                    </div>
                    <div className="num mono">{item.id}</div>
                    <div className="num mono">{item.count.toLocaleString()}</div>
                    <div className="num mono" style={{color: item.volume != null ? 'var(--parch-3)' : 'var(--muted)'}} title={item.volume != null ? `${item.volume.v.toLocaleString()} units/${item.volume.p}` : ''}>
                      {item.volume != null ? (
                        <>
                          {window.fmtCompact(item.volume.v)}
                          <span style={{fontSize: 9, color: 'var(--muted)', marginLeft: 4, letterSpacing: '0.05em'}}>
                            /{item.volume.p === 'week' ? 'wk' : 'day'}
                          </span>
                        </>
                      ) : '—'}
                    </div>
                    <div className="num mono" style={{color: item.sheet != null ? 'var(--parch)' : 'var(--muted)'}}>
                      {item.sheet != null ? fmtG(item.sheet) : '—'}
                    </div>
                    <div className="num">
                      {item.hardcoded ? (
                        <span style={{color: 'var(--muted)', fontStyle: 'italic', fontSize: 11}}>locked</span>
                      ) : (
                        <span className={`price-edit ${item.manual != null ? 'modified' : ''}`} style={{padding: '4px 10px'}}>
                          <input
                            type="number"
                            step="0.0001"
                            min="0"
                            value={display}
                            placeholder={item.sheet != null ? fmtG(item.sheet) : 'enter price'}
                            onChange={(e) => setEdits(prev => ({ ...prev, [item.id]: e.target.value }))}
                            onBlur={(e) => commit(item.id, e.target.value, item.name)}
                            onKeyDown={(e) => { if (e.key === 'Enter') e.target.blur(); }}
                          />
                          <span className="cur">{currency}</span>
                          {writeStatus[item.id] === 'pending' && <span className="write-status pending" title="Writing to sheet…">⟳</span>}
                          {writeStatus[item.id] === 'ok' && <span className="write-status ok" title="Saved to sheet">✓</span>}
                          {writeStatus[item.id] === 'error' && <span className="write-status err" title={writeError[item.id] || 'Write failed'}>!</span>}
                        </span>
                      )}
                    </div>
                    <div className="num mono" style={{color: effective != null ? 'var(--view-accent)' : 'var(--garnet)', fontWeight: 500}}>
                      {effective != null ? fmtG(effective) + currency : 'unset'}
                    </div>
                  </div>
                );
              })}
              {filtered.length === 0 && (
                <div style={{padding: '60px 20px', textAlign: 'center', color: 'var(--muted)', fontSize: 13}}>
                  {filter === 'missing' && missingCount === 0
                    ? '🎉 Every item used in a recipe has a price.'
                    : 'No items match your filters.'}
                </div>
              )}
              {filtered.length > shown && (
                <button className="sb-loadmore" onClick={() => setShown(s => s + 80)} style={{maxWidth: 'unset', width: 'calc(100% - 20px)', margin: '16px 10px'}}>
                  Show {Math.min(80, filtered.length - shown)} more
                </button>
              )}
            </div>
          </div>
        </div>

        {/* ── Notes ────────────────────────────────────────────────── */}
        <div className="notes-panel">
          <div className="notes-label">Notes</div>
          Prices are entered in <strong>gold</strong> (decimal). For copper/silver: 100 copper = 1 silver, 100 silver = 1 gold — so <span className="mono" style={{color: 'var(--parch)'}}>0.01g = 1 silver</span> and <span className="mono" style={{color: 'var(--parch)'}}>0.0001g = 1 copper</span>. <em>Coin (ID 500) is fixed at 1 copper by the system.</em>
          <br />
          The <strong>Sheet</strong> column shows live values fetched from the hardcoded shared price spreadsheet (7-day average, with 30-day fallback). Click <strong>↻ Refresh</strong> above to re-pull.
          {webhookUrl && webhookUrl.trim() ? (
            <><br /><span style={{color: 'var(--emerald)'}}>Sheet writeback is enabled</span> — your entries are also saved to the shared spreadsheet so friends will see them on next refresh.</>
          ) : (
            <><br />Your entries are saved only in this browser. To share prices with friends, set up an Apps Script webhook URL in Tweaks.</>
          )}
        </div>
      </div>
    </main>
  );
}

window.PricesPanel = PricesPanel;
