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

let currentTab = null;
let selectedText = '';
let selectedHtml = '';

// --- 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;
}

function decodeToken(token) {
  try {
    const payload = JSON.parse(atob(token.split('.')[1]));
    if (payload.exp && payload.exp * 1000 < Date.now()) return null;
    return payload;
  } catch { return null; }
}

function parseTags(tagString) {
  if (!tagString || !tagString.trim()) return [];
  return tagString.split(',').map(t => t.trim().toLowerCase()).filter(Boolean);
}

function showStatus(message, type) {
  const el = document.getElementById('status');
  el.textContent = message;
  el.className = `status ${type}`;
  if (type === 'success') {
    setTimeout(() => { el.className = 'status'; }, 3000);
  }
}

// --- API calls ---

async function createNote(data) {
  const token = await getToken();
  const settings = await getSettings();

  if (!settings.slug) {
    showStatus('Configure space slug in Settings first', 'error');
    return;
  }

  const body = {
    title: data.title,
    content: data.content,
    type: data.type || 'CLIP',
    url: data.url,
  };

  const notebookId = document.getElementById('notebook').value;
  if (notebookId) body.notebook_id = notebookId;

  const tags = parseTags(document.getElementById('tags').value);
  if (tags.length > 0) body.tags = tags;

  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 fetchNotebooks() {
  const token = await getToken();
  const settings = await getSettings();
  if (!settings.slug) return [];

  const response = await fetch(`${apiBase(settings)}/api/notebooks`, {
    headers: { 'Authorization': `Bearer ${token}` },
  });

  if (!response.ok) return [];
  const data = await response.json();
  return data.notebooks || (Array.isArray(data) ? data : []);
}

// --- UI ---

async function populateNotebooks() {
  const select = document.getElementById('notebook');
  try {
    const notebooks = await fetchNotebooks();
    for (const nb of notebooks) {
      const option = document.createElement('option');
      option.value = nb.id;
      option.textContent = nb.title;
      select.appendChild(option);
    }

    const { lastNotebookId } = await chrome.storage.local.get(['lastNotebookId']);
    if (lastNotebookId) select.value = lastNotebookId;
  } catch (err) {
    console.error('Failed to load notebooks:', err);
  }
}

function setupNotebookMemory() {
  document.getElementById('notebook').addEventListener('change', (e) => {
    chrome.storage.local.set({ lastNotebookId: e.target.value });
  });
}

async function init() {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  currentTab = tab;

  document.getElementById('pageTitle').textContent = tab.title || 'Untitled';
  document.getElementById('pageUrl').textContent = tab.url || '';

  const token = await getToken();
  const claims = token ? decodeToken(token) : null;
  const settings = await getSettings();

  if (!claims) {
    document.getElementById('userStatus').textContent = 'Not signed in';
    document.getElementById('userStatus').classList.add('not-authed');
    document.getElementById('authWarning').style.display = 'block';
    return;
  }

  if (!settings.slug) {
    document.getElementById('userStatus').textContent = 'No space configured';
    document.getElementById('userStatus').classList.add('not-authed');
    document.getElementById('authWarning').style.display = 'block';
    document.getElementById('authWarning').innerHTML = 'Configure your space slug. <a id="openSettings">Open Settings</a>';
    document.getElementById('openSettings')?.addEventListener('click', (e) => { e.preventDefault(); chrome.runtime.openOptionsPage(); });
    return;
  }

  document.getElementById('userStatus').textContent = claims.username || claims.sub?.slice(0, 16) || 'Authenticated';
  document.getElementById('authWarning').style.display = 'none';

  document.getElementById('clipPageBtn').disabled = false;
  document.getElementById('unlockBtn').disabled = false;
  document.getElementById('voiceBtn').disabled = false;

  await populateNotebooks();
  setupNotebookMemory();

  try {
    const [result] = await chrome.scripting.executeScript({
      target: { tabId: tab.id },
      func: () => {
        const selection = window.getSelection();
        if (!selection || selection.rangeCount === 0 || selection.isCollapsed) return { text: '', html: '' };
        const range = selection.getRangeAt(0);
        const div = document.createElement('div');
        div.appendChild(range.cloneContents());
        return { text: selection.toString(), html: div.innerHTML };
      },
    });
    if (result?.result?.text) {
      selectedText = result.result.text;
      selectedHtml = result.result.html;
      document.getElementById('clipSelectionBtn').disabled = false;
    }
  } catch (err) {
    console.warn('Cannot access page content:', err);
  }
}

// --- Event handlers ---

document.getElementById('clipPageBtn').addEventListener('click', async () => {
  const btn = document.getElementById('clipPageBtn');
  btn.disabled = true;
  showStatus('Clipping page...', 'loading');

  try {
    let pageContent = '';
    try {
      const [result] = await chrome.scripting.executeScript({
        target: { tabId: currentTab.id },
        func: () => document.body.innerHTML,
      });
      pageContent = result?.result || '';
    } catch {
      pageContent = `<p>Clipped from <a href="${currentTab.url}">${currentTab.url}</a></p>`;
    }

    await createNote({
      title: currentTab.title || 'Untitled Clip',
      content: pageContent,
      type: 'CLIP',
      url: currentTab.url,
    });

    showStatus('Clipped! Note saved.', 'success');
    chrome.runtime.sendMessage({ type: 'notify', title: 'Page Clipped', message: `"${currentTab.title}" saved to rSpace` });
  } catch (err) {
    showStatus(`Error: ${err.message}`, 'error');
  } finally {
    btn.disabled = false;
  }
});

document.getElementById('clipSelectionBtn').addEventListener('click', async () => {
  const btn = document.getElementById('clipSelectionBtn');
  btn.disabled = true;
  showStatus('Clipping selection...', 'loading');

  try {
    const content = selectedHtml || `<p>${selectedText}</p>`;
    await createNote({
      title: `Selection from ${currentTab.title || 'page'}`,
      content,
      type: 'CLIP',
      url: currentTab.url,
    });

    showStatus('Selection clipped!', 'success');
    chrome.runtime.sendMessage({ type: 'notify', title: 'Selection Clipped', message: 'Saved to rSpace' });
  } catch (err) {
    showStatus(`Error: ${err.message}`, 'error');
  } finally {
    btn.disabled = false;
  }
});

document.getElementById('unlockBtn').addEventListener('click', async () => {
  const btn = document.getElementById('unlockBtn');
  btn.disabled = true;
  showStatus('Unlocking article...', 'loading');

  try {
    const token = await getToken();
    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: currentTab.url }),
    });
    const result = await response.json();

    if (result.success && result.archiveUrl) {
      await createNote({
        title: currentTab.title || 'Unlocked Article',
        content: `<p>Unlocked via ${result.strategy}</p><p>Original: <a href="${currentTab.url}">${currentTab.url}</a></p><p>Archive: <a href="${result.archiveUrl}">${result.archiveUrl}</a></p>`,
        type: 'CLIP',
        url: currentTab.url,
      });
      showStatus(`Unlocked via ${result.strategy}! Opening...`, 'success');
      chrome.tabs.create({ url: result.archiveUrl });
    } else {
      showStatus(result.error || 'No archived version found', 'error');
    }
  } catch (err) {
    showStatus(`Error: ${err.message}`, 'error');
  } finally {
    btn.disabled = false;
  }
});

document.getElementById('voiceBtn').addEventListener('click', async () => {
  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 });
  window.close();
});

document.getElementById('optionsLink').addEventListener('click', (e) => {
  e.preventDefault();
  chrome.runtime.openOptionsPage();
});

document.getElementById('openSettings')?.addEventListener('click', (e) => {
  e.preventDefault();
  chrome.runtime.openOptionsPage();
});

// --- Mode switching ---

document.querySelectorAll('.mode-tab').forEach((tab) => {
  tab.addEventListener('click', () => {
    const mode = tab.dataset.mode;
    document.querySelectorAll('.mode-tab').forEach((t) => t.classList.remove('active'));
    tab.classList.add('active');

    document.getElementById('clipperPanel').style.display = mode === 'clipper' ? '' : 'none';
    document.getElementById('cartPanel').style.display = mode === 'cart' ? '' : 'none';

    chrome.storage.local.set({ lastPopupMode: mode });

    if (mode === 'cart') initCartMode();
  });
});

// --- Cart helpers ---

function showCartStatus(message, type) {
  const el = document.getElementById('cartStatus');
  el.textContent = message;
  el.className = `cart-status ${type}`;
  if (type === 'success') {
    setTimeout(() => { el.className = 'cart-status'; }, 3000);
  }
}

async function fetchSpaces() {
  const settings = await getSettings();
  const token = await getToken();
  try {
    const headers = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;
    const res = await fetch(`${settings.host}/api/spaces`, { headers });
    if (res.ok) {
      const data = await res.json();
      return data.spaces || data || [];
    }
  } catch {}
  return [{ slug: 'demo', name: 'demo' }];
}

async function fetchCarts(space) {
  const settings = await getSettings();
  const token = await getToken();
  try {
    const headers = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;
    const res = await fetch(`${settings.host}/${space}/rcart/api/shopping-carts`, { headers });
    if (res.ok) {
      const data = await res.json();
      return data.carts || [];
    }
  } catch {}
  return [];
}

async function fetchCartSummary(space) {
  const settings = await getSettings();
  const token = await getToken();
  try {
    const headers = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;
    const res = await fetch(`${settings.host}/${space}/rcart/api/cart/summary`, { headers });
    if (res.ok) return res.json();
  } catch {}
  return null;
}

function renderCartPreview(summary) {
  const el = document.getElementById('cartPreview');
  if (!summary || summary.totalItems === 0) {
    el.innerHTML = '<div class="empty-msg">Cart is empty</div>';
    return;
  }

  const vendors = summary.vendorGroups || [];
  const vendorHtml = vendors.map((v) =>
    `<div class="vendor-bullet">${v.domain || v.vendor || 'unknown'} (${v.count || v.items || 0})</div>`
  ).join('');

  el.innerHTML = `
    <div class="preview-card">
      <div class="preview-row"><span>Items</span><span class="value">${summary.totalItems}</span></div>
      <div class="preview-row"><span>Total</span><span class="value">$${(summary.totalAmount || 0).toFixed(2)}</span></div>
      ${vendors.length > 0 ? `<div class="vendor-list">${vendorHtml}</div>` : ''}
    </div>`;
}

async function initCartMode() {
  const spaceSelect = document.getElementById('spaceSelect');
  const cartSelect = document.getElementById('cartSelect');

  // Populate spaces
  const spaces = await fetchSpaces();
  const { selectedSpace } = await chrome.storage.sync.get(['selectedSpace']);
  const currentSpace = selectedSpace || 'demo';

  spaceSelect.innerHTML = '';
  for (const s of spaces) {
    const opt = document.createElement('option');
    opt.value = s.slug || s.name || s;
    opt.textContent = s.name || s.slug || s;
    spaceSelect.appendChild(opt);
  }
  // Ensure current space option exists
  if (!spaceSelect.querySelector(`option[value="${currentSpace}"]`)) {
    const opt = document.createElement('option');
    opt.value = currentSpace;
    opt.textContent = currentSpace;
    spaceSelect.prepend(opt);
  }
  spaceSelect.value = currentSpace;

  // Load carts for this space
  await loadCartsForSpace(currentSpace);
}

async function loadCartsForSpace(space) {
  const cartSelect = document.getElementById('cartSelect');
  cartSelect.innerHTML = '<option value="">Loading...</option>';

  const carts = await fetchCarts(space);
  const { selectedCartId } = await chrome.storage.sync.get(['selectedCartId']);

  cartSelect.innerHTML = '';
  if (carts.length === 0) {
    cartSelect.innerHTML = '<option value="">No carts</option>';
    renderCartPreview(null);
    return;
  }

  for (const c of carts) {
    const opt = document.createElement('option');
    opt.value = c.id;
    opt.textContent = c.name || c.id;
    cartSelect.appendChild(opt);
  }

  if (selectedCartId && cartSelect.querySelector(`option[value="${selectedCartId}"]`)) {
    cartSelect.value = selectedCartId;
  }

  // Load preview
  const summary = await fetchCartSummary(space);
  renderCartPreview(summary);
}

// Space change handler
document.getElementById('spaceSelect').addEventListener('change', async (e) => {
  const space = e.target.value;
  await chrome.storage.sync.set({ selectedSpace: space });
  await loadCartsForSpace(space);
  chrome.runtime.sendMessage({ type: 'cart-settings-changed', space });
});

// Cart change handler
document.getElementById('cartSelect').addEventListener('change', async (e) => {
  await chrome.storage.sync.set({ selectedCartId: e.target.value });
});

// Add to Cart
document.getElementById('addToCartBtn').addEventListener('click', async () => {
  const btn = document.getElementById('addToCartBtn');
  btn.disabled = true;
  showCartStatus('Detecting product...', 'loading');

  try {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    const settings = await getSettings();
    const token = await getToken();
    const { selectedSpace } = await chrome.storage.sync.get(['selectedSpace']);
    const space = selectedSpace || 'demo';

    // Try to detect product info from the page
    let product = null;
    try {
      const [result] = await chrome.scripting.executeScript({
        target: { tabId: tab.id },
        func: () => {
          // Try JSON-LD
          const ldScripts = document.querySelectorAll('script[type="application/ld+json"]');
          for (const s of ldScripts) {
            try {
              const data = JSON.parse(s.textContent);
              const item = data['@type'] === 'Product' ? data : (Array.isArray(data['@graph']) ? data['@graph'].find(i => i['@type'] === 'Product') : null);
              if (item) {
                return {
                  name: item.name,
                  image: item.image?.url || item.image?.[0] || item.image,
                  price: item.offers?.price || item.offers?.[0]?.price,
                  currency: item.offers?.priceCurrency || item.offers?.[0]?.priceCurrency,
                };
              }
            } catch {}
          }
          // Fallback to meta tags
          const title = document.querySelector('meta[property="og:title"]')?.content || document.title;
          const image = document.querySelector('meta[property="og:image"]')?.content;
          return { name: title, image };
        },
      });
      if (result?.result?.name) product = result.result;
    } catch {}

    showCartStatus('Adding to cart...', 'loading');

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

    const body = { url: tab.url };
    if (product) body.product = product;

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

    if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);

    const added = await res.json();
    showCartStatus(`Added: ${added.name || product?.name || 'item'}`, 'success');

    // Update preview
    const summary = await fetchCartSummary(space);
    renderCartPreview(summary);

    // Notify background to update badge
    chrome.runtime.sendMessage({ type: 'cart-item-added', space });
  } catch (err) {
    showCartStatus(`Error: ${err.message}`, 'error');
  } finally {
    btn.disabled = false;
  }
});

// View Cart
document.getElementById('viewCartBtn').addEventListener('click', async () => {
  const settings = await getSettings();
  const { selectedSpace } = await chrome.storage.sync.get(['selectedSpace']);
  const space = selectedSpace || 'demo';
  chrome.tabs.create({ url: `${settings.host}/${space}/rcart` });
  window.close();
});

// --- Init ---

document.addEventListener('DOMContentLoaded', async () => {
  await init();

  // Restore last popup mode
  const { lastPopupMode } = await chrome.storage.local.get(['lastPopupMode']);
  if (lastPopupMode === 'cart') {
    document.querySelectorAll('.mode-tab').forEach((t) => t.classList.remove('active'));
    document.querySelector('.mode-tab[data-mode="cart"]').classList.add('active');
    document.getElementById('clipperPanel').style.display = 'none';
    document.getElementById('cartPanel').style.display = '';
    initCartMode();
  }
});
