// ========= Error & Console Panel (非阻塞右下角显示，包含 console.log 等) =========
export default function installErrorConsolePanel() {
  // ========== 可配置项 ==========
  const MAX_ENTRIES = 400;
  const PANEL_ID = 'js-error-panel';
  const COLLAPSE_LENGTH = 1200; // 超过多少字符时折叠显示
  const CAPTURE_CONSOLE = true; // 是否捕获 console.log/info/warn/debug（保留原行为）
  // ================================

  // 安全 stringify（处理循环引用）
  function getCircularReplacer() {
    const seen = new WeakSet();
    return (key, value) => {
      if (typeof value === 'object' && value !== null) {
        if (seen.has(value)) return '[Circular]';
        seen.add(value);
      }
      return value;
    };
  }
  function safeStringify(x) {
    try {
      if (typeof x === 'string') return x;
      if (x instanceof Error) return x.stack || x.message || String(x);
      return JSON.stringify(x, getCircularReplacer(), 2);
    } catch (e) {
      try {
        return String(x);
      } catch (e2) {
        return '[unstringifiable]';
      }
    }
  }

  // ========== Panel DOM 创建 ==========
  function createPanel() {
    if (document.getElementById(PANEL_ID)) return document.getElementById(PANEL_ID);

    const panel = document.createElement('div');
    panel.id = PANEL_ID;
    Object.assign(panel.style, {
      position: 'fixed',
      right: '12px',
      bottom: '12px',
      width: '460px',
      maxHeight: '45vh',
      boxSizing: 'border-box',
      overflow: 'hidden',
      zIndex: 2147483647,
      fontFamily: 'Menlo,Consolas,monospace',
      fontSize: '12px',
      color: '#fff',
      borderRadius: '8px',
      boxShadow: '0 6px 18px rgba(0,0,0,0.55)',
      background: 'linear-gradient(180deg, rgba(0,0,0,0.86), rgba(24,24,24,0.86))',
      display: 'flex',
      flexDirection: 'column',
      gap: '6px',
      padding: '8px',
    });

    // header
    const header = document.createElement('div');
    Object.assign(header.style, {
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center',
      gap: '8px',
    });
    header.innerHTML = `<strong style="font-size:13px">JS Logs / Errors</strong><span style="opacity:.7;font-size:11px">（非阻塞）</span>`;

    const btns = document.createElement('div');

    const clearBtn = document.createElement('button');
    clearBtn.textContent = '清空';
    Object.assign(clearBtn.style, { marginLeft: '6px', cursor: 'pointer', fontSize: '12px' });
    clearBtn.onclick = () => {
      entriesContainer.innerHTML = '';
      entryCount = 0;
      updateStats();
    };

    const toggleBtn = document.createElement('button');
    toggleBtn.textContent = '隐藏';
    Object.assign(toggleBtn.style, { cursor: 'pointer', fontSize: '12px' });
    toggleBtn.onclick = () => {
      if (entriesContainer.style.display === 'none') {
        entriesContainer.style.display = '';
        toggleBtn.textContent = '隐藏';
      } else {
        entriesContainer.style.display = 'none';
        toggleBtn.textContent = '显示';
      }
    };

    const statsSpan = document.createElement('span');
    statsSpan.style.opacity = '.8';
    statsSpan.style.fontSize = '11px';
    statsSpan.textContent = '0 条';

    btns.appendChild(statsSpan);
    btns.appendChild(toggleBtn);
    btns.appendChild(clearBtn);
    header.appendChild(btns);

    // entries container (scrollable)
    const entriesContainer = document.createElement('div');
    Object.assign(entriesContainer.style, {
      overflowY: 'auto',
      padding: '6px',
      borderRadius: '6px',
      background: 'rgba(0,0,0,0.32)',
      maxHeight: 'calc(45vh - 48px)',
      boxSizing: 'border-box',
    });

    panel.appendChild(header);
    panel.appendChild(entriesContainer);
    document.body.appendChild(panel);

    // helper to update stats
    function updateStats() {
      statsSpan.textContent = `${entryCount} 条`;
    }

    panel._entriesContainer = entriesContainer;
    panel._statsUpdater = updateStats;
    return panel;
  }

  // ========== 添加条目 ==========
  let entryCount = 0;
  function addEntry({
    type = 'log',
    message = '',
    time = new Date().toLocaleString(),
    meta = null,
  }) {
    const panel = createPanel();
    const entriesContainer = panel._entriesContainer;
    const updateStats = panel._statsUpdater;

    // 限制数量
    if (entryCount >= MAX_ENTRIES) {
      const first = entriesContainer.firstChild;
      if (first) entriesContainer.removeChild(first);
      entryCount--;
    }

    const entry = document.createElement('div');
    Object.assign(entry.style, {
      padding: '6px',
      marginBottom: '6px',
      borderRadius: '6px',
      background: 'rgba(255,255,255,0.03)',
    });

    const header = document.createElement('div');
    header.style.display = 'flex';
    header.style.justifyContent = 'space-between';
    header.style.alignItems = 'center';
    header.style.gap = '8px';

    const left = document.createElement('div');
    // 彩色 type 标签
    const colorMap = {
      error: '#ff6b6b',
      'window.onerror': '#ff6b6b',
      resource: '#ff9966',
      unhandledrejection: '#ff8c66',
      'console.error': '#ff6b6b',
      'console.warn': '#ffd966',
      'console.info': '#66bfff',
      'console.log': '#bfbfbf',
      'console.debug': '#a0a0a0',
      'Vue.error (2)': '#ff6b6b',
      'Vue.error (3)': '#ff6b6b',
    };
    const tagColor = colorMap[type] || '#bfbfbf';
    left.innerHTML = `<span style="font-weight:700;color:${tagColor}">${type}</span> <span style="opacity:.7;font-size:11px"> ${time}</span>`;

    const right = document.createElement('div');
    right.style.display = 'flex';
    right.style.gap = '6px';

    const copyBtn = document.createElement('button');
    copyBtn.textContent = '复制';
    Object.assign(copyBtn.style, { cursor: 'pointer', fontSize: '11px' });

    const expandBtn = document.createElement('button');
    expandBtn.textContent = '展开';
    Object.assign(expandBtn.style, { cursor: 'pointer', fontSize: '11px' });

    right.appendChild(copyBtn);
    right.appendChild(expandBtn);
    header.appendChild(left);
    header.appendChild(right);

    const content = document.createElement('pre');
    Object.assign(content.style, {
      whiteSpace: 'pre-wrap',
      wordBreak: 'break-word',
      margin: '6px 0 0 0',
      maxHeight: '240px',
      overflow: 'auto',
      fontSize: '12px',
      lineHeight: '1.3',
      display: 'block',
    });

    // 合成文本（message + meta）
    let txt = typeof message === 'string' ? message : safeStringify(message);
    if (meta) {
      try {
        const metaStr = safeStringify(meta);
        txt = `${txt}\n\n[meta]\n${metaStr}`;
      } catch (e) {}
    }
    const fullText = txt;

    if (txt.length > COLLAPSE_LENGTH) {
      content.textContent = txt.slice(0, COLLAPSE_LENGTH) + '\n\n...（已折叠，点击展开查看全部）';
      expandBtn.onclick = () => {
        content.textContent = fullText;
        expandBtn.style.display = 'none';
        entriesContainer.scrollTop = entriesContainer.scrollHeight;
      };
    } else {
      content.textContent = txt;
      expandBtn.style.display = 'none';
    }

    copyBtn.onclick = () => {
      try {
        navigator.clipboard.writeText(fullText);
      } catch (e) {
        try {
          prompt('复制文本：Ctrl+C, Enter', fullText);
        } catch (ee) {}
      }
    };

    entry.appendChild(header);
    entry.appendChild(content);
    entriesContainer.appendChild(entry);
    entryCount++;
    updateStats();

    // 自动滚到底部
    entriesContainer.scrollTop = entriesContainer.scrollHeight;
  }

  // 报告包装
  function report(obj) {
    try {
      addEntry({
        type: obj.type || 'log',
        message: obj.message || safeStringify(obj),
        time: new Date().toLocaleString(),
        meta: obj.meta || null,
      });
    } catch (e) {
      console.warn('Error panel report failed', e);
    }
  }

  // ========== 捕获逻辑 ==========

  // 传统同步错误
  window.onerror = function (message, source, lineno, colno, error) {
    const msg = `${message}\n at ${source}:${lineno}:${colno}\n${
      error && error.stack ? error.stack : ''
    }`;
    report({ type: 'window.onerror', message: msg });
    return false;
  };

  // 资源加载错误（图片/script/css 等）
  window.addEventListener(
    'error',
    function (event) {
      const target = event.target || event.srcElement;
      if (target && (target.src || target.href)) {
        const tag = target.tagName;
        const url = target.src || target.href;
        report({ type: 'resource', message: `Failed to load resource: <${tag}> ${url}` });
      }
    },
    true
  );

  // 未处理的 Promise 拒绝
  window.addEventListener('unhandledrejection', function (event) {
    report({ type: 'unhandledrejection', message: safeStringify(event.reason) });
  });

  // 捕获 console.*（可选）
  if (CAPTURE_CONSOLE && typeof console !== 'undefined') {
    const methods = ['log', 'info', 'warn', 'error', 'debug'];
    methods.forEach(m => {
      if (!(m in console)) return;
      const orig = console[m].bind(console);
      console[m] = function (...args) {
        try {
          // 生成调用栈（方便定位是谁调用了 console）
          let stack = null;
          try {
            const err = new Error();
            if (err.stack) {
              // 移除前两行（Error + 本函数）
              stack = err.stack.split('\n').slice(2).join('\n');
            }
          } catch (e) {
            stack = null;
          }

          const payload = {
            type: `console.${m}`,
            message: args.map(a => safeStringify(a)).join(' '),
            meta: stack,
          };
          report(payload);
        } catch (e) {
          // noop
        }
        // 保持原有行为
        try {
          orig(...args);
        } catch (e) {}
      };
    });
  }

  // Vue 2 支持（若使用全局 Vue）
  if (typeof Vue !== 'undefined' && Vue && Vue.config) {
    try {
      Vue.config.errorHandler = function (err, vm, info) {
        report({
          type: 'Vue.error (2)',
          message: `${info}\n${err && err.stack ? err.stack : safeStringify(err)}`,
        });
      };
    } catch (e) {
      /* ignore */
    }
  }

  // Vue 3 注册函数（在 main.js 创建 app 后调用）
  window.registerVue3ErrorHandler = function (app) {
    if (!app || !app.config) return;
    app.config.errorHandler = (err, instance, info) => {
      report({
        type: 'Vue.error (3)',
        message: `${info}\n${err && err.stack ? err.stack : safeStringify(err)}`,
      });
    };
  };

  // 立即创建 panel（或可改为按需）
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', createPanel);
  } else createPanel();
}
// ========= End Panel =========
