const DEFAULT_HOST = 'https://rspace.online';

// --- Context Menu Setup ---

chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({ id: 'clip-page', title: 'Clip page to rSpace', contexts: ['page'] });
  chrome.contextMenus.create({ id: 'save-link', title: 'Save link to rSpace', contexts: ['link'] });
  chrome.contextMenus.create({ id: 'save-image', title: 'Save image to rSpace', contexts: ['image'] });
  chrome.contextMenus.create({ id: 'clip-selection', title: 'Clip selection to rSpace', contexts: ['selection'] });
  chrome.contextMenus.create({ id: 'unlock-article', title: 'Unlock & Clip article to rSpace', contexts: ['page', 'link'] });
  chrome.contextMenus.create({ id: 'separator-cart', type: 'separator', contexts: ['page', 'link'] });
  chrome.contextMenus.create({ id: 'add-to-cart', title: 'Add to rCart', contexts: ['page', 'link'] });
});

// --- Helpers ---

async function getSettings() {
  const result = await chrome.storage.sync.get(['rspaceHost', 'rspaceSlug']);
  return {
    host: result.rspaceHost || DEFAULT_HOST,
    slug: result.rspaceSlug || '',
  };
}

function apiBase(settings) {
  return settings.slug ? `${settings.host}/${settings.slug}/rnotes` : `${settings.host}/rnotes`;
}

async function getToken() {
  const result = await chrome.storage.local.get(['encryptid_token']);
  return result.encryptid_token || null;
}

async function getDefaultNotebook() {
  const result = await chrome.storage.local.get(['lastNotebookId']);
  return result.lastNotebookId || null;
}

function showNotification(title, message) {
  chrome.notifications.create({
    type: 'basic', iconUrl: 'icons/icon-128.png', title, message,
  });
}

async function createNote(data) {
  const token = await getToken();
  if (!token) { showNotification('rSpace Error', 'Not signed in. Open extension settings.'); return; }

  const settings = await getSettings();
  if (!settings.slug) { showNotification('rSpace Error', 'Configure space slug in extension settings.'); return; }

  const notebookId = await getDefaultNotebook();
  const body = { title: data.title, content: data.content, type: data.type || 'CLIP', url: data.url };
  if (notebookId) body.notebook_id = notebookId;
  if (data.fileUrl) body.file_url = data.fileUrl;
  if (data.mimeType) body.mime_type = data.mimeType;
  if (data.fileSize) body.file_size = data.fileSize;

  const response = await fetch(`${apiBase(settings)}/api/notes`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify(body),
  });
  if (!response.ok) { const text = await response.text(); throw new Error(`${response.status}: ${text}`); }
  return response.json();
}

async function uploadImage(imageUrl) {
  const token = await getToken();
  const settings = await getSettings();

  const imgResponse = await fetch(imageUrl);
  const blob = await imgResponse.blob();
  let filename;
  try { filename = new URL(imageUrl).pathname.split('/').pop() || `image-${Date.now()}.jpg`; }
  catch { filename = `image-${Date.now()}.jpg`; }

  const formData = new FormData();
  formData.append('file', blob, filename);

  const response = await fetch(`${apiBase(settings)}/api/uploads`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${token}` },
    body: formData,
  });
  if (!response.ok) { const text = await response.text(); throw new Error(`Upload failed: ${response.status} ${text}`); }
  return response.json();
}

async function unlockArticle(url) {
  const token = await getToken();
  if (!token) { showNotification('rSpace Error', 'Not signed in.'); return null; }

  const settings = await getSettings();
  const response = await fetch(`${apiBase(settings)}/api/articles/unlock`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify({ url }),
  });
  if (!response.ok) { const text = await response.text(); throw new Error(`Unlock failed: ${response.status} ${text}`); }
  return response.json();
}

// --- Context Menu Handler ---

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  try {
    switch (info.menuItemId) {
      case 'clip-page': {
        let content = '';
        try {
          const [result] = await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: () => document.body.innerHTML });
          content = result?.result || '';
        } catch { content = `<p>Clipped from <a href="${tab.url}">${tab.url}</a></p>`; }
        await createNote({ title: tab.title || 'Untitled Clip', content, type: 'CLIP', url: tab.url });
        showNotification('Page Clipped', `"${tab.title}" saved to rSpace`);
        break;
      }
      case 'save-link': {
        const linkUrl = info.linkUrl;
        const linkText = info.selectionText || linkUrl;
        await createNote({ title: linkText, content: `<p><a href="${linkUrl}">${linkText}</a></p><p>Found on: <a href="${tab.url}">${tab.title}</a></p>`, type: 'BOOKMARK', url: linkUrl });
        showNotification('Link Saved', 'Bookmark saved to rSpace');
        break;
      }
      case 'save-image': {
        const upload = await uploadImage(info.srcUrl);
        await createNote({ title: `Image from ${tab.title || 'page'}`, content: `<p><img src="${upload.url}" alt="Clipped image" /></p><p>Source: <a href="${tab.url}">${tab.title}</a></p>`, type: 'IMAGE', url: tab.url, fileUrl: upload.url, mimeType: upload.mimeType, fileSize: upload.size });
        showNotification('Image Saved', 'Image saved to rSpace');
        break;
      }
      case 'unlock-article': {
        const targetUrl = info.linkUrl || tab.url;
        showNotification('Unlocking Article', `Finding readable version of ${new URL(targetUrl).hostname}...`);
        const result = await unlockArticle(targetUrl);
        if (result?.success && result.archiveUrl) {
          await createNote({ title: tab.title || 'Unlocked Article', content: `<p>Unlocked via ${result.strategy}</p><p>Original: <a href="${targetUrl}">${targetUrl}</a></p><p>Archive: <a href="${result.archiveUrl}">${result.archiveUrl}</a></p>`, type: 'CLIP', url: targetUrl });
          showNotification('Article Unlocked', `Readable version found via ${result.strategy}`);
          chrome.tabs.create({ url: result.archiveUrl });
        } else {
          showNotification('Unlock Failed', result?.error || 'No archived version found');
        }
        break;
      }
      case 'add-to-cart': {
        const targetUrl = info.linkUrl || tab.url;
        const { selectedSpace } = await chrome.storage.sync.get(['selectedSpace']);
        const space = selectedSpace || 'demo';
        const settings = await getSettings();
        const token = await getToken();

        const headers = { 'Content-Type': 'application/json' };
        if (token) headers['Authorization'] = `Bearer ${token}`;

        const res = await fetch(`${settings.host}/${space}/rcart/api/cart/quick-add`, {
          method: 'POST',
          headers,
          body: JSON.stringify({ url: targetUrl }),
        });

        if (res.ok) {
          const added = await res.json();
          showNotification('Added to rCart', added.name || `Item from ${new URL(targetUrl).hostname}`);
          updateCartBadge(space);
        } else {
          showNotification('rCart Error', `Failed to add item (${res.status})`);
        }
        break;
      }
      case 'clip-selection': {
        let content = '';
        try {
          const [result] = await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: () => { const s = window.getSelection(); if (!s || s.rangeCount === 0) return ''; const r = s.getRangeAt(0); const d = document.createElement('div'); d.appendChild(r.cloneContents()); return d.innerHTML; } });
          content = result?.result || '';
        } catch { content = `<p>${info.selectionText || ''}</p>`; }
        if (!content && info.selectionText) content = `<p>${info.selectionText}</p>`;
        await createNote({ title: `Selection from ${tab.title || 'page'}`, content, type: 'CLIP', url: tab.url });
        showNotification('Selection Clipped', 'Saved to rSpace');
        break;
      }
    }
  } catch (err) {
    console.error('Context menu action failed:', err);
    showNotification('rSpace Error', err.message || 'Failed to save');
  }
});

// --- Keyboard shortcut handler ---

chrome.commands.onCommand.addListener(async (command) => {
  if (command === 'open-voice-recorder') {
    const settings = await getSettings();
    const voiceUrl = settings.slug ? `${settings.host}/${settings.slug}/rnotes/voice` : `${settings.host}/rnotes/voice`;
    chrome.windows.create({ url: voiceUrl, type: 'popup', width: 400, height: 600, focused: true });
  }
});

// --- Cart Badge ---

async function updateCartBadge(space) {
  if (!space) {
    const result = await chrome.storage.sync.get(['selectedSpace']);
    space = result.selectedSpace || 'demo';
  }
  try {
    const settings = await getSettings();
    const token = await getToken();
    const headers = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;

    const res = await fetch(`${settings.host}/${space}/rcart/api/cart/summary`, { headers });
    if (res.ok) {
      const summary = await res.json();
      const count = summary.totalItems || 0;
      chrome.action.setBadgeText({ text: count > 0 ? String(count) : '' });
      chrome.action.setBadgeBackgroundColor({ color: '#6366f1' });
    }
  } catch {
    // Badge update is best-effort
  }
}

// Update badge on startup
chrome.runtime.onStartup?.addListener(() => updateCartBadge());

// --- Message Handler ---

chrome.runtime.onMessage.addListener((message) => {
  if (message.type === 'notify') showNotification(message.title, message.message);
  if (message.type === 'cart-settings-changed') updateCartBadge(message.space);
  if (message.type === 'cart-item-added') updateCartBadge(message.space);
});
