/* 移动端主页 — 数据库为主体，Agent 买电视助手为入口，小工具页挂前台工具。
   两个已上线工具（mobile.jsx 的 ComposeApp/LightApp）在壳内 push 打开，一个手机壳一站到底。
   复用 icons.jsx(Icon) / data.jsx(TVS) / images.jsx(IMG)。深链：?tab=tools · ?tool=compose|light */
const { useState, useEffect, useRef } = React;
const cx = (...a) => a.filter(Boolean).join(' ');
const q = (k) => new URLSearchParams(location.search).get(k);
const REDUCE = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);

function Phone({ children }) {
  return (
    <div className="phone">
      <div className="pscreen">{children}</div>
      <div className="island"></div>
      <div className="phome"></div>
    </div>
  );
}

const ASKS = ['预算 1.5 万，客厅怎么选', '白天客厅很亮，怕反光', 'OLED 会烧屏吗'];
const CMD = '我想买台客厅用的电视'; // 演示固定命令：点对话框打字机输入，点发送进入 Agent 对话

/* 前台工具：2 个已上线（壳内打开），4 个规划位 */
const LIVE_TOOLS = [
  { k: 'compose', icon: 'sparkle', n: 'AI 客厅合成', d: '拍下电视墙，AI 生成等比合成预览', img: () => IMG.wall },
  { k: 'light', icon: 'sun', n: '采光 · 测光', d: '两拍测照度与反光源，反推抗反需求', img: () => IMG.rev },
];
const PLAN_TOOLS = [
  { icon: 'scan', n: 'AR 量房 · 摆放', d: '量电视墙净宽与入户路径', tag: '规划中' },
  { icon: 'cube', n: '旧机估值变现', d: '拍照识别 → 含搬运费估价', tag: '规划中' },
  { icon: 'eye', n: '开箱验机 · 故障上报', d: '拍照验收，反哺故障率库', tag: '规划中' },
  { icon: 'crosshair', n: '交互对比看板', d: '并排对比实测画质与参数', tag: '网页版', href: '电视对比看板.html' },
];

function HomeScreen({ on, openDb, openAgent, frozen }) {
  const [ask, setAsk] = useState('');
  const [typing, setTyping] = useState(false);
  const tRef = useRef(null);
  useEffect(() => () => clearInterval(tRef.current), []);
  /* 点对话框：打字机敲入固定命令 */
  const typeCmd = () => {
    if (typing || ask === CMD) return;
    clearInterval(tRef.current); setTyping(true); setAsk('');
    let i = 0;
    tRef.current = setInterval(() => {
      i++; setAsk(CMD.slice(0, i));
      if (i >= CMD.length) { clearInterval(tRef.current); setTyping(false); }
    }, REDUCE ? 4 : 52);
  };
  /* 点发送：从 Agent 卡片 morph 进对话（空输入时直接用固定命令） */
  const send = (e) => {
    if (typing) return;
    e.stopPropagation();
    openAgent(e.currentTarget.closest('.agent'), ask || CMD);
  };
  return (
    <div className={cx('screen', !on && 'off')}>
      <div className="hm-head">
        <img className="hm-logo-img" src="logo.png" alt="先看" draggable="false" />
        <div className="hm-t">电视数据库</div>
      </div>

      {/* Agent 买电视助手 — 主入口 */}
      <div className="agent">
        <span className="ag-glow g1"></span><span className="ag-glow g2"></span>
        <div className="ag-top">
          <span className="ag-orb"><Icon name="sparkle" size={22} /></span>
          <div className="ag-tt">
            <div className="ag-t">AI 买电视助手</div>
            <div className="ag-s">从选到装到售后，直接问</div>
          </div>
        </div>
        <div className="ag-ask" role="button" tabIndex={0} onClick={typeCmd}>
          <span className={cx('ag-q', !ask && !typing && 'ph')}>
            {ask || (typing ? '' : '想买多大？预算多少？点我试试…')}
            {typing && <span className="ag-caret"></span>}
          </span>
          <button className={cx('ag-send', ask && !typing && 'go')} onClick={send} aria-label="发送">
            <Icon name="chevRight" size={17} />
          </button>
        </div>
        <div className="ag-chips">
          {ASKS.map((a) => <button key={a} className={cx('ag-chip', ask === a && 'on')} onClick={() => setAsk(a)}>{a}</button>)}
        </div>
      </div>

      {/* 数据资产 — 用户视角：在库量 + 即将入库 */}
      <div className="card">
        <div className="sec-head"><Icon name="database" size={14} /><span>数据资产</span></div>
        <div className="dbx">
          <div className="dbx-n">
            <b>{DB_STATS.inStock}</b>
            <span>台电视<br />实测在库</span>
          </div>
          <div className="dbx-side">
            <span className="lab-chip"><span className="lab-dot"></span>{DB_STATS.incoming} 台即将入库</span>
            <span className="dbx-sub">{DB_STATS.brands} 个品牌</span>
          </div>
        </div>
      </div>

      {/* 机型库 — 自动滚动条 + 全部入口 */}
      <div className="sec-row">
        <span className="sec-t">机型库</span>
        <button className="sec-btn" onClick={openDb}>全部 {DB_STATS.inStock} 台<Icon name="chevRight" size={13} /></button>
      </div>
      {REDUCE ? (
        <div className="tv-rail">{DBTV.map((t) => <TvCard key={t.id} t={t} onClick={openDb} />)}</div>
      ) : (
        <div className="tv-marq">
          {/* 壳内层打开时暂停跑马灯，省掉层下每帧重绘 */}
          <div className="tv-track" style={{ animationPlayState: frozen ? 'paused' : 'running' }}>
            <div className="tv-set">{DBTV.map((t) => <TvCard key={t.id} t={t} onClick={openDb} />)}</div>
            <div className="tv-set" aria-hidden="true">{DBTV.map((t) => <TvCard key={'d' + t.id} t={t} onClick={openDb} />)}</div>
          </div>
        </div>
      )}
    </div>
  );
}

function TvCard({ t, onClick }) {
  return (
    <div className="tv-card" role="button" tabIndex={0} onClick={onClick}>
      <div className="tvc-n">{t.brand} {t.model}</div>
      <div className="tvc-tags"><span>{t.panel}</span><span>{t.size}″</span></div>
      <div className="tvc-hl"><Icon name="activity" size={12} />{t.hl}</div>
      <div className="tvc-p">¥{t.price.toLocaleString()}</div>
    </div>
  );
}

/* DbScreen（详细机型库）在 dbview.jsx */

function ToolsScreen({ on, openTool }) {
  return (
    <div className={cx('screen', !on && 'off')}>
      <div className="hm-head">
        <div className="hm-t">小工具</div>
      </div>

      {LIVE_TOOLS.map((t) => (
        <button key={t.k} className="tool-live" onClick={(e) => openTool(t.k, e)}>
          <div className="tl-thumb">
            <img src={t.img()} alt={t.n} draggable="false" />
            <span className="tl-badge"><span className="lab-dot"></span>可体验</span>
          </div>
          <div className="tl-body">
            <span className="tl-ic"><Icon name={t.icon} size={17} /></span>
            <div className="tl-tt"><b>{t.n}</b><small>{t.d}</small></div>
            <span className="tl-chev"><Icon name="chevRight" size={16} /></span>
          </div>
        </button>
      ))}

      <div className="sec-row"><span className="sec-t">规划中</span></div>
      {PLAN_TOOLS.map((t) => {
        const inner = (
          <React.Fragment>
            <span className="tr-ic"><Icon name={t.icon} size={16} /></span>
            <div className="tr-tt"><b>{t.n}</b><small>{t.d}</small></div>
            <span className={cx('tr-tag', t.href && 'web')}>{t.tag}</span>
          </React.Fragment>
        );
        return t.href
          ? <a key={t.n} className="tool-row" href={t.href} target="_blank" rel="noreferrer">{inner}</a>
          : <div key={t.n} className="tool-row">{inner}</div>;
      })}
    </div>
  );
}

/* 壳内层：两段式 morph（防卡顿）。
   ① 空面板从来源卡片 rect clip-path 张开（动画帧里没有内容挂载/重绘成本）；
   ② 落定后再挂载内容淡入。关闭时内容先淡出、面板反向收回后卸载（fresh mount）。
   rect 为 null（深链直开）时从屏幕中央小窗张开。 */
function MorphLayer({ rect, closing, children }) {
  const [on, setOn] = useState(false);
  const [ready, setReady] = useState(REDUCE);
  useEffect(() => {
    const r = requestAnimationFrame(() => setOn(true));
    const t = setTimeout(() => setReady(true), REDUCE ? 0 : 460);
    return () => { cancelAnimationFrame(r); clearTimeout(t); };
  }, []);
  const from = rect
    ? `inset(${rect.top}px ${rect.right}px ${rect.bottom}px ${rect.left}px round 22px)`
    : 'inset(42% 24% 42% 24% round 26px)';
  const open = on && !closing;
  return (
    <div className="tool-layer" style={{ clipPath: open ? 'inset(0px 0px 0px 0px round 0px)' : from, opacity: open ? 1 : .5 }}>
      <div className={cx('tool-content', ready && !closing && 'ready')}>{ready && children}</div>
    </div>
  );
}

function HomeApp() {
  const tool0 = ['compose', 'light', 'db', 'agent'].includes(q('tool')) ? q('tool') : null;
  const [tab, setTab] = useState(tool0 === 'compose' || tool0 === 'light' || q('tab') === 'tools' ? 'tools' : 'home');
  const [tool, setTool] = useState(tool0);
  const [agentAsk, setAgentAsk] = useState(CMD);
  const [rect, setRect] = useState(null);
  const [closing, setClosing] = useState(false);
  const syncUrl = (fn) => { const u = new URL(location); fn(u.searchParams); history.replaceState(null, '', u); };
  const pick = (t) => {
    if (t === tab) return;
    syncUrl((p) => { if (t === 'tools') p.set('tab', 'tools'); else p.delete('tab'); });
    setTab(t);
  };
  /* 记录点击卡片相对手机屏的 rect（壳被缩放时按比例还原），morph 从这里张开 */
  const openTool = (k, e) => {
    let r = null;
    const host = e && e.currentTarget.closest('.m-app');
    if (host) {
      const hr = host.getBoundingClientRect();
      const cr = e.currentTarget.getBoundingClientRect();
      const s = hr.width ? host.offsetWidth / hr.width : 1;
      r = { top: (cr.top - hr.top) * s, left: (cr.left - hr.left) * s,
            right: (hr.right - cr.right) * s, bottom: (hr.bottom - cr.bottom) * s };
    }
    setRect(r);
    syncUrl((p) => p.set('tool', k)); setClosing(false); setTool(k);
  };
  const closeTool = () => {
    syncUrl((p) => p.delete('tool')); setClosing(true);
    setTimeout(() => { setTool(null); setClosing(false); }, REDUCE ? 60 : 650);
  };
  return (
    <div className="m-app home">
      <div className="hm-bg"><span className="hb b1"></span><span className="hb b2"></span><span className="hb b3"></span></div>
      <HomeScreen on={tab === 'home'} openDb={(e) => openTool('db', e)}
        openAgent={(el, text) => { setAgentAsk(text); openTool('agent', el && { currentTarget: el }); }} frozen={!!tool} />
      <ToolsScreen on={tab === 'tools'} openTool={openTool} />
      {tool && (
        <MorphLayer rect={rect} closing={closing}>
          {tool === 'db' ? <DbScreen onBack={closeTool} />
            : tool === 'agent' ? <AgentChat onBack={closeTool} ask={agentAsk} />
            : tool === 'light' ? <LightApp onBack={closeTool} />
            : <ComposeApp onBack={closeTool} />}
        </MorphLayer>
      )}
      <div className="tabbar" style={{ '--tab-active': tab === 'tools' ? 1 : 0 }}>
        <span className="tab-thumb"></span>
        {[['home', '首页', 'database'], ['tools', '小工具', 'grid']].map(([k, l, ic]) => (
          <button key={k} className={tab === k ? 'on' : ''} onClick={() => pick(k)}>
            <Icon name={ic} size={19} />{l}
          </button>
        ))}
      </div>
    </div>
  );
}

function StageHome() {
  return (
    <div className="stage">
      <div className="stage-head">
        <h1>电视数据库 · 移动端主页</h1>
        <p>数据库是主体，Agent 买电视助手是主入口；小工具页只放手机才能测的前台工具，两个已上线 demo 可直接点进。</p>
        <div className="tag-row">
          <span className="chip accent">Agent 主导</span>
          <span className="chip">Liquid Glass</span>
          <span className="chip">双 Tab</span>
        </div>
      </div>
      <div className="frames"><Phone><HomeApp /></Phone></div>
      <div className="stage-foot">深链：?tab=tools 直达小工具 · ?tool=compose|light|db|agent 壳内直开工具 / 机型库 / 买电视助手</div>
    </div>
  );
}

/* 真机模式：小屏（真手机/窄窗）全屏直跑，不套假手机壳；?m=1 强制真机、?m=0 强制评审舞台 */
const REAL = q('m') === '1' || (q('m') !== '0' && window.matchMedia('(max-width: 620px)').matches);
if (REAL) document.documentElement.classList.add('real');
ReactDOM.createRoot(document.getElementById('root')).render(
  REAL ? <div className="real-shell"><HomeApp /></div> : <StageHome />
);
