/* AI 买电视助手（壳内层）— 脚本化演示对话：固定命令 → 工具调用 → 选项式追问 →
   AR 量房回传 → 入户预检 → 结论机型卡（价格/链接）→ 旧机估值。
   机型/价格取自 dbdata.jsx（BRANDS）与 data.jsx 实测值；对话为 demo 剧本，非真模型。
   深链：?tool=agent · &auto=1 自动替用户点选项（走 AR→中档→备选→旧机全支线，评审/截图用） */
const AG_RM = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
const AG_AUTO = new URLSearchParams(location.search).get('auto') === '1';
const agCx = (...a) => a.filter(Boolean).join(' ');
const AG_CMD = '我想买台客厅用的电视';

/* 尺寸 → 在库命中数 / 包装箱最长边（入户预检用） */
const AG_HIT = { 75: 8, 85: 21, 98: 11 };
const AG_BOX = {
  75: { long: '1.86 m' },
  85: { long: '2.08 m' },
  98: { long: '2.36 m', warn: '箱体超 2.3 m：需斜立进梯，建议约 2 名搬运（免费）' },
};

/* 预算选项按尺寸给（价格全部来自机型库在售录价） */
const AG_BUDGETS = {
  75: [
    { label: '5 – 6 千', v: '75b1' },
    { label: '1 万左右', v: '75b2' },
    { label: '不确定，直接推荐', v: '75b2' },
  ],
  85: [
    { label: '1 万以内', v: '85low' },
    { label: '1 – 1.5 万', v: '85mid' },
    { label: '不设上限', v: '85high' },
  ],
  98: [
    { label: '3 万左右', v: '98b1' },
    { label: '5 万以上', v: '98b2' },
    { label: '不确定，直接推荐', v: '98b1' },
  ],
};

const AG_PICKS = {
  '75b1': {
    say: '5–6 千的 75″，这台生态和画质都最顺——',
    main: { brand: '华为', model: '智慧屏 Vision 5 75', panel: 'MiniLED', size: 75, zone: '392 区', nit: '1600 nit', refl: '3.0%', price: 5647, hl: '鸿蒙生态', why: '1600 nit 应对白天客厅够用，鸿蒙投屏/联动是同价位独一档；实测系统无广告。' },
    altSay: '还想再省一千的话：',
    alt: { brand: '华为', model: 'Vision 5 SE 75', panel: 'LED', size: 75, zone: '直下背光', nit: '800 nit', refl: '3.4%', price: 4499, hl: '入门首选', why: '亮度低一档，晚上看为主完全够；预算敏感选它不亏。' },
  },
  '75b2': {
    say: '1 万左右的 75″，白天客厅我推这台——',
    main: { brand: '海信', model: '75 E7Q', panel: 'MiniLED', size: 75, zone: '1120 区', nit: '2600 nit', refl: '2.8%', price: 9749, hl: '亮度扎实', why: '2600 nit 峰值 + 低反屏，强环境光下高光不发灰；游戏 144Hz 顺带满足。' },
    altSay: '想砍一半预算也有得选：',
    alt: { brand: '华为', model: '智慧屏 Vision 5 75', panel: 'MiniLED', size: 75, zone: '392 区', nit: '1600 nit', refl: '3.0%', price: 5647, hl: '鸿蒙生态', why: '亮度低一档但生态好用，混龄家庭很省心。' },
  },
  '85low': {
    say: '1 万内的 85″，这台几乎没有对手——',
    main: { brand: '雷鸟', model: '85 鹤7 PRO 25款', panel: 'QD-MiniLED', size: 85, zone: '1680 区', nit: '3200 nit', refl: '2.6%', price: 9799, hl: '同价位控光标杆', why: '万元内把亮度和分区堆到顶，白天客厅高光场景不发灰；144Hz 高刷打游戏也顺带满足。' },
    altSay: '同档还有台更均衡的备选：',
    alt: { brand: '海信', model: '85 E7N PRO', panel: 'MiniLED', size: 85, zone: '1120 区', nit: '2400 nit', refl: '2.8%', price: 9999, hl: '均衡水桶机', why: '亮度略低半档，但色彩调校更稳、系统更省心，长辈混用更友好。' },
  },
  '85mid': {
    say: '1–1.5 万这档，白天亮客厅我只推它——',
    main: { brand: '海信', model: '85 E8S', panel: 'RGB-MiniLED', size: 85, zone: '2340 区', nit: '5000 nit', refl: '2.4%', price: 14999, hl: 'RGB 光晕控制出色', why: '峰值 5000 nit + RGB 三色控光，你家这种强环境光客厅正是它的主场；实测反射率 2.4% 是同价位最低。' },
    altSay: '想省 3 千的话，看这台：',
    alt: { brand: 'TCL', model: '85 Q10L', panel: 'QD-MiniLED', size: 85, zone: '万象分区', nit: '4500 nit', refl: '2.8%', price: 11999, hl: '超窄金属边', why: '亮度同样管够，光晕控制略逊 E8S，但直接便宜 3000 元。' },
  },
  '85high': {
    say: '不设上限的话，客厅直接一步到位——',
    main: { brand: '海信', model: '100 E8Q PRO', panel: 'RGB-MiniLED', size: 100, zone: '3000+ 区', nit: '5000 nit', refl: '2.4%', price: 28999, hl: '百吋影院级', why: '既然墙放得下，100″ 沉浸感是 85″ 追不上的；白天抗反、夜里控光都是这档天花板。' },
    altSay: '想要挂墙更像一幅画的话：',
    alt: { brand: '三星', model: '85LS03D', panel: 'QLED', size: 85, zone: '哑光屏', nit: '2000 nit', refl: '1.9%', price: 23999, hl: 'The Frame 画壁', why: '哑光屏几乎零反光 + 艺术画模式，客厅颜值党的首选。' },
  },
  '98b1': {
    say: '3 万左右的百吋档，这两台打架，先看它——',
    main: { brand: '海信', model: '100 E8Q PRO', panel: 'RGB-MiniLED', size: 100, zone: '3000+ 区', nit: '5000 nit', refl: '2.4%', price: 28999, hl: 'RGB 控光', why: '100″ + 5000 nit，白天强光客厅唯一不虚的百吋；光晕控制实测比同档好半档。' },
    altSay: '备选是隔壁这台：',
    alt: { brand: 'TCL', model: '98 Q10L PRO', panel: 'QD-MiniLED', size: 98, zone: '万象分区', nit: '4800 nit', refl: '2.7%', price: 28999, hl: '音响更强', why: '同价同亮度，安桥音响低频更猛，看演唱会/大片更爽。' },
  },
  '98b2': {
    say: '5 万以上就是旗舰随便挑了——',
    main: { brand: '海信', model: '98 UX', panel: 'RGB-MiniLED', size: 98, zone: '10000+ 区', nit: '8000 nit', refl: '2.2%', price: 51999, hl: '灯塔级旗舰', why: '万级分区 + 8000 nit，目前在库实测天花板；HDR 高光是别家两倍的观感。' },
    altSay: '理性一点的备选：',
    alt: { brand: '海信', model: '100 E8Q PRO', panel: 'RGB-MiniLED', size: 100, zone: '3000+ 区', nit: '5000 nit', refl: '2.4%', price: 28999, hl: '性价比旗舰', why: '尺寸还大 2″，价格差出一台 85″——追求面积优先选它。' },
  },
};

const agSleep = (ms) => new Promise((r) => setTimeout(r, AG_RM ? Math.min(ms, 80) : ms));

/* ---- 假 AR 量房浮层：识别平面 → 量净宽 → 量视距 → 回传 ---- */
function AgArOverlay({ onDone }) {
  const { useState, useEffect } = React;
  const [ph, setPh] = useState(0);
  useEffect(() => {
    const k = AG_RM ? 0.1 : 1;
    const ts = [
      setTimeout(() => setPh(1), 1000 * k),
      setTimeout(() => setPh(2), 2300 * k),
      setTimeout(() => setPh(3), 3600 * k),
      setTimeout(onDone, 4500 * k),
    ];
    return () => ts.forEach(clearTimeout);
  }, []);
  const hints = ['正在识别电视墙平面…', '测量电视墙净宽…', '测量沙发观看距离…', '测量完成，回传助手'];
  return (
    <div className="arov">
      <img className="arov-bg" src={IMG.wall} alt="" draggable="false" />
      <div className="arov-dim"></div>
      <div className="arov-grid"></div>
      <span className="arc tl"></span><span className="arc tr"></span>
      <span className="arc bl"></span><span className="arc br"></span>
      <div className="arov-hint">{hints[ph]}</div>
      {ph >= 1 && <div className="ar-w"><span className="ar-lbl">净宽 3.62 m</span></div>}
      {ph >= 2 && <div className="ar-d"><span className="ar-lbl">视距 2.9 m</span></div>}
      <div className={agCx('arov-pill', ph >= 3 && 'ok')}>
        {ph >= 3 ? <Icon name="check" size={14} /> : <span className="tc-spin"></span>}
        {ph >= 3 ? '数据已回传买电视助手' : 'AR 量房小工具运行中'}
      </div>
    </div>
  );
}

/* ---- 消息卡片 ---- */
function AgTvCard({ tv, tag }) {
  const color = (BRANDS.find((b) => b.zh === tv.brand) || {}).color || 'var(--accent)';
  const jd = 'https://search.jd.com/Search?keyword=' + encodeURIComponent(`${tv.brand}${tv.model.replace(/\s+/g, '')}电视`);
  return (
    <div className="agk tvk">
      <div className="tvk-top">
        <span className="tvk-b" style={{ color }}>{tv.brand}</span>
        <b className="tvk-n">{tv.model}</b>
        <span className="tvk-tag">{tag}</span>
      </div>
      <div className="tvk-tags"><span>{tv.panel}</span><span>{tv.size}″</span><span>{tv.hl}</span></div>
      <div className="tvk-mx">
        <div><small>峰值亮度</small><b>{tv.nit}</b></div>
        <div><small>实测反射率</small><b>{tv.refl}</b></div>
        <div><small>控光</small><b>{tv.zone}</b></div>
      </div>
      <p className="tvk-why">{tv.why}</p>
      <div className="tvk-buy">
        <div className="tvk-p"><b>¥{tv.price.toLocaleString()}</b><small>今日含国补到手</small></div>
        <a className="agk-btn pri" href={jd} target="_blank" rel="noreferrer">去京东<Icon name="chevRight" size={13} /></a>
        <a className="agk-btn" href="电视对比看板.html" target="_blank" rel="noreferrer">加入对比</a>
      </div>
    </div>
  );
}

function AgEntryCard({ size }) {
  const box = AG_BOX[size] || AG_BOX[85];
  return (
    <div className="agk entk">
      <div className="agk-h"><Icon name="cube" size={14} />入户可行性预检<span className="entk-ok">通过 ✓</span></div>
      <div className="entk-rows">
        <div className="entk-row"><Icon name="check" size={13} />包装箱最长边 {box.long}<em>电梯轿厢 1.6×1.5×2.3 m</em></div>
        <div className="entk-row"><Icon name="check" size={13} />入户门净宽 0.95 m<em>拆箱前可直进</em></div>
        <div className="entk-row"><Icon name="check" size={13} />楼道转角 · 无台阶<em>路径已核对</em></div>
      </div>
      {box.warn && <div className="entk-warn">{box.warn}</div>}
      <div className="agk-note">数据来自小区众包入户库（演示数据）</div>
    </div>
  );
}

function AgArCard() {
  return (
    <div className="agk ark">
      <div className="agk-h"><Icon name="scan" size={14} />AR 量房 · 数据回传</div>
      <div className="ark-vals">
        <div><small>电视墙净宽</small><b>3.62 m</b></div>
        <div><small>沙发视距</small><b>2.9 m</b></div>
        <div><small>推荐尺寸</small><b className="acc">85″</b></div>
      </div>
    </div>
  );
}

function AgTradeCard() {
  return (
    <div className="agk trk">
      <div className="agk-h"><Icon name="cube" size={14} />旧机估值 · 回收抵扣</div>
      <div className="trk-v"><b>¥360 – 520</b><span>55″ 液晶 · 约 2017 年 · 屏幕完好</span></div>
      <div className="agk-note">含上门拆挂与搬运费 · 回收款下单直接抵扣</div>
      <button className="agk-btn">预约与新机同日上门</button>
    </div>
  );
}

function AgEndCard({ size, bud, name, traded }) {
  return (
    <div className="agk endk">
      <div className="agk-h"><Icon name="check" size={14} />本次方案小结</div>
      <div className="endk-chips">
        <span>{size}″</span><span>{bud}</span><span>{name}</span>
        <span>送装 + 挂墙</span>{traded && <span>旧机抵扣 ✓</span>}
      </div>
    </div>
  );
}

/* ---- 聊天主体：剧本引擎 ---- */
function AgentChatInner({ onBack, onRestart, ask }) {
  const { useState, useEffect, useRef } = React;
  const [msgs, setMsgs] = useState([]);
  const [ar, setAr] = useState(false);
  const seq = useRef(0);
  const alive = useRef(true);
  const pend = useRef(null);   // 选项等待 {id, res}
  const arRes = useRef(null);  // AR 等待 resolve
  const scRef = useRef(null);

  useEffect(() => () => { alive.current = false; }, []);
  useEffect(() => {
    const el = scRef.current;
    if (el) el.scrollTo({ top: el.scrollHeight, behavior: AG_RM ? 'auto' : 'smooth' });
  }, [msgs, ar]);

  const push = (m) => { const id = ++seq.current; setMsgs((s) => [...s, { id, ...m }]); return id; };
  const patch = (id, p) => setMsgs((s) => s.map((m) => (m.id === id ? { ...m, ...p } : m)));
  const sleep = async (ms) => { await agSleep(ms); if (!alive.current) throw 0; };

  const ai = async (text, wait = 950) => {
    const id = push({ kind: 'ai', typing: true });
    await sleep(wait);
    patch(id, { typing: false, text });
    await sleep(260);
  };
  const tool = async (icon, name, detail, result, wait = 1400) => {
    const id = push({ kind: 'tool', icon, name, detail, state: 'run' });
    await sleep(wait);
    patch(id, { state: 'done', result });
    await sleep(320);
  };
  const opts = (items) => new Promise((res) => {
    const id = push({ kind: 'opts', items });
    pend.current = { id, res };
    if (AG_AUTO) agSleep(1100).then(() => {
      if (pend.current && pend.current.id === id)
        pick(items.find((it) => it.wide) || items[Math.min(1, items.length - 1)]);
    });
  });
  const pick = (it) => {
    const p = pend.current; if (!p) return;
    pend.current = null;
    patch(p.id, { done: true });
    push({ kind: 'user', text: it.bubble || it.label });
    p.res(it);
  };
  const arRun = () => new Promise((res) => { arRes.current = res; setAr(true); });
  const arDone = () => { setAr(false); const r = arRes.current; arRes.current = null; if (r) r(); };

  useEffect(() => { run().catch(() => {}); }, []);

  async function run() {
    push({ kind: 'user', text: ask || AG_CMD });
    await sleep(650);
    await tool('database', '检索机型库', '按「客厅」场景匹配在库实测机', '在库 58 台 · 客厅适配 32 台');
    await tool('sliders', '加载场景权重', '客厅 · 强环境光', '亮度 30% + 抗反光 25%，权重就位', 1100);
    await ai('收到！客厅白天环境光强，我会重点比「亮度」和「抗反光」两项实测。先定尺寸——你倾向多大？');
    const s = await opts([
      { label: '75″', sub: '视距 2.3 – 2.8 m', v: 75 },
      { label: '85″', sub: '视距 2.8 – 3.4 m', v: 85 },
      { label: '98″ 以上', sub: '视距 3.4 m+', v: 98 },
      { label: '不知道怎么选，帮我量一下', sub: '跳转 AR 量房小工具 · 10 秒自动回传', v: 'ar', accent: true, wide: true, bubble: '不知道怎么选' },
    ]);
    let size = s.v;
    if (size === 'ar') {
      await ai('没问题，我拉起 AR 量房，镜头对着电视墙慢慢扫一圈就行。', 750);
      await sleep(900);
      await arRun();
      push({ kind: 'ar' });
      await sleep(750);
      await ai('数据回来了：净宽 3.62 m、视距 2.9 m。按 THX 40° 视角算，85″ 正好在甜点区；98″ 放得下但视距偏近。我按 85″ 帮你找。');
      size = 85;
    }
    await tool('cube', '入户可行性预检', `${size}″ 包装箱 × 小区电梯库`, '电梯与入户门均可通过 ✓', 1600);
    push({ kind: 'entry', size });
    await sleep(750);
    await ai('入户没问题 ✓ 再确认下预算，大概什么范围？');
    const b = await opts(AG_BUDGETS[size]);
    const P = AG_PICKS[b.v];
    await tool('search', '筛选在库机型', `${size}″ · 客厅高亮 · ${b.label}`, `58 台 → 命中 ${AG_HIT[size]} 台 → 初选 3 台`);
    await tool('activity', '拉取实测数据', '峰值/全屏亮度 · 反射率 · 控光分区', '3 台整档实测齐全，可横向对比', 1500);
    await tool('bolt', '全网比价', '今日到手价 · 含国补', '已按最低到手价排序', 1150);
    await ai(P.say);
    push({ kind: 'tv', tv: P.main, tag: '首选' });
    await sleep(750);
    const fb = await opts([
      { label: '很合适，就它了', v: 'ok', accent: true },
      { label: '再看看备选', v: 'alt' },
    ]);
    if (fb.v === 'alt') {
      await ai(P.altSay, 700);
      push({ kind: 'tv', tv: P.alt, tag: '备选' });
      await sleep(750);
      await ai('两台链接都在上面了，价格实时同步，随时能下单。', 650);
    } else {
      await ai('好眼光，这台也是我在这档的第一推荐 👌', 650);
    }
    await ai('对了，家里旧电视要一起处理吗？拍两张照就能出回收价，能直接抵新机。');
    const tr = await opts([
      { label: '要，帮我估个价', v: 'y', accent: true },
      { label: '不用了', v: 'n' },
    ]);
    let traded = false;
    if (tr.v === 'y') {
      await tool('camera', '旧机估值', '型号识别 · 成色问答 · 含上门搬运', '识别：55″ 液晶（约 2017 年）', 1700);
      push({ kind: 'trade' });
      traded = true;
      await sleep(750);
    }
    await ai('搞定！方案小结在下面：链接直达下单页，送装、挂墙和旧机回收可以约同一天上门。有新问题随时回来找我 ✌️');
    push({ kind: 'end', size, bud: b.label, name: `${P.main.brand} ${P.main.model}`, traded });
  }

  return (
    <div className="agc">
      <div className="agc-head">
        <button className="mh-back" onClick={onBack} aria-label="返回主页"><Icon name="arrowLeft" size={16} /></button>
        <span className="agc-orb"><Icon name="sparkle" size={18} /></span>
        <div className="agc-ht"><b>AI 买电视助手</b><small>已接入 {DB_STATS.inStock} 台实测机型库</small></div>
        <button className="agc-re" onClick={onRestart} aria-label="重新演示"><Icon name="refresh" size={15} /></button>
      </div>

      <div className="agc-scroll" ref={scRef}>
        {msgs.map((m) => {
          switch (m.kind) {
            case 'user': return <div key={m.id} className="msg user">{m.text}</div>;
            case 'ai': return (
              <div key={m.id} className="msg ai">
                {m.typing
                  ? <span className="agc-dots"><span></span><span></span><span></span></span>
                  : m.text}
              </div>
            );
            case 'tool': return (
              <div key={m.id} className={agCx('tcall', m.state === 'done' && 'done')}>
                <span className="tc-ic"><Icon name={m.icon} size={15} /></span>
                <div className="tc-tt">
                  <b>{m.name}</b>
                  <small className={m.state === 'done' ? 'ok' : ''}>{m.state === 'done' ? m.result : m.detail}</small>
                </div>
                {m.state === 'run'
                  ? <span className="tc-spin"></span>
                  : <span className="tc-done"><Icon name="check" size={13} /></span>}
              </div>
            );
            case 'opts': return m.done ? null : (
              <div key={m.id} className="opts">
                {m.items.map((it, i) => (
                  <button key={i} className={agCx('opt', it.accent && 'accent', it.wide && 'wide')} onClick={() => pick(it)}>
                    {it.label}{it.sub && <small>{it.sub}</small>}
                  </button>
                ))}
              </div>
            );
            case 'ar': return <AgArCard key={m.id} />;
            case 'entry': return <AgEntryCard key={m.id} size={m.size} />;
            case 'tv': return <AgTvCard key={m.id} tv={m.tv} tag={m.tag} />;
            case 'trade': return <AgTradeCard key={m.id} />;
            case 'end': return <AgEndCard key={m.id} size={m.size} bud={m.bud} name={m.name} traded={m.traded} />;
            default: return null;
          }
        })}
      </div>

      <div className="agc-bar">
        <span>选择上方选项继续（演示为固定剧本）</span>
        <span className="agc-mic"><Icon name="broadcast" size={15} /></span>
      </div>

      {ar && <AgArOverlay onDone={arDone} />}
    </div>
  );
}

/* 外壳：epoch 换 key 实现「重新演示」整段重跑 */
function AgentChat(props) {
  const { useState } = React;
  const [ep, setEp] = useState(0);
  return <AgentChatInner key={ep} {...props} onRestart={() => setEp((e) => e + 1)} />;
}

Object.assign(window, { AgentChat });
