/**
 * Background Service Worker
 * Nhiệm vụ:
 * 1. Handle SYNC_AUTH từ content script (auto-sync Clerk token)
 * 2. Handle SAVE_NOTE từ content script (gọi API save memo)
 * 3. Handle REFRESH_TOKEN từ popup (refresh Clerk JWT trước khi gọi API)
 */

import { createMemo } from '../shared/api-client';

/**
 * Grab fresh Clerk token from ANY OpenNotion tab
 * Scans all open tabs, finds OpenNotion, injects script to get token
 */
async function grabFreshToken(): Promise<string | null> {
  try {
    const allTabs = await chrome.tabs.query({});
    const candidates = allTabs.filter((t) => {
      const url = t.url || '';
      return (
        url.includes('172.16.2.210') ||
        url.includes('localhost:3001') ||
        url.includes('opennotion') ||
        url.includes('cucunote')
      );
    });

    for (const tab of candidates) {
      if (!tab.id) continue;
      try {
        const results = await chrome.scripting.executeScript({
          target: { tabId: tab.id },
          world: 'MAIN',
          func: async () => {
            try {
              const clerk = (window as any).Clerk;
              if (clerk?.session?.getToken) {
                return await clerk.session.getToken();
              }
            } catch { /* Clerk not available */ }
            return null;
          },
        });
        const token = results[0]?.result;
        if (token) {
          await chrome.storage.local.set({
            clerkSessionToken: token,
            clerkTokenSyncedAt: Date.now(),
          });
          console.log('[CuCu BG] ✅ Fresh token from tab', tab.id, `(${token.length} chars)`);
          return token;
        }
      } catch {
        // This tab didn't work, try next
      }
    }
  } catch {
    // Tab scanning failed
  }
  return null;
}

chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
  // ============ AUTO-SYNC AUTH TOKEN ============
  if (message.type === 'SYNC_AUTH') {
    const { clerkSessionToken } = message.data || {};
    if (clerkSessionToken) {
      chrome.storage.local.set({
        clerkSessionToken,
        clerkTokenSyncedAt: Date.now(),
      });
      console.log('[CuCu BG] ✅ Clerk token auto-synced from content script');
    }
    sendResponse({ success: true });
    return false; // synchronous response
  }

  // ============ REFRESH TOKEN (popup requests fresh token) ============
  if (message.type === 'REFRESH_TOKEN') {
    // Scan ALL OpenNotion tabs to get a fresh Clerk JWT
    grabFreshToken()
      .then((token) => {
        if (token) {
          sendResponse({ success: true, token });
        } else {
          sendResponse({ success: false, reason: 'no_opennotion_tab' });
        }
      })
      .catch((err) => {
        console.log('[CuCu BG] ❌ Token refresh failed:', err?.message);
        sendResponse({ success: false, reason: err?.message });
      });
    return true; // keep channel open for async
  }

  // ============ SHOW NOTE FORM ============
  if (message.type === 'SHOW_NOTE_FORM') {
    // Mở popup với note form
    chrome.action.openPopup();

    // Lưu data vào storage để popup có thể lấy
    chrome.storage.local.set({
      pendingNote: message.data,
    });

    sendResponse({ success: true });
  }

  // ============ SAVE NOTE ============
  else if (message.type === 'SAVE_NOTE') {
    // Auto save note ngay lập tức
    const { text, url, title } = message.data;

    // Parse tags từ URL
    const domain = new URL(url).hostname.replace('www.', '');
    const tagList = [domain, 'web-highlight'];

    // Add source info vào content
    const contentWithSource = `${text}\n\n---\nSource: [${title}](${url})`;

    // Gọi API để save (có gửi kèm Clerk token trong Authorization header)
    const memoData = {
      content: contentWithSource,
      tags: tagList,
      visibility: 'PRIVATE',
    };

    createMemo(memoData)
      .then((memo) => {
        sendResponse({ success: true, memo });
      })
      .catch((error) => {
        sendResponse({ success: false, error: error.message });
      });

    return true; // Keep channel open for async
  }

  return true; // Keep channel open for async response
});
