// Cliente do backend real. Todas as chamadas passam por /api/*.
// A sessão é mantida via cookie httpOnly — o browser cuida disso sozinho.

async function apiFetch(path, { method = 'GET', body, signal } = {}) {
  const res = await fetch(path, {
    method,
    credentials: 'include',
    headers: body ? { 'Content-Type': 'application/json' } : {},
    body: body ? JSON.stringify(body) : undefined,
    signal,
  });
  const text = await res.text();
  let json = null;
  try { json = text ? JSON.parse(text) : null; } catch { /* resposta não-JSON */ }
  if (!res.ok) {
    const msg = json?.error || `HTTP ${res.status}`;
    throw new Error(msg);
  }
  return json;
}

window.DB = {
  _listeners: new Set(),
  _setUser(user) {
    window.USER = user;
    for (const fn of this._listeners) { try { fn(user); } catch {} }
  },
  onUserChange(fn) {
    this._listeners.add(fn);
    return () => this._listeners.delete(fn);
  },

  async loadSession() {
    try {
      const { user } = await apiFetch('/api/auth/me');
      this._setUser(user || null);
      return user;
    } catch (e) {
      this._setUser(null);
      return null;
    }
  },

  async signup({ name, email, pass, listings, plan }) {
    const { user } = await apiFetch('/api/auth/signup', {
      method: 'POST', body: { name, email, pass, listings, plan },
    });
    this._setUser(user);
    return user;
  },

  async login(email, pass) {
    const { user } = await apiFetch('/api/auth/login', { method: 'POST', body: { email, pass } });
    this._setUser(user);
    return user;
  },

  googleLogin() {
    // Full page redirect para o servidor iniciar o fluxo OAuth.
    window.location.href = '/auth/google';
  },

  async logout() {
    try { await apiFetch('/api/auth/logout', { method: 'POST' }); } catch {}
    this._setUser(null);
  },

  async updateUser(updates) {
    const { user } = await apiFetch('/api/auth/update', { method: 'POST', body: updates });
    this._setUser(user);
    return user;
  },

  async forgotPassword(email) {
    return apiFetch('/api/auth/forgot', { method: 'POST', body: { email } });
  },

  async resetPassword(token, pass) {
    const { user } = await apiFetch('/api/auth/reset', { method: 'POST', body: { token, pass } });
    this._setUser(user);
    return user;
  },

  // Tokeniza cartão diretamente na API Pagar.me (PCI-DSS compliant).
  // O número do cartão NUNCA passa pelo nosso servidor.
  async tokenizeCard({ number, holderName, expMonth, expYear, cvv }) {
    const publicKey = window.__PAGARME_PK;
    if (!publicKey) throw new Error('Chave pública Pagar.me não configurada.');
    const url = `https://api.pagar.me/core/v5/tokens?appId=${publicKey}`;
    const res = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        type: 'card',
        card: {
          number: String(number).replace(/\D/g, ''),
          holder_name: holderName,
          exp_month: expMonth,
          exp_year: expYear,
          cvv: cvv,
        },
      }),
    });
    const data = await res.json();
    if (!res.ok || !data.id) {
      throw new Error(data.message || data.errors?.[0]?.message || 'Erro ao tokenizar cartão.');
    }
    return data.id; // tok_xxxxx
  },

  async createOrder(payload) {
    return apiFetch('/api/checkout/order', { method: 'POST', body: payload });
  },

  async pollOrder(orderId) {
    return apiFetch('/api/checkout/order/' + encodeURIComponent(orderId));
  },

  async getReceiptCode(orderId) {
    return apiFetch('/api/checkout/my-receipt/' + encodeURIComponent(orderId));
  },

  async listPurchases() {
    const { items } = await apiFetch('/api/auth/purchases');
    return items || [];
  },

  async changePassword(currentPass, newPass) {
    return apiFetch('/api/auth/change-password', { method: 'POST', body: { currentPass, newPass } });
  },

  async consumeCredit() {
    const { user } = await apiFetch('/api/checkout/consume-credit', { method: 'POST' });
    this._setUser(user);
    return user;
  },

  async editWithGemini({ prompt, mime, base64, presetName, parentGenerationId, purchaseId }) {
    const data = await apiFetch('/api/gemini/edit', {
      method: 'POST',
      body: { prompt, mime, base64, presetName, parentGenerationId: parentGenerationId || null, purchaseId: purchaseId || null },
    });
    // data = { dataUrl, galId }
    return data;
  },

  async fetchGallery() {
    const { items } = await apiFetch('/api/auth/gallery');
    return items || [];
  },

  creditsAvailable() {
    const u = window.USER;
    if (!u) return 0;
    return Math.max(0, (u.creditsTotal || 0) - (u.creditsUsed || 0));
  },

  async adminLogin(username, password) {
    await apiFetch('/api/admin/login', { method: 'POST', body: { username, password } });
    window.__isAdmin = true;
  },

  async adminLogout() {
    try { await apiFetch('/api/admin/logout', { method: 'POST' }); } catch {}
    window.__isAdmin = false;
  },

  async checkAdmin() {
    try {
      const { isAdmin } = await apiFetch('/api/admin/check');
      window.__isAdmin = !!isAdmin;
      return isAdmin;
    } catch { window.__isAdmin = false; return false; }
  },
};

// boot: carrega sessão e config pública antes do React montar.
window.__sessionReady = Promise.all([
  window.DB.loadSession().then(() => window.DB.checkAdmin()),
  apiFetch('/api/config').then(cfg => {
    window.__PAGARME_PK = cfg?.pagarmePk || '';
  }).catch(() => {}),
]);
