// talon-db.jsx — HTTP API client. Manages auth, regions, and POI overrides.
const REGION_FALLBACK = [
  { id: "talon-mainland", name: "Talon Mainland", treatment: "painted", image: "assets/talon-mainland.png", size: { width: 3840, height: 2160 }, initialView: { x: 0.50, y: 0.46, zoom: 0.92 }, minZoom: 0.55, maxZoom: 2.6 },
  { id: "vorthrocs-reach", name: "Vorthrocs Reach", treatment: "painted", image: "assets/vorthrocs-reach.png", size: { width: 2800, height: 1800 }, initialView: { x: 0.5, y: 0.5, zoom: 1 }, minZoom: 0.6, maxZoom: 2.4 },
  { id: "ashen-wastes", name: "The Ashen Wastes", treatment: "placeholder", image: null, size: { width: 3200, height: 1700 }, initialView: { x: 0.5, y: 0.5, zoom: 1 }, minZoom: 0.6, maxZoom: 2.4 },
];

const TalonDB = {
  isServer: true,
  mode: 'loading',
  _cache: null,
  _regions: null,
  _saveTimer: 0,
  _token: null,
  authRequired: false,
  _LS_KEY: 'talon-admin-v1',

  async init() {
    try {
      const [statusRes, regionsRes, overridesRes] = await Promise.all([
        fetch('/api/auth/status'),
        fetch('/api/regions'),
        fetch('/api/overrides'),
      ]);
      if (!statusRes.ok || !regionsRes.ok || !overridesRes.ok) throw new Error('HTTP error');
      const status = await statusRes.json();
      this.authRequired = !!status.required;
      this._regions = await regionsRes.json();
      this._cache = await overridesRes.json();
      this.mode = 'sqlite';
    } catch (e) {
      console.warn('[TalonDB] API unavailable, falling back to localStorage:', e.message);
      this.mode = 'fallback';
      this.authRequired = false;
      this._regions = REGION_FALLBACK;
      try {
        const raw = localStorage.getItem(this._LS_KEY);
        this._cache = raw ? JSON.parse(raw) : { regions: {} };
      } catch (_) {
        this._cache = { regions: {} };
      }
    }
    return { mode: this.mode };
  },

  setToken(t) {
    this._token = t;
  },

  isAuthRequired() {
    return this.authRequired;
  },

  readRegions() {
    return this._regions || REGION_FALLBACK;
  },

  readOverrides() {
    return this._cache || { regions: {} };
  },

  write(overrides) {
    this._cache = overrides;
    if (this.mode === 'fallback') {
      try { localStorage.setItem(this._LS_KEY, JSON.stringify(overrides)); } catch (_) {}
      return;
    }
    clearTimeout(this._saveTimer);
    this._saveTimer = setTimeout(() => this._persist(), 300);
  },

  async _persist() {
    try {
      const headers = { 'Content-Type': 'application/json' };
      if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
      const res = await fetch('/api/overrides', {
        method: 'POST',
        headers,
        body: JSON.stringify(this._cache),
      });
      if (!res.ok) throw new Error('HTTP ' + res.status);
    } catch (e) {
      console.warn('[TalonDB] auto-save failed:', e.message);
    }
  },

  async createRegion(data) {
    const headers = { 'Content-Type': 'application/json' };
    if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
    const res = await fetch('/api/regions', { method: 'POST', headers, body: JSON.stringify(data) });
    if (!res.ok) {
      const body = await res.json().catch(() => ({ error: 'Create failed' }));
      throw new Error(body.error || 'Create failed');
    }
    const created = await res.json();
    this._regions = [...(this._regions || []), created];
    return created;
  },

  async updateRegion(id, patch) {
    const headers = { 'Content-Type': 'application/json' };
    if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
    const res = await fetch(`/api/regions/${id}`, { method: 'PUT', headers, body: JSON.stringify(patch) });
    if (!res.ok) throw new Error('HTTP ' + res.status);
    const updated = await res.json();
    this._regions = (this._regions || []).map(r => r.id === id ? updated : r);
    return updated;
  },

  async deleteRegion(id) {
    const headers = {};
    if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
    const res = await fetch(`/api/regions/${id}`, { method: 'DELETE', headers });
    if (!res.ok) throw new Error('HTTP ' + res.status);
    this._regions = (this._regions || []).filter(r => r.id !== id);
  },

  async uploadRegionImage(id, file) {
    const headers = { 'Content-Type': file.type || 'image/png' };
    if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
    const bytes = await file.arrayBuffer();
    const res = await fetch(`/api/regions/${id}/image`, { method: 'POST', headers, body: bytes });
    if (!res.ok) throw new Error('HTTP ' + res.status);
    return await res.json();
  },

  exportSqlite() { return null; },

  async importSqlite(bytes) {
    const headers = { 'Content-Type': 'application/octet-stream' };
    if (this._token) headers['Authorization'] = `Bearer ${this._token}`;
    const res = await fetch('/api/import/sqlite', { method: 'POST', headers, body: bytes });
    if (!res.ok) {
      const body = await res.json().catch(() => ({ error: 'Import failed' }));
      throw new Error(body.error || 'Import failed');
    }
    this._cache = await res.json();
    return this._cache;
  },

  rowCount() {
    if (!this._cache) return 0;
    return Object.values(this._cache.regions || {}).reduce(
      (n, r) => n + Object.keys(r.edits || {}).length, 0
    );
  },
};

window.TalonDB = TalonDB;
