/**
 * edge-worker-client.js — Main-thread proxy for the edge-worker Web Worker.
 *
 * Spawns js/edge-worker.js as a module Worker and exposes:
 *   classify(text)   → Promise<{
 *                         complexity: 'trivial'|'moderate'|'complex',
 *                         score:      number,
 *                         reason:     string,
 *                         localReply?: string   // only when complexity === 'trivial'
 *                       }>
 *   sentiment(text)  → Promise<{ label:'POSITIVE'|'NEGATIVE'|'NEUTRAL', score }>
 *   onReady(fn)      → register a callback fired when models finish loading
 *   isReady()        → boolean — true once both models are warm
 *   warmup()         → start the worker early so first classify() is fast
 *
 * Complexity tiers (set by the worker):
 *   trivial  — greeting/small-talk; answered locally, 0 sats, no server call
 *   moderate — simple question; show cost preview, route to server
 *   complex  — technical/creative/code; always priced, show cost preview
 *
 * If Web Workers are unavailable (SSR / old browser), all calls fall back
 * gracefully: classify → { complexity:'moderate', ... } so the app still works.
 */

let _worker = null;
let _ready  = false;
let _readyCb = null;
const _pending = new Map(); // id → { resolve, reject }
let _nextId = 1;

function _init() {
  if (_worker) return;

  try {
    // Use import.meta.url so Vite can resolve the worker URL correctly.
    // type:'module' is required for ESM imports inside the worker.
    _worker = new Worker(new URL('./edge-worker.js', import.meta.url), { type: 'module' });

    _worker.addEventListener('message', ({ data }) => {
      // Lifecycle events have no id
      if (data?.type === 'ready') {
        _ready = true;
        if (_readyCb) { _readyCb(); _readyCb = null; }
        return;
      }
      if (data?.type === 'error') {
        console.warn('[edge-worker] worker boot error:', data.message);
        // Resolve all pending with fallback values
        for (const [, { resolve }] of _pending) resolve(_fallback(null));
        _pending.clear();
        return;
      }

      // Regular response: { id, result }
      const { id, result } = data ?? {};
      const entry = _pending.get(id);
      if (entry) {
        _pending.delete(id);
        entry.resolve(result);
      }
    });

    _worker.addEventListener('error', (err) => {
      console.warn('[edge-worker] worker error:', err.message);
    });

  } catch (err) {
    console.warn('[edge-worker] Web Workers unavailable — using fallback routing:', err.message);
    _worker = null;
  }
}

function _fallback(type) {
  if (type === 'sentiment') return { label: 'NEUTRAL', score: 0.5 };
  // classify fallback: moderate keeps the UI functional (shows estimate, routes to server)
  return { complexity: 'moderate', score: 0, reason: 'worker-unavailable' };
}

function _send(type, text) {
  if (!_worker) return Promise.resolve(_fallback(type));

  const id = _nextId++;
  return new Promise((resolve) => {
    _pending.set(id, { resolve, reject: resolve });
    _worker.postMessage({ id, type, text });
  });
}

// ── Public API ────────────────────────────────────────────────────────────────

export function classify(text) {
  _init();
  return _send('classify', text);
}

export function sentiment(text) {
  _init();
  return _send('sentiment', text);
}

export function onReady(fn) {
  if (_ready) { fn(); return; }
  _readyCb = fn;
}

export function isReady() { return _ready; }

/**
 * warmup() — start the worker (and model loading) early so classify/sentiment
 * calls on first user interaction don't stall waiting for models.
 */
export function warmup() { _init(); }
