// aerOS — shared API client (all surfaces).
// Loaded before any data.jsx. Exposes window.aerosApi: a thin fetch wrapper that
// attaches the bearer token (admin/superadmin) and X-Tenant slug (guest/tenant)
// to every call, matching the django-ninja backend's auth + multi-tenancy.
(function () {
  // API base: override via <meta name="aeros-api-base"> or localStorage; else
  // prod = same origin (Caddy proxies /api/*), dev = backend on :8000.
  function resolveBase() {
    const meta = document.querySelector('meta[name="aeros-api-base"]');
    if (meta && meta.content) return meta.content.replace(/\/$/, '');
    const ls = localStorage.getItem('aeros-api-base');
    if (ls) return ls.replace(/\/$/, '');
    // Production: the SPA and API share an origin, so a relative base sends calls
    // to https://<host>/api/... Dev (http localhost): backend runs on :8000.
    const host = location.hostname;
    const isLocal = host === 'localhost' || host.endsWith('.localhost') || host === '127.0.0.1';
    if (location.protocol === 'https:' || !isLocal) return '';
    return location.protocol + '//' + host + ':8000';
  }
  const BASE = resolveBase();

  // Per-surface token so the superadmin / tenant-admin / guest sessions don't
  // clobber each other's auth in the same browser (shared localStorage).
  function surface() {
    if (window.AEROS_SURFACE) return window.AEROS_SURFACE;
    const p = decodeURIComponent(location.pathname).toLowerCase();
    if (p.includes('admin.html') || p.includes('tenant')) return 'ta';   // tenant panel
    if (p.includes('superadmin') || p.includes('/admin')) return 'sa';   // platform console
    if (p.includes('guest')) return 'guest';
    return 'app';
  }
  const SURFACE = surface();
  const tokenKey = 'aeros-token-' + SURFACE;
  // Surface-scoped so a tenant-admin login (which calls setTenant(org_slug)) on
  // the same browser/origin cannot clobber the guest's tenant — they shared one
  // 'aeros-tenant' key before, so logging into Radisson admin made the guest menu
  // resolve to Radisson too.
  const tenantKey = 'aeros-tenant-' + SURFACE;

  // SSO handoff: the central login (app.html) redirects to the tenant subdomain
  // with #t=<token>. Capture it into this origin's storage, then clean the URL.
  (function () {
    const m = /[#&]t=([^&]+)/.exec(location.hash || '');
    if (m) {
      try { localStorage.setItem(tokenKey, decodeURIComponent(m[1])); } catch (e) {}
      try { history.replaceState(null, '', location.pathname + location.search); } catch (e) {}
    }
  })();

  // Persist guest context (tenant + room/table/mode/outlet) from the QR/deep-link
  // query so it survives a PWA relaunch — the manifest start_url drops the query
  // string — and overrides any stale value left by a previous tenant on this
  // device. Runs only when the query actually carries a value.
  (function () {
    try {
      const q = new URLSearchParams(location.search);
      const t = q.get('tenant');
      if (t) localStorage.setItem(tenantKey, t);
      ['room', 'table', 'mode', 'outlet'].forEach(function (k) {
        const v = q.get(k);
        if (v) localStorage.setItem('aeros-guest-' + k, v);
      });
    } catch (e) {}
  })();

  function getToken() { return localStorage.getItem(tokenKey) || ''; }
  function setToken(t) { t ? localStorage.setItem(tokenKey, t) : localStorage.removeItem(tokenKey); }
  // Tenant resolution order: ?tenant= (explicit/dev) -> stored -> subdomain.
  // Prod: <tenant>.qrmenu.boranyazilim.com -> the first label is the tenant.
  function _subdomainTenant() {
    const parts = (location.hostname || '').toLowerCase().split('.');
    const reserved = ['www', 'app', 'admin', 'qrmenu', 'localhost', 'staging', '127', '0', 'aeros'];
    if (reserved.indexOf(parts[0]) !== -1) return '';
    // <tenant>.localhost  (local dev — Chromium resolves *.localhost to 127.0.0.1)
    if (parts.length === 2 && parts[1] === 'localhost') return parts[0];
    // <tenant>.qrmenu.boranyazilim.com  (prod, wildcard subdomain)
    if (parts.length >= 3) return parts[0];
    return '';
  }
  function getTenant() {
    return new URLSearchParams(location.search).get('tenant') ||
      localStorage.getItem(tenantKey) || _subdomainTenant() || '';
  }
  function setTenant(s) { s ? localStorage.setItem(tenantKey, s) : localStorage.removeItem(tenantKey); }

  async function request(path, { method = 'POST', body, auth = true } = {}) {
    const headers = {};
    if (body !== undefined) headers['Content-Type'] = 'application/json';
    if (auth && getToken()) headers['Authorization'] = 'Bearer ' + getToken();
    const ten = getTenant();
    if (ten) headers['X-Tenant'] = ten;

    let res;
    try {
      res = await fetch(BASE + '/api' + path, {
        method, headers,
        body: body !== undefined ? JSON.stringify(body) : undefined,
      });
    } catch (e) {
      const err = new Error('network'); err.network = true; throw err;
    }

    let data = null;
    try { data = await res.json(); } catch (e) { /* empty body */ }

    if (!res.ok) {
      const err = new Error((data && (data.msg_txt || data.detail)) || ('HTTP ' + res.status));
      err.status = res.status; err.data = data; throw err;
    }
    return data;
  }

  window.aerosApi = {
    BASE,
    get: (p, o = {}) => request(p, { ...o, method: 'GET' }),
    post: (p, b, o = {}) => request(p, { ...o, method: 'POST', body: b }),
    getToken, setToken, getTenant, setTenant,
    // unwrap the backend's {success, data} envelope
    data: (resp) => (resp && resp.data !== undefined ? resp.data : resp),
  };

  // Image intake: downscale + recompress in-browser before sending base64.
  // Phone photos are 2-8MB; raw base64 of those blows past reverse-proxy body
  // limits (Caddy/nginx) and bloats the DB TextField. We cap the longest edge
  // and emit JPEG so a typical upload lands well under ~300KB.
  // format: 'jpeg' (default, opaque, smallest) or 'png' (keeps transparency — use for logos).
  function fileToResizedDataURL(file, { maxEdge = 1280, quality = 0.82, format = 'jpeg' } = {}) {
    return new Promise((resolve, reject) => {
      if (!file) { resolve(null); return; }
      const reader = new FileReader();
      reader.onerror = () => reject(new Error('read_failed'));
      reader.onload = () => {
        const img = new Image();
        img.onerror = () => resolve(reader.result);   // not a decodable image — fall back to raw
        img.onload = () => {
          const w = img.width, h = img.height;
          const scale = Math.min(1, maxEdge / Math.max(w, h));
          // SVG/GIF or already-small: keep original (canvas would rasterize/animate-flatten).
          if (scale >= 1 && /image\/(svg|gif)/.test(file.type || '')) { resolve(reader.result); return; }
          const cw = Math.round(w * scale), ch = Math.round(h * scale);
          const canvas = document.createElement('canvas');
          canvas.width = cw; canvas.height = ch;
          const ctx = canvas.getContext('2d');
          const png = format === 'png';
          if (!png) { ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, cw, ch); }   // matte for opaque JPEG
          ctx.drawImage(img, 0, 0, cw, ch);
          try { resolve(png ? canvas.toDataURL('image/png') : canvas.toDataURL('image/jpeg', quality)); }
          catch (e) { resolve(reader.result); }
        };
        img.src = reader.result;
      };
      reader.readAsDataURL(file);
    });
  }
  window.aerosImage = { fromFile: fileToResizedDataURL };
})();
