/**
 * Side Panel 使用全局（无 tabId）配置，避免按标签页绑定导致切换网页时面板卸载/重建。
 * 路由侧配合 createMemoryHistory，避免 hash URL 触发部分浏览器对侧栏 iframe 的重挂。
 *
 * 任务完成通知：侧栏面板在检测到智能任务生成完成时，通过 runtime.sendMessage 通知
 * Service Worker，由 SW 统一弹出系统通知。
 *
 * 网页上下文：右键「发送到知了探讨」把当前页标题/地址与划选写入 session storage，
 * 侧栏探讨页消费后拼进消息。只读页面，不向网页注入登录 Token。
 */
const PAGE_CONTEXT_PENDING_KEY = 'zl_ext_page_context_pending';
const MENU_SEND_SELECTION = 'zhiliao-send-selection';
const MENU_SEND_PAGE = 'zhiliao-send-page';

function reportSidePanelError(error) {
  if (typeof console !== 'undefined') console.warn('[extension] side panel initialization failed', error);
}

chrome.sidePanel
  .setOptions({ path: 'sidepanel.html', enabled: true })
  .catch(reportSidePanelError);

chrome.sidePanel
  .setPanelBehavior({ openPanelOnActionClick: true })
  .catch(reportSidePanelError);

function isRestrictedUrl(url) {
  const u = String(url || '');
  return (
    /^(chrome|edge|about|chrome-extension|devtools|view-source|moz-extension):/i.test(u) ||
    /chromewebstore\.google\.com/i.test(u) ||
    /chrome\.google\.com\/webstore/i.test(u)
  );
}

function originHostname(url) {
  try {
    return new URL(url).hostname || '';
  } catch {
    return '';
  }
}

/** 注入到网页：只读标题、地址、描述与划选 */
function readPageContextInTab() {
  const selection = String(window.getSelection?.()?.toString() || '')
    .replace(/\u00a0/g, ' ')
    .replace(/[ \t]+\n/g, '\n')
    .replace(/\n{3,}/g, '\n\n')
    .trim()
    .slice(0, 8000);
  const meta =
    document.querySelector('meta[name="description"]') ||
    document.querySelector('meta[property="og:description"]');
  const description = String(meta?.getAttribute('content') || '')
    .replace(/\s+/g, ' ')
    .trim()
    .slice(0, 400);
  return {
    url: location.href,
    title: String(document.title || '').trim(),
    hostname: location.hostname || '',
    selection,
    description,
  };
}

function emptyPageContext(tab, selectionText) {
  const url = String(tab?.url || '');
  return {
    url,
    title: String(tab?.title || '').trim(),
    hostname: originHostname(url),
    selection: String(selectionText || '').trim().slice(0, 8000),
    description: '',
  };
}

async function captureTabContext(tab, selectionText) {
  const fallback = emptyPageContext(tab, selectionText);
  if (!tab?.id || !fallback.url || isRestrictedUrl(fallback.url)) return fallback;
  try {
    const results = await chrome.scripting.executeScript({
      target: { tabId: tab.id },
      func: readPageContextInTab,
    });
    const raw = results?.[0]?.result || {};
    return {
      url: String(raw.url || fallback.url).trim(),
      title: String(raw.title || fallback.title).trim(),
      hostname: String(raw.hostname || fallback.hostname).trim(),
      selection: String(raw.selection || fallback.selection).trim().slice(0, 8000),
      description: String(raw.description || '').trim().slice(0, 400),
    };
  } catch {
    return fallback;
  }
}

async function setPendingPageContext(payload) {
  try {
    if (chrome.storage.session?.set) {
      await chrome.storage.session.set({ [PAGE_CONTEXT_PENDING_KEY]: payload });
      return;
    }
  } catch {
    /* fall through */
  }
  await chrome.storage.local.set({ [PAGE_CONTEXT_PENDING_KEY]: payload });
}

function ensureContextMenus() {
  chrome.contextMenus.removeAll(() => {
    chrome.contextMenus.create({
      id: MENU_SEND_SELECTION,
      title: '发送到知了探讨',
      contexts: ['selection'],
    });
    chrome.contextMenus.create({
      id: MENU_SEND_PAGE,
      title: '本页信息送到知了探讨',
      contexts: ['page'],
    });
  });
}

chrome.runtime.onInstalled.addListener(ensureContextMenus);
chrome.runtime.onStartup.addListener(ensureContextMenus);

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  const isSelection = info.menuItemId === MENU_SEND_SELECTION;
  const isPage = info.menuItemId === MENU_SEND_PAGE;
  if (!isSelection && !isPage) return;

  const captured = await captureTabContext(tab, info.selectionText);
  const selection = String(captured.selection || info.selectionText || '').trim();
  await setPendingPageContext({
    ...captured,
    selection,
    includePage: true,
    includeSelection: Boolean(selection),
  });

  const windowId = tab?.windowId;
  if (windowId != null) {
    try {
      await chrome.sidePanel.open({ windowId });
    } catch (error) {
      if (typeof console !== 'undefined') {
        console.warn('[extension] side panel open failed', error);
      }
    }
  }
});

// ---- 任务完成通知 ----
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'task-completed') {
    const taskName = String(message.taskName || '智能任务').slice(0, 80);
    const preview = String(message.preview || '').slice(0, 120);
    chrome.notifications.create(
      `task-${Date.now()}`,
      {
        type: 'basic',
        iconUrl: 'icons/icon128.png',
        title: '任务生成完成',
        message: `${taskName}\n${preview}`,
        priority: 1,
      },
      () => {
        if (chrome.runtime.lastError) {
          if (typeof console !== 'undefined') {
            console.warn('[extension] notification failed:', chrome.runtime.lastError.message);
          }
        }
      },
    );
    sendResponse({ ok: true });
    return true;
  }
  if (message.type === 'task-failed') {
    const taskName = String(message.taskName || '智能任务').slice(0, 80);
    chrome.notifications.create(
      `task-fail-${Date.now()}`,
      {
        type: 'basic',
        iconUrl: 'icons/icon128.png',
        title: '任务执行失败',
        message: taskName,
        priority: 1,
      },
    );
    sendResponse({ ok: true });
    return true;
  }
  return false;
});
