/* ===== api.jsx — REST client to Hono Worker =====
 * Reads API base URL from window.__API__ (set in index.html) or falls back to
 * same-origin /api. Session ID stored in localStorage, sent as X-Session-Id.
 *
 * Usage:
 *   await api.suppliers.list()
 *   await api.suppliers.create({ name: 'Foo' })
 *   await api.reagentOutflows.create({ batchId, customerId, ... })
 *   const u = await api.auth.me()
 */
(function () {
  const SID_KEY = 'erp.sid';
  // Default API base for production. Override with window.__API__ for local dev.
  const DEFAULT_API =
    typeof window !== 'undefined' &&
    /^(localhost|127\.0\.0\.1|0\.0\.0\.0)$/.test(window.location.hostname)
      ? 'http://localhost:8787/api'
      : 'https://api.erp.gopromp.com/api';
  const BASE = (window.__API__ || DEFAULT_API).replace(/\/$/, '');

  function getSid() { return localStorage.getItem(SID_KEY) || ''; }
  function setSid(sid) { sid ? localStorage.setItem(SID_KEY, sid) : localStorage.removeItem(SID_KEY); }

  async function req(method, path, body, opts = {}) {
    const headers = { 'Content-Type': 'application/json' };
    const sid = getSid();
    if (sid) headers['X-Session-Id'] = sid;
    if (opts.headers) Object.assign(headers, opts.headers);
    const res = await fetch(`${BASE}${path}`, {
      method,
      headers,
      body: body == null ? undefined : (typeof body === 'string' ? body : JSON.stringify(body)),
      credentials: 'include',
    });
    let data = null;
    const ct = res.headers.get('content-type') || '';
    if (ct.includes('application/json')) {
      try { data = await res.json(); } catch { /* empty */ }
    } else {
      data = await res.text();
    }
    if (!res.ok) {
      const msg = (data && data.error) || `${res.status} ${res.statusText}`;
      const err = new Error(msg);
      err.status = res.status;
      err.data = data;
      throw err;
    }
    return data;
  }

  const get   = (p) => req('GET', p);
  const post  = (p, b) => req('POST', p, b);
  const patch = (p, b) => req('PATCH', p, b);
  const del   = (p) => req('DELETE', p);

  function crud(base, searchableQuery = true) {
    return {
      list: (q) => {
        const qs = searchableQuery && q ? `?q=${encodeURIComponent(q)}` : '';
        return get(`${base}${qs}`);
      },
      get: (id) => get(`${base}/${id}`),
      create: (data) => post(base, data),
      update: (id, data) => patch(`${base}/${id}`, data),
      archive: (id) => patch(`${base}/${id}/archive`),
      restore: (id) => patch(`${base}/${id}/restore`),
    };
  }

  const api = {
    base: BASE,
    health: () => get('/health'),

    auth: {
      login: async (email, password) => {
        const r = await post('/auth/login', { email, password });
        if (r?.sid) setSid(r.sid);
        return r;
      },
      logout: async () => {
        const r = await post('/auth/logout');
        setSid('');
        return r;
      },
      me: () => get('/auth/me'),
      register: (data) => post('/auth/register', data),
    },

    suppliers: crud('/suppliers'),
    customers: crud('/customers'),

    reagentProducts: crud('/reagent-products'),
    reagentBatches: {
      list: (opts = {}) => get(`/reagent-batches${opts.archived ? '?archived=1' : ''}`),
      get: (id) => get(`/reagent-batches/${id}`),
      create: (data) => post('/reagent-batches', data),
    },
    reagentOutflows: {
      create: (data) => post('/reagent-outflows', data),
    },
    reagentReturns: {
      create: (data) => post('/reagent-returns', data),
    },

    deviceProducts: crud('/device-products'),
    deviceUnits: {
      list: (opts = {}) => get(`/device-units${opts.archived ? '?archived=1' : ''}`),
      get: (id) => get(`/device-units/${id}`),
      create: (data) => post('/device-units', data),
      update: (id, data) => patch(`/device-units/${id}`, data),
    },
    deviceTransfers: {
      create: (data) => post('/device-transfers', data),
    },

    activity: (limit = 20) => get(`/activity?limit=${limit}`),
    search: (q) => get(`/search?q=${encodeURIComponent(q)}`),

    attachments: {
      list: (entityType, entityId) =>
        get(`/attachments/list?entity_type=${entityType}&entity_id=${entityId}`),
      upload: async (entityType, entityId, file) => {
        const sid = getSid();
        const url =
          `${BASE}/attachments?entity_type=${entityType}` +
          `&entity_id=${entityId}` +
          `&filename=${encodeURIComponent(file.name)}`;
        const res = await fetch(url, {
          method: 'POST',
          headers: sid ? { 'X-Session-Id': sid } : {},
          body: file,
        });
        if (!res.ok) throw new Error(await res.text());
        return res.json();
      },
      downloadUrl: (r2Key) => `${BASE}/attachments/get/${r2Key}`,
    },
  };

  Object.assign(window, { api, getSid, setSid });
})();
