// auxdetect.js
// window watcher, observers and identifies CODE, JSON, and INQ requests, and initiates on user click to send to verbatim via auxio

if (typeof window.__AUX_DETECT_READY__ === 'undefined') window.__AUX_DETECT_READY__ = false;
if (typeof window.__AUX_DETECTED_ANCHORS__ === 'undefined') window.__AUX_DETECTED_ANCHORS__ = new WeakSet();
if (typeof window.__AUX_OVERLAY_ITEMS__ === 'undefined') window.__AUX_OVERLAY_ITEMS__ = [];
if (typeof window.__AUX_OVERLAY_BOUND__ === 'undefined') window.__AUX_OVERLAY_BOUND__ = false;
if (typeof window.__AUX_SCAN_TIMER__ === 'undefined') window.__AUX_SCAN_TIMER__ = null;

if (!window.__AUX_DETECT_READY__ && auxHostAllowed()) {
  window.__AUX_DETECT_READY__ = true;
  installAuxDetectRuntime();
  startAuxScanner();
}

function auxHostAllowed() {
  const host = String(location.hostname || '').toLowerCase();
  return [
    'chatgpt.com', 
    'chat.openai.com', 
    'gemini.google.com', 
    'claude.ai', 
    'copilot.microsoft.com', 
    'aistudio.google.com'
  ].includes(host);
}

function installAuxDetectRuntime() {
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message?.type === 'AUX_PING_CONTENT') sendResponse({ ok: true, owner: 'auxdetect' });
    if (message?.type === 'AUX_MANUAL_ELEMENT_SCRAPE') { scanAuxPage(document); sendResponse({ ok: true }); }
    if (message?.type === 'AUX_CHAT_INSERT') sendResponse(insertTextIntoChat(message.text, { submit: Boolean(message.submit) }));
    return true;
  });
}

function startAuxScanner(root = document) {
  scanAuxPage(root);
  const observer = new MutationObserver(() => {
    clearTimeout(window.__AUX_SCAN_TIMER__);
    window.__AUX_SCAN_TIMER__ = setTimeout(() => scanAuxPage(root), 220);
  });
  observer.observe(root.body || root, { childList: true, subtree: true });
  if (!window.__AUX_OVERLAY_BOUND__) {
    window.__AUX_OVERLAY_BOUND__ = true;
    window.addEventListener('scroll', renderAuxOverlay, true);
    window.addEventListener('resize', renderAuxOverlay, true);
  }
  return observer;
}

function scanAuxPage(root = document) {
  // 1. Scan Container Codeblocks
  Array.from(root.querySelectorAll('button, [role="button"], input[type="button"]'))
    .filter(btn => ['copy', 'clone'].some(k => [btn.getAttribute('aria-label'), btn.getAttribute('title'), btn.innerText, btn.className].join(' ').toLowerCase().includes(k)))
    .forEach(copyButton => {
      if (window.__AUX_DETECTED_ANCHORS__.has(copyButton)) return;
      const host = copyButton.closest('pre') || copyButton.closest('code') || copyButton.closest('[class*="code" i]');
      if (!host || window.__AUX_DETECTED_ANCHORS__.has(host)) return;

      const clone = host.cloneNode(true);
      clone.querySelectorAll('.aux-inline-wrap, .aux-inline-menu, button, [role="button"]').forEach(n => n.remove());
      const payload = String(clone.innerText || clone.textContent || '').trim();
      if (!payload) return;

      window.__AUX_DETECTED_ANCHORS__.add(copyButton);
      window.__AUX_DETECTED_ANCHORS__.add(host);

      // Classify RecordingSheet-shaped JSON before falling back to CODE.
      if (isRecordingSheetJson(payload)) {
        decorateDetectedItem(copyButton, 'JSON', payload, [
          { label: 'AUX', button: 'jsonaux' },
          { label: 'VRBM', button: 'jsonvrbm' }
        ]);
      } else if (payload.length > 40) {
        decorateDetectedItem(copyButton, 'CODE', payload, [
          { label: 'AUX', button: 'codeaux' }
        ]);
      }
    });

  const scanRoot = root.body || root;
  const walker = document.createTreeWalker(scanRoot, NodeFilter.SHOW_TEXT, {
    acceptNode(node) {
      if (node.parentElement?.closest('script, style, textarea, input, .aux-inline-wrap, #aux-overlay-root, pre, code')) return NodeFilter.FILTER_REJECT;
      return String(node.nodeValue || '').includes('AUXCALL@') ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
    }
  });

  let textNode;
  while ((textNode = walker.nextNode())) {
    const host = textNode.parentElement;
    if (!host || window.__AUX_DETECTED_ANCHORS__.has(host)) continue;
    const match = String(textNode.nodeValue || '').match(/AUXCALL@\s*(\S+)/i);
    if (match?.[1]) {
      window.__AUX_DETECTED_ANCHORS__.add(host);
      decorateDetectedItem(host, 'INQUIRY', `AUXCALL@${match[1].replace(/[\]\s]+$/, '')}`, [
        { label: 'AUX', button: 'inqaux' },
        { label: 'VRBM', button: 'inqvrbm' },
        { label: 'AUTO', button: 'inqdirect' }
      ]);
    }
  }
}

function isRecordingSheetJson(text) {
  const raw = String(text || '').trim();
  if (!raw || !raw.includes('{') || !raw.includes('}')) return false;

  const parseCandidates = value => {
    const candidates = [
      value,
      value.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/i, '').trim()
    ];

    const fencePattern = /```(?:json)?\s*([\s\S]*?)\s*```/gi;
    let fence = null;
    while ((fence = fencePattern.exec(value))) {
      if (fence[1]) candidates.push(fence[1].trim());
    }

    const firstObject = value.indexOf('{');
    const lastObject = value.lastIndexOf('}');
    if (firstObject !== -1 && lastObject > firstObject) candidates.push(value.slice(firstObject, lastObject + 1));

    const firstArray = value.indexOf('[');
    const lastArray = value.lastIndexOf(']');
    if (firstArray !== -1 && lastArray > firstArray) candidates.push(value.slice(firstArray, lastArray + 1));

    return [...new Set(candidates.filter(Boolean))]
      .map(candidate => {
        try { return JSON.parse(candidate); }
        catch { return null; }
      })
      .filter(Boolean);
  };

  const isSheet = value => {
    if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
    const keys = Object.keys(value).map(key => key.toLowerCase());
    return keys.includes('action') &&
      keys.includes('filepath') &&
      keys.includes('payload') &&
      (
        keys.includes('task') ||
        keys.includes('enhancement') ||
        keys.includes('diagnostic')
      );
  };

  const visit = value => {
    if (isSheet(value)) return true;
    if (Array.isArray(value)) return value.some(visit);
    if (!value || typeof value !== 'object') return false;
    return Object.values(value).some(visit);
  };

  if (parseCandidates(raw).some(visit)) return true;

  const hasKey = key => new RegExp(`["']?${key}["']?\\s*:`, 'i').test(raw);
  return hasKey('Action') &&
    hasKey('FilePath') &&
    hasKey('Payload') &&
    (
      hasKey('Task') ||
      hasKey('Enhancement') ||
      hasKey('Diagnostic')
    );
}
function decorateDetectedItem(anchor, stream, payload, actions) {
  ensureAuxInlineStyles();
  window.__AUX_OVERLAY_ITEMS__.push({ anchor, stream, payload, actions });
  renderAuxOverlay();
}

function renderAuxOverlay() {
  const root = getAuxOverlayRoot();
  window.__AUX_OVERLAY_ITEMS__ = window.__AUX_OVERLAY_ITEMS__.filter(item => item.anchor?.isConnected);
  root.innerHTML = '';

  window.__AUX_OVERLAY_ITEMS__.forEach(item => {
    const rect = item.anchor.getBoundingClientRect();
    if ((!rect.width && !rect.height) || rect.bottom < 0 || rect.top > window.innerHeight) return;

    const wrap = document.createElement('span');
    wrap.className = 'aux-inline-wrap aux-overlay-wrap';
    wrap.style.left = `${Math.min(window.innerWidth - 128, Math.max(8, rect.right + 8))}px`;
    wrap.style.top = `${Math.max(8, rect.top)}px`;

    const menu = document.createElement('span');
    menu.className = 'aux-inline-menu';

    item.actions.forEach(act => {
      const btn = document.createElement('button');
      btn.className = 'aux-inline-button';
      btn.type = 'button';
      btn.textContent = act.label;
      btn.addEventListener('click', (e) => {
        e.preventDefault(); e.stopPropagation();
        chrome.runtime.sendMessage({
          type: 'AUX_DETECTED_ITEM',
          item: {
            classification: item.stream,
            stream: item.stream,
            button: act.button,
            action: act.button,
            payload: item.payload,
            source: 'inline-click',
            url: location.href,
            at: Date.now()
          }
        });
      });
      menu.appendChild(btn);
    });

    wrap.appendChild(menu);
    root.appendChild(wrap);
  });
}

function getAuxOverlayRoot() {
  let root = document.getElementById('aux-overlay-root');
  if (!root) {
    root = document.createElement('div');
    root.id = 'aux-overlay-root';
    root.className = 'aux-overlay-root';
    document.body.appendChild(root);
  }
  return root;
}

function insertTextIntoChat(text, options = {}) {
  const value = String(text || '');
  if (!value.trim()) return { ok: false, msg: 'No text to insert' };

  const selectors = [
    '#prompt-textarea',
    '[data-testid="prompt-textarea"]',
    'main form textarea',
    'main form [contenteditable="true"]',
    'form textarea',
    'form [contenteditable="true"]',
    'textarea',
    '[contenteditable="true"]'
  ];

  const target = selectors
    .map(selector => document.querySelector(selector))
    .find(el => {
      if (!el) return false;
      const rect = el.getBoundingClientRect();
      return !el.disabled && rect.width > 0 && rect.height > 0;
    });

  if (!target) return { ok: false, msg: 'Chat input not found' };

  target.focus();

  let inserted = false;

  if (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT') {
    const proto = target.tagName === 'TEXTAREA'
      ? HTMLTextAreaElement.prototype
      : HTMLInputElement.prototype;
    const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;

    if (setter) setter.call(target, value);
    else target.value = value;

    inserted = true;
  } else {
    try {
      const dt = new DataTransfer();
      dt.setData('text/plain', value);

      const paste = new ClipboardEvent('paste', {
        bubbles: true,
        cancelable: true,
        clipboardData: dt
      });

      target.dispatchEvent(paste);
      inserted = String(target.innerText || target.textContent || '').includes(value.slice(0, 20));
    } catch {}

    if (!inserted) {
      try {
        const selection = window.getSelection();
        const range = document.createRange();

        range.selectNodeContents(target);
        range.deleteContents();
        range.collapse(true);

        selection.removeAllRanges();
        selection.addRange(range);

        inserted = document.execCommand('insertText', false, value);
      } catch {
        inserted = false;
      }
    }

    if (!inserted) {
      target.textContent = value;
      inserted = true;
    }
  }

  target.dispatchEvent(new InputEvent('input', {
    bubbles: true,
    cancelable: true,
    composed: true,
    inputType: 'insertFromPaste',
    data: value
  }));

  target.dispatchEvent(new Event('change', { bubbles: true }));

  if (options.submit) {
    const sendBtn = Array.from(document.querySelectorAll('button, [role="button"]')).find(btn => {
      const label = [
        btn.getAttribute('aria-label'),
        btn.getAttribute('title'),
        btn.innerText,
        btn.className
      ].join(' ').toLowerCase();

      return ['send', 'submit', 'arrow-up', 'paper'].some(key => label.includes(key));
    });

    if (sendBtn) {
      setTimeout(() => sendBtn.click(), 50);
      return { ok: true, submitted: true };
    }

    target.dispatchEvent(new KeyboardEvent('keydown', {
      bubbles: true,
      cancelable: true,
      key: 'Enter',
      code: 'Enter'
    }));

    return { ok: true, submitted: true, fallback: 'enter' };
  }

  return { ok: true, submitted: false };
}
function ensureAuxInlineStyles() {
  if (document.getElementById('aux-inline-style')) return;
  const style = document.createElement('style');
  style.id = 'aux-inline-style';
  style.textContent = `.aux-overlay-root { position: fixed; inset: 0; z-index: 2147483645; pointer-events: none; contain: layout style; } .aux-inline-wrap { display: inline-flex; align-items: center; gap: 6px; padding: 3px 5px; border: 1px solid rgba(180, 120, 255, 0.42); border-radius: 8px; background: rgba(20, 12, 30, 0.86); color: #f2eaff; font-size: 11px; line-height: 1; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35); } .aux-overlay-wrap { position: fixed; pointer-events: auto; } .aux-inline-menu { display: inline-flex; align-items: center; gap: 4px; } .aux-inline-button { border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 6px; background: rgba(255, 255, 255, 0.08); color: #ffffff; cursor: pointer; font-size: 10px; line-height: 1; padding: 4px 6px; font-weight: 800; letter-spacing: 0.05em; } .aux-inline-button:hover { background: rgba(190, 135, 255, 0.35); }`;
  document.head.appendChild(style);
}