(() => {
  const MAX_VISIBLE = 6;
  const blocks = [];
  let showAll = false;
  let idSeed = 1;
  let running = false;
  let timers = [];

  const stackShell = document.getElementById('stackShell');
  const stackInner = document.getElementById('stackInner');
  const btnPlay = document.getElementById('playLoop');
  const btnStep = document.getElementById('stepOnce');
  const btnPause = document.getElementById('pauseLoop');
  const btnClear = document.getElementById('clearAll');
  const btnToggleAll = document.getElementById('toggleAll');

  const samples = [
    '评估用户意图，先汇总检索关键字，再推演候选工具。',
    '正在调用 web_search，拼接 query 并去重关键词。',
    '校验上下文有效性，准备输出草稿。',
    '工具结果将写入下一个文本块，留意引用。',
    '自动回溯最近 3 条工具调用，避免重复请求。'
  ];

  const pick = () => samples[Math.floor(Math.random() * samples.length)];

  const createBlock = type => ({
    id: `${type}-${idSeed++}`,
    type,
    title: type === 'thinking' ? '思考过程' : '搜索完成',
    detail: pick(),
    streaming: true,
    expanded: type === 'thinking',
    timestamp: Date.now()
  });

  const computeVisible = () => {
    if (showAll || blocks.length <= MAX_VISIBLE) return [...blocks];
    const hidden = blocks.length - MAX_VISIBLE;
    return [{ id: `more-${hidden}`, type: 'more', hidden }, ...blocks.slice(-MAX_VISIBLE)];
  };

  const updateButtons = () => {
    const overLimit = blocks.length > MAX_VISIBLE;
    btnToggleAll.disabled = !overLimit;
    btnToggleAll.textContent = showAll ? '收起到最近 6 个' : '展开全部';
  };

  const measurePositions = () => {
    const map = {};
    stackInner.querySelectorAll('[data-id]').forEach(el => {
      map[el.dataset.id] = el.getBoundingClientRect();
    });
    return map;
  };

  const animateHeight = (prev, next) => {
    if (prev === next) return;
    stackShell.style.height = prev + 'px';
    // force reflow
    stackShell.getBoundingClientRect();
    stackShell.style.transition = 'height 280ms cubic-bezier(0.25, 0.9, 0.3, 1)';
    stackShell.style.height = next + 'px';
    const clear = () => {
      stackShell.style.transition = '';
      stackShell.removeEventListener('transitionend', clear);
    };
    stackShell.addEventListener('transitionend', clear);
  };

  const applyFLIP = (prev, isGrowMode, addedId) => {
    stackInner.querySelectorAll('[data-id]').forEach(el => {
      const id = el.dataset.id;
      const isMoreRow = id.startsWith('more');
      const now = el.getBoundingClientRect();
      const old = prev[id];

      if (old) {
        const dy = old.top - now.top;
        if (Math.abs(dy) > 0.5) {
          el.style.transform = `translateY(${dy}px)`;
          el.style.transition = 'transform 220ms ease, opacity 220ms ease';
          requestAnimationFrame(() => {
            el.style.transform = 'translateY(0)';
          });
          el.addEventListener(
            'transitionend',
            () => {
              el.style.transform = '';
              el.style.transition = '';
            },
            { once: true }
          );
        }
      } else {
        const usePeek = !showAll && blocks.length <= MAX_VISIBLE && id === addedId;
        if (usePeek) {
          el.classList.add('peek');
          requestAnimationFrame(() => el.classList.remove('peek'));
        } else if (isGrowMode || isMoreRow) {
          el.classList.add('flow-enter');
          requestAnimationFrame(() => el.classList.add('flow-enter-active'));
          el.addEventListener(
            'transitionend',
            () => {
              el.classList.remove('flow-enter', 'flow-enter-active');
            },
            { once: true }
          );
        } else if (id === addedId) {
          el.classList.add('peek');
          requestAnimationFrame(() => el.classList.remove('peek'));
        }
      }
    });
  };

  const createBlockRow = block => {
    const row = document.createElement('div');
    row.className = `row block-row type-${block.type}`;
    row.dataset.id = block.id;

    const main = document.createElement('div');
    main.className = 'row-main';
    main.addEventListener('click', () => {
      block.expanded = !block.expanded;
      render();
    });

    const arrow = document.createElement('div');
    arrow.className = `arrow ${block.expanded ? 'open' : ''}`;
    arrow.textContent = '›';

    const icon = document.createElement('div');
    icon.className = 'row-icon';
    icon.textContent = block.type === 'thinking' ? '🧠' : '🔍';

    const text = document.createElement('div');
    text.className = 'row-text';

    const title = document.createElement('div');
    title.className = 'row-title';
    title.textContent = block.title;

    const sub = document.createElement('div');
    sub.className = 'row-sub';
    if (block.type === 'thinking') {
      sub.textContent = block.streaming ? '思考中 · 默认展开' : '思考完成 · 点击查看详情';
    } else {
      sub.textContent = block.streaming ? '工具调用中 · 运行后自动收起' : '工具完成 · 点击展开结果';
    }

    text.appendChild(title);
    text.appendChild(sub);

    const pill = document.createElement('div');
    pill.className = `pill ${block.streaming ? '' : 'green'}`;
    pill.textContent = block.streaming ? '进行中' : '已完成';

    main.appendChild(arrow);
    main.appendChild(icon);
    main.appendChild(text);
    main.appendChild(pill);

    const detailWrap = document.createElement('div');
    detailWrap.className = 'row-detail';
    detailWrap.style.display = block.expanded ? 'block' : 'none';

    const detailInner = document.createElement('div');
    detailInner.className = 'row-detail-inner';
    detailInner.textContent = block.detail;
    detailWrap.appendChild(detailInner);

    row.appendChild(main);
    row.appendChild(detailWrap);

    if (block.streaming) {
      const progress = document.createElement('div');
      progress.className = 'progress';
      row.appendChild(progress);
    }

    return row;
  };

  const createMoreRow = (id, hidden) => {
    const row = document.createElement('div');
    row.className = 'row more-row';
    row.dataset.id = id;
    row.addEventListener('click', () => {
      showAll = true;
      render();
    });

    const dot = document.createElement('div');
    dot.className = 'more-dot';
    dot.textContent = '···';

    const text = document.createElement('div');
    const title = document.createElement('div');
    title.className = 'row-title';
    title.textContent = '更多';
    const tip = document.createElement('div');
    tip.className = 'more-tip';
    tip.textContent = `已折叠 ${hidden} 个更早的块，点击展开查看`;
    text.appendChild(title);
    text.appendChild(tip);

    const btn = document.createElement('button');
    btn.className = 'more-btn';
    btn.textContent = '展开';

    row.appendChild(dot);
    row.appendChild(text);
    row.appendChild(btn);
    return row;
  };

  const render = (options = {}) => {
    const prev = measurePositions();
    const prevHeight = stackShell.getBoundingClientRect().height || 0;
    const visible = computeVisible();
    stackInner.innerHTML = '';

    if (!visible.length) {
      stackShell.classList.add('empty');
      updateButtons();
      animateHeight(prevHeight, 140);
      return;
    }

    stackShell.classList.remove('empty');

    visible.forEach(block => {
      if (block.type === 'more') {
        stackInner.appendChild(createMoreRow(block.id, block.hidden));
      } else {
        stackInner.appendChild(createBlockRow(block));
      }
    });

    const isGrowMode = showAll || blocks.length <= MAX_VISIBLE;
    requestAnimationFrame(() => applyFLIP(prev, isGrowMode, options.newlyAddedId));
    updateButtons();
    const nextHeight = stackInner.scrollHeight;
    animateHeight(prevHeight || nextHeight, nextHeight);
  };

  const addBlock = type => {
    const block = createBlock(type);
    blocks.push(block);
    render({ newlyAddedId: block.id });

    // 返回 Promise，结束时机取决于类型
    return new Promise(resolve => {
      if (type === 'thinking') {
        timers.push(
          setTimeout(() => {
            block.streaming = false;
            block.detail += ' · 已产出结论，等待工具。';
            render();
          }, 1200)
        );
        timers.push(
          setTimeout(() => {
            block.expanded = false;
            render();
            resolve();
          }, 2000)
        );
      } else {
        timers.push(
          setTimeout(() => {
            block.streaming = false;
            block.detail = '检索到 3 条结果，已写入后续回复。';
            render();
            resolve();
          }, 1400)
        );
      }
    });
  };

  const wait = ms => new Promise(r => timers.push(setTimeout(r, ms)));

  const runCycle = async () => {
    const thinkingDone = await addBlock('thinking');
    await wait(200); // 给折叠留一帧
    await addBlock('tool');
    await wait(500); // 循环间隔
  };

  const playLoop = async () => {
    if (running) return;
    running = true;
    btnPlay.disabled = true;
    btnStep.disabled = true;
    btnPause.disabled = false;
    while (running) {
      await runCycle();
    }
    btnPlay.disabled = false;
    btnStep.disabled = false;
    btnPause.disabled = true;
  };

  const stepOnce = async () => {
    if (running) return;
    btnStep.disabled = true;
    await runCycle();
    btnStep.disabled = false;
  };

  const pauseLoop = () => {
    running = false;
  };

  const clearAll = () => {
    timers.forEach(t => clearTimeout(t));
    timers = [];
    running = false;
    blocks.length = 0;
    showAll = false;
    render();
    btnPlay.disabled = false;
    btnStep.disabled = false;
    btnPause.disabled = true;
  };

  btnPlay.addEventListener('click', playLoop);
  btnStep.addEventListener('click', stepOnce);
  btnPause.addEventListener('click', pauseLoop);
  btnClear.addEventListener('click', clearAll);
  btnToggleAll.addEventListener('click', () => {
    if (blocks.length <= MAX_VISIBLE) return;
    showAll = !showAll;
    render();
  });

  // 初始播放一轮示例，演示“先思考后工具”的顺序
  stepOnce();
})();
