/**
 * viewer-bridge.js
 * In MV3, data URLs and inline scripts are strictly forbidden by CSP.
 * To render arbitrary HTML with inline scripts, we MUST use a sandboxed iframe.
 */

chrome.storage.local.get(['render_html_content'], (res) => {
  const html = res.render_html_content;

  if (!html) {
    document.getElementById('loadingMsg').innerHTML =
      '<h2>📭 没有可显示的内容</h2><p>请在侧边栏聊天中发送"查看爆款报告"获取最新报告。</p>';
    return;
  }

  console.log('[Viewer] HTML loaded from storage, length:', html.length);

  // Use the sandboxed page
  const frame = document.getElementById('frame');
  frame.src = "sandbox.html";
  frame.style.display = 'block';
  document.getElementById('loadingMsg').style.display = 'none';

  // Wait for iframe to load before sending the HTML
  frame.onload = () => {
     frame.contentWindow.postMessage({ type: 'load_html', html: html }, '*');
     console.log('[Viewer] Sent HTML to sandboxed iframe');
  };
});

// Bridge: listen for postMessage from the sandboxed iframe and relay to background.js
window.addEventListener('message', (event) => {
  if (!event.data) return;

  // ── Workflow 回调：__ocSubmit 触发，直接发服务端续跑，不过 LLM ──
  if (event.data.type === '__oc_workflow_callback__') {
    console.log('[Viewer] Workflow callback from sandbox:', event.data.payload);
    chrome.runtime.sendMessage({
      target: 'background',
      action: 'workflow_callback',
      payload: event.data.payload,
    });
    return;
  }

  // ── 二次交互 chain：__ocStartSkill 触发，直接发服务端启动新 skill，不过 LLM ──
  if (event.data.type === '__oc_start_skill__') {
    console.log('[Viewer] Start skill (chain) from sandbox:', event.data.skill_id, event.data.payload);
    chrome.runtime.sendMessage({
      target: 'background',
      action: 'start_skill',
      skill_id: event.data.skill_id,
      payload: event.data.payload,
    });
    return;
  }

  if (event.data.type === 'openclaw_submit') {
    console.log('[Viewer] Received submit from sandbox iframe, relaying...', event.data);
    chrome.runtime.sendMessage({
      target: 'background',
      action: 'dispatch_atomic_skill',
      skill_id: event.data.skill_id,
      payload: event.data.payload
    }, (response) => {
      console.log('[Viewer] Send result:', response);
      try {
        document.getElementById('frame').contentWindow.postMessage({
          type: 'openclaw_submit_ack',
          ok: response && response.ok
        }, '*');
      } catch (e) { /* expected cross-origin */ }
    });
  } else if (event.data.type === 'open_url') {
    console.log('[Viewer] Received open_url from sandbox iframe, opening cleanly via background...');
    chrome.runtime.sendMessage({ target: 'background', action: 'navigate_clean', url: event.data.url });
  }
});

chrome.runtime.onMessage.addListener((msg) => {
  if (msg.type === 'reply') {
    try {
      document.getElementById('frame').contentWindow.postMessage({ type: 'openclaw_unlock' }, '*');
    } catch (e) { /* expected */ }
  }

  // ── Workflow 执行结果：转发给 sandbox iframe 让面板更新 ──
  if (msg.type === 'workflow_result') {
    try {
      document.getElementById('frame').contentWindow.postMessage({
        type: 'workflow_result',
        task_id: msg.task_id,
        result: msg.result,
        error: msg.error,
      }, '*');
    } catch (e) { /* expected */ }
  }

  // ── 二次交互 chain 中的 render_html：服务端 chain 启动新 skill 渲染了新 HTML ──
  // 关键：必须 recreate iframe（不能用 postMessage load_html 重写 DOM）
  // 原因：sandbox iframe 的 window.addEventListener 注册的 listener 不会随 DOM 替换销毁，
  //      旧 skill 的 __oc_workflow_error__/success listener 会和新 skill 的 listener 冲突
  //      （旧的可能整个 body innerHTML 替换 → 新的找不到 DOM 节点）
  if (msg.type === 'render_html_update') {
    try {
      var oldFrame = document.getElementById('frame');
      if (oldFrame) {
        var parent = oldFrame.parentNode;
        var savedStyle = oldFrame.getAttribute('style') || '';
        oldFrame.remove();
        var newFrame = document.createElement('iframe');
        newFrame.id = 'frame';
        newFrame.src = 'sandbox.html';
        if (savedStyle) newFrame.setAttribute('style', savedStyle);
        newFrame.onload = function() {
          newFrame.contentWindow.postMessage({ type: 'load_html', html: msg.html }, '*');
          console.log('[Viewer] chain hot-reload: new iframe loaded, html length=' + (msg.html || '').length);
        };
        parent.appendChild(newFrame);
      }
    } catch (e) {
      console.error('[Viewer] hot-reload error:', e);
    }
  }
});
