/* 详细机型库（壳内层）— 品牌 logo 网格 →（品牌卡 morph 展开）品牌机型缩略图网格 → 机型详情 sheet；按价格分组视图。
   数据：BRANDS/DB_STATS（dbdata.jsx，_mkdb.py 从本地 db dump 生成）；DBTV（data.jsx）补 6 台演示机的面板/亮点。
   dump 只有价格/尺寸 —— 详情里其余规格为演示值：面板按品牌×系列推断，指标按价位档生成（id 作种子，刷新稳定）。
   深链：?tool=db · &dbv=price · &b=品牌中文名 */
const dbCx = (...a) => a.filter(Boolean).join(' ');
const dbQ = (k) => new URLSearchParams(location.search).get(k);
const DB_REDUCE = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
const DBTV_DETAIL = {};
DBTV.forEach((t) => { DBTV_DETAIL[t.id] = t; });

const DB_PRICE_BUCKETS = [
  { label: '5 千内', test: (p) => p < 5000 },
  { label: '5 千 – 1 万', test: (p) => p >= 5000 && p < 10000 },
  { label: '1 – 2 万', test: (p) => p >= 10000 && p < 20000 },
  { label: '2 万以上', test: (p) => p >= 20000 },
];

/* 演示规格生成 —— 同一机型永远得到同一组值 */
const dbSeed = (id) => { let x = id % 233280; return () => (x = (x * 9301 + 49297) % 233280) / 233280; };
function dbSpec(b, m) {
  const det = DBTV_DETAIL[m.id];
  const rnd = dbSeed(m.id);
  const est = m.price || Math.round(m.size * m.size * 1.15); /* 未录价按尺寸估档 */
  const tier = est >= 20000 ? 3 : est >= 10000 ? 2 : est >= 5000 ? 1 : 0;
  let panel = det && det.panel;
  if (!panel) {
    if (b.zh === 'LG') panel = 'OLED';
    else if (b.zh === '索尼') panel = /A9|BRAVIA 8/i.test(m.m) ? 'QD-OLED' : 'MiniLED';
    else if (b.zh === '三星') panel = /S9/i.test(m.m) ? 'QD-OLED' : 'MiniLED';
    else panel = tier === 0 ? 'QLED' : 'MiniLED';
  }
  const oled = /OLED/i.test(panel);
  const mini = /Mini/i.test(panel);
  const zones = oled ? '逐像素' : mini ? `${[288, 640, 1440, 2560][tier] + Math.round(rnd() * 10) * 32} 区` : '—';
  const nits = oled ? 950 + tier * 350 + Math.round(rnd() * 6) * 50
                    : [550, 1300, 2800, 4600][tier] + Math.round(rnd() * 8) * 50;
  const de = ((oled ? 0.9 : 1.4) + (3 - tier) * .35 + rnd() * .6).toFixed(1);
  const hz = tier >= 2 ? 144 : 120;
  /* SPEC_REAL（data.jsx）锁定值压过价位档演示值 —— 与 Agent 卡片同一口径，避免同屏两套数 */
  return { panel, zones, nits, de, hz, hl: det && det.hl, ...(SPEC_REAL[m.id] || {}) };
}

const dbPrice = (p) => p > 0 ? `¥${p.toLocaleString()}` : '未录价';

/* 缩略图卡（品牌详情网格）：CSS 绘制的电视正面 —— 品牌色氛围光 + 尺寸 + 面板徽标 */
function DbModelCard({ b, m, onOpen }) {
  const sp = dbSpec(b, m);
  return (
    <button className="mcard" onClick={() => onOpen({ b, m })}>
      <span className="mc-thumb" style={{ '--bc': b.color }}>
        <em className="mc-panel">{sp.panel}</em>
        <b className="mc-size">{m.size}<i>″</i></b>
      </span>
      <b className="mc-name">{m.m}</b>
      <small className={dbCx('mc-price', !(m.price > 0) && 'na')}>{dbPrice(m.price)}</small>
    </button>
  );
}

function DbModelRow({ b, m, onOpen }) {
  const det = DBTV_DETAIL[m.id];
  const sub = [det && det.panel, m.size && `${m.size}″`, det && det.hl].filter(Boolean).join(' · ');
  return (
    <button className="db-row" onClick={() => onOpen({ b, m })}>
      <div className="dbr-tt">
        <b>{b.zh} {m.m}</b>
        {sub && <small>{sub}</small>}
      </div>
      <span className={dbCx('dbr-p', !(m.price > 0) && 'na')}>{dbPrice(m.price)}</span>
    </button>
  );
}

/* 机型详情 sheet：价格 + 六格规格 */
function DbDetailSheet({ sel, closing, onClose }) {
  const { b, m } = sel;
  const sp = dbSpec(b, m);
  const cells = [
    ['面板类型', sp.panel],
    ['峰值亮度', `${sp.nits} nit`],
    ['控光分区', sp.zones],
    ['色准 ΔE', sp.de],
    ['尺寸', `${m.size}″`],
    ['刷新率', `${sp.hz} Hz`],
  ];
  return (
    <div className={dbCx('mdet-wrap', closing && 'out')} onClick={onClose}>
      <div className="mdet" onClick={(e) => e.stopPropagation()}>
        <span className="mdet-bar"></span>
        <div className="mdet-head">
          <div className="mdet-tt">
            <b>{b.zh} {m.m}</b>
            <small>{sp.hl || '实测详情逐步入库中'}</small>
          </div>
          <span className={dbCx('mdet-p', !(m.price > 0) && 'na')}>{dbPrice(m.price)}</span>
        </div>
        <div className="mdet-grid">
          {cells.map(([k, v]) => (
            <div key={k} className="mdet-cell"><small>{k}</small><b>{v}</b></div>
          ))}
        </div>
      </div>
    </div>
  );
}

const DB_HUB_MODEL_IDS = [
  10000788, /* 海信 85 E8S */
  10000227, /* TCL 85 Q9L PRO */
  10000443, /* 小米 S Pro 85 Mini LED */
  10000445, /* 雷鸟 鹤6 Ultra */
  10000222, /* VIDDA 发现 X Pro */
  10000455, /* LG 83 C5 */
];

function dbFindModel(id) {
  for (const b of BRANDS) {
    const m = b.models.find((item) => item.id === id);
    if (m) return { b, m };
  }
  return null;
}

function DbModelPicker({ side, current, onPick, onClose }) {
  const candidates = DB_HUB_MODEL_IDS.map(dbFindModel).filter(Boolean);
  return (
    <div className="dbpick-wrap" onClick={onClose}>
      <section className="dbpick" onClick={(e) => e.stopPropagation()} aria-label={`选择${side === 'left' ? '左侧' : '右侧'}电视`}>
        <span className="mdet-bar"></span>
        <div className="dbpick-head">
          <div><b>选择{side === 'left' ? '左侧' : '右侧'}电视</b><small>从实测在库机型中选择</small></div>
          <button onClick={onClose} aria-label="关闭机型选择"><Icon name="x" size={16} /></button>
        </div>
        <div className="dbpick-list">
          {candidates.map(({ b, m }) => {
            const sp = dbSpec(b, m);
            const active = current && current.m.id === m.id;
            return (
              <button key={m.id} className={dbCx('dbpick-row', active && 'on')} onClick={() => onPick({ b, m })}>
                <span className="dbpick-check"><Icon name={active ? 'check' : 'tv'} size={14} /></span>
                <span className="dbpick-copy"><b>{b.zh} {m.m}</b><small>{m.size ? `${m.size}″ · ` : ''}{sp.panel} · {sp.hz} Hz</small></span>
                <em>{dbPrice(m.price)}</em>
              </button>
            );
          })}
        </div>
      </section>
    </div>
  );
}

function DbRankingSheet({ onClose, onLibrary }) {
  const rows = [
    { id: 10000788, score: '9.2', why: '亮厅画质领先' },
    { id: 10000227, score: '8.7', why: '综合表现均衡' },
    { id: 10000443, score: '8.5', why: '游戏体验突出' },
  ].map((item) => ({ ...item, found: dbFindModel(item.id) })).filter((item) => item.found);
  return (
    <div className="dbrank-wrap" onClick={onClose}>
      <section className="dbrank" onClick={(e) => e.stopPropagation()} aria-label="实测排行榜">
        <span className="mdet-bar"></span>
        <div className="dbpick-head">
          <div><b>实测排行榜</b><small>综合画质与场景表现</small></div>
          <button onClick={onClose} aria-label="关闭排行榜"><Icon name="x" size={16} /></button>
        </div>
        <div className="dbrank-list">
          {rows.map(({ id, score, why, found }, index) => (
            <div className="dbrank-row" key={id}>
              <span>{index + 1}</span>
              <div><b>{found.b.zh} {found.m.m}</b><small>{why}</small></div>
              <em>{score}</em>
            </div>
          ))}
        </div>
        <button className="dbrank-all" onClick={onLibrary}>进入全部机型 <Icon name="chevRight" size={14} /></button>
      </section>
    </div>
  );
}

function DbHub({ onBack, onTools, onLibrary }) {
  const { useState } = React;
  const [left, setLeft] = useState(dbFindModel(10000788));
  const [right, setRight] = useState(dbFindModel(10000227));
  const [picker, setPicker] = useState(null);
  const [ranking, setRanking] = useState(false);
  const modelLabel = (item) => item ? `${item.b.zh} ${item.m.m}` : '选择电视';
  const pick = (item) => {
    if (picker === 'left') setLeft(item);
    else setRight(item);
    setPicker(null);
  };
  return (
    <div className="db-app tvhub">
      <header className="tvhub-head">
        <button className="mh-back" onClick={onBack} aria-label="返回主页"><Icon name="arrowLeft" size={16} /></button>
        <b>电视</b>
      </header>
      <main className="tvhub-scroll">
        <div className="tvhub-intro">
          <h1>电视对比</h1>
          <p>选两台，关键差异一眼看懂</p>
        </div>

        <section className="tvhub-compare" aria-label="电视对比">
          <div className="tvhub-visual">
            <img src="tv-compare-hero.png" alt="两台电视斜侧对向展示" />
            <span className="tvhub-vs">VS</span>
          </div>
          <div className="tvhub-models">
            <button className="tvhub-model" onClick={() => setPicker('left')} aria-label={`更换左侧电视，当前${modelLabel(left)}`}>
              <span className="tvhub-model-check"><Icon name="check" size={13} /></span>
              <span><b>{modelLabel(left)}</b><small>换一台</small></span>
              <Icon name="chevRight" size={13} />
            </button>
            <button className="tvhub-model" onClick={() => setPicker('right')} aria-label={`更换右侧电视，当前${modelLabel(right)}`}>
              <span className="tvhub-model-check"><Icon name="check" size={13} /></span>
              <span><b>{modelLabel(right)}</b><small>换一台</small></span>
              <Icon name="chevRight" size={13} />
            </button>
          </div>
          <a className="tvhub-start" href="电视对比看板.html">开始对比</a>
        </section>

        <section className="tvhub-secondary" aria-label="电视服务入口">
          <button className="tvhub-tile" onClick={onTools} aria-label="进入小工具">
            <img src="room-composites/room-mount-slim.webp" alt="在客厅中试电视" />
            <span className="tvhub-tile-copy"><b>小工具</b><small>在我家试电视 · 环境光检测</small></span>
            <span className="tvhub-tile-go"><Icon name="chevRight" size={14} /></span>
          </button>
          <button className="tvhub-tile" onClick={() => setRanking(true)} aria-label="打开实测排行榜">
            <img src="tv-ranking-card.png" alt="电视实测排行榜奖杯" />
            <span className="tvhub-tile-copy"><b>排行榜</b><small>综合 · 亮厅 · 电影 · 游戏</small></span>
            <span className="tvhub-tile-go"><Icon name="chevRight" size={14} /></span>
          </button>
        </section>
      </main>

      {picker && <DbModelPicker side={picker} current={picker === 'left' ? left : right} onPick={pick} onClose={() => setPicker(null)} />}
      {ranking && <DbRankingSheet onClose={() => setRanking(false)} onLibrary={onLibrary} />}
    </div>
  );
}

function DbScreen({ onBack, onTools }) {
  const { useState } = React;
  const [view, setView] = useState(dbQ('dbv') || dbQ('b') ? 'library' : 'hub');
  const [mode, setMode] = useState(dbQ('dbv') === 'price' ? 'price' : 'brand');
  const [brand, setBrand] = useState(BRANDS.find((b) => b.zh === dbQ('b')) || null);
  const [bRect, setBRect] = useState(null);
  const [bFace, setBFace] = useState(null);
  const [bOut, setBOut] = useState(false);
  const [bKey, setBKey] = useState(0); /* 每次打开换 key：全新实例，避免"关闭中重开"复用半状态 */
  const bTimer = React.useRef(null);
  const bOrigin = React.useRef(null); /* morph 期间隐藏来源品牌卡，落点由克隆无缝换真 */
  const [sel, setSel] = useState(null);
  const [selOut, setSelOut] = useState(false);
  const sync = (fn) => { const u = new URL(location); fn(u.searchParams); history.replaceState(null, '', u); };
  /* 品牌视图从被点的品牌卡 morph 展开（复用 home.jsx 的 MorphLayer；深链 &b= 时 rect=null 中央张开） */
  const pickBrand = (b, e) => {
    clearTimeout(bTimer.current);
    if (bOrigin.current) bOrigin.current.style.visibility = '';
    const o = morphOrigin(e, '.db-app');
    bOrigin.current = (e && e.currentTarget) || null;
    if (bOrigin.current) bOrigin.current.style.visibility = 'hidden';
    setBRect(o.rect); setBFace(o.face);
    sync((p) => p.set('b', b.zh)); setBOut(false); setBrand(b); setBKey((v) => v + 1);
  };
  const closeBrand = () => {
    sync((p) => p.delete('b')); setBOut(true);
    clearTimeout(bTimer.current);
    bTimer.current = setTimeout(() => {
      setBrand(null); setBOut(false);
      if (bOrigin.current) { bOrigin.current.style.visibility = ''; bOrigin.current = null; }
    }, DB_REDUCE ? 60 : MORPH_CLOSE_WAIT);
  };
  const closeSel = () => {
    setSelOut(true);
    setTimeout(() => { setSel(null); setSelOut(false); }, DB_REDUCE ? 0 : 240);
  };

  const openLibrary = () => {
    sync((p) => p.set('dbv', mode));
    setView('library');
  };
  const closeLibrary = () => {
    sync((p) => { p.delete('dbv'); p.delete('b'); });
    setBrand(null); setBOut(false); setView('hub');
  };

  if (view === 'hub') {
    return <DbHub onBack={onBack} onTools={onTools} onLibrary={openLibrary} />;
  }

  return (
    <div className="db-app">
      <div className="db-head">
        <button className="mh-back" onClick={closeLibrary} aria-label="返回电视主页"><Icon name="arrowLeft" size={16} /></button>
        <div className="db-ht">
          <b>机型库</b>
          <small>{`在库 ${DB_STATS.inStock} 台 · ${DB_STATS.brands} 个品牌`}</small>
        </div>
      </div>

      <div className="db-pane">
        <div className="db-seg" style={{ '--seg-active': mode === 'price' ? 1 : 0 }}>
          <span className="seg-thumb"></span>
          <button className={mode === 'brand' ? 'on' : ''} onClick={() => { setMode('brand'); sync((p) => p.set('dbv', 'brand')); }}>按品牌</button>
          <button className={mode === 'price' ? 'on' : ''} onClick={() => { setMode('price'); sync((p) => p.set('dbv', 'price')); }}>按价格</button>
        </div>
        {mode === 'brand' ? (
          <div className="bgrid">
            {BRANDS.map((b) => (
              <button key={b.zh} className="bcard" onClick={(e) => pickBrand(b, e)}>
                <span className={dbCx('bd-logo', b.box && 'box')}
                  style={b.box ? { background: b.color } : { color: b.color }}>{b.en}</span>
                {b.zh.toLowerCase() !== b.en.toLowerCase() && <b className="bd-zh">{b.zh}</b>}
                <small className="bd-n">共收录 {b.models.length} 款机型</small>
              </button>
            ))}
          </div>
        ) : (
          DB_PRICE_BUCKETS.map((bk) => {
            const items = BRANDS.flatMap((b) => b.models.filter((m) => m.price > 0 && bk.test(m.price))
              .map((m) => ({ m, b }))).sort((a, c) => a.m.price - c.m.price);
            if (!items.length) return null;
            return (
              <React.Fragment key={bk.label}>
                <div className="dbg-h">{bk.label}<em>{items.length} 台</em></div>
                {items.map(({ m, b }) => <DbModelRow key={m.id} b={b} m={m} onOpen={setSel} />)}
              </React.Fragment>
            );
          })
        )}
      </div>

      {/* 品牌机型缩略图网格 —— 从品牌卡 morph 展开的覆盖层 */}
      {brand && (
        <MorphLayer key={bKey} rect={bRect} face={bFace} closing={bOut}>
          <div className="db-app">
            <div className="db-head">
              <button className="mh-back" onClick={closeBrand} aria-label="返回品牌列表"><Icon name="arrowLeft" size={16} /></button>
              <div className="db-ht">
                <b>{brand.zh}</b>
                <small>共收录 {brand.models.length} 款机型</small>
              </div>
            </div>
            <div className="db-pane">
              <div className="mgrid">
                {brand.models.map((m) => <DbModelCard key={m.id} b={brand} m={m} onOpen={setSel} />)}
              </div>
            </div>
          </div>
        </MorphLayer>
      )}

      {sel && <DbDetailSheet sel={sel} closing={selOut} onClose={closeSel} />}
    </div>
  );
}

Object.assign(window, { DbScreen });
