// ============================================================
// DATA LAYER — Real backend (PHP)
// Mantém EXATAMENTE a mesma interface api.* do protótipo,
// porém agora cada método é uma chamada fetch() para /api/.
// ============================================================

// Caminho da API relativo à pasta do blog. Funciona em qualquer
// domínio (drangelo.com.br/blog/ → drangelo.com.br/blog/api/).
const API_BASE = 'api';

// ---------- HTTP helper ----------
async function http(path, opts = {}) {
  const url = `${API_BASE}/${path}`;
  const res = await fetch(url, {
    credentials: 'same-origin',
    headers: { 'Accept': 'application/json' },
    ...opts,
  });
  const text = await res.text();
  let payload = null;
  try { payload = text ? JSON.parse(text) : null; } catch (e) { payload = { error: text }; }
  if (!res.ok) {
    const msg = (payload && (payload.error || payload.message)) || `Erro HTTP ${res.status}`;
    throw new Error(msg);
  }
  return payload;
}

function httpJSON(path, method, body) {
  return http(path, {
    method,
    headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
    body: JSON.stringify(body || {}),
  });
}

// ---------- Slug & utils (clientside) ----------
function slugify(s) {
  return (s || '')
    .toLowerCase()
    .normalize('NFD').replace(/[̀-ͯ]/g, '')
    .replace(/[^a-z0-9\s-]/g, '')
    .trim().replace(/\s+/g, '-').slice(0, 80);
}
function uid() { return 'a' + Math.random().toString(36).slice(2, 10); }

// ---------- Cache de categorias (evita chamadas repetidas) ----------
let _catCache = null;
async function ensureCategories() {
  if (_catCache) return _catCache;
  _catCache = await http('categories.php');
  return _catCache;
}
function invalidateCats() { _catCache = null; }

// ---------- Public API (mesma assinatura do protótipo) ----------
const api = {
  async listArticles({ status, category, q } = {}) {
    const params = new URLSearchParams();
    if (status)   params.set('status', status);
    if (category) params.set('category', category);
    if (q)        params.set('q', q);
    const qs = params.toString();
    return http('articles.php' + (qs ? '?' + qs : ''));
  },

  async getArticle(slugOrId) {
    try {
      return await http('articles.php?id=' + encodeURIComponent(slugOrId));
    } catch (e) {
      // 404 → retorna null (compatível com a expectativa do article.jsx)
      return null;
    }
  },

  async upsertArticle(payload) {
    return httpJSON('articles.php', 'POST', payload);
  },

  async deleteArticle(id) {
    await http('articles.php?id=' + encodeURIComponent(id), { method: 'DELETE' });
    return true;
  },

  async listCategories() {
    const cats = await ensureCategories();
    _catSyncCache = cats;
    return cats;
  },

  async saveCategories(cats) {
    const saved = await httpJSON('categories.php', 'POST', { categories: cats });
    _catCache = saved;
    _catSyncCache = saved;
    return saved;
  },

  async subscribe(email) {
    await httpJSON('subscribe.php', 'POST', { email });
    return true;
  },

  // -------- Upload de imagem (capa ou corpo do artigo) --------
  async uploadImage(file) {
    const fd = new FormData();
    fd.append('file', file);
    const res = await fetch(`${API_BASE}/upload.php`, {
      method: 'POST',
      credentials: 'same-origin',
      body: fd,
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.error || 'Falha no upload da imagem.');
    return data.url;
  },

  // -------- Auth (senha única) --------
  async login(password) {
    const session = await httpJSON('auth.php?action=login', 'POST', { password });
    try { localStorage.setItem('angelo_session_hint', JSON.stringify(session)); } catch (e) {}
    return session;
  },

  getSession() {
    // Hint local só para a UI renderizar sem flicker. A validação real
    // é o cookie de sessão do PHP (verificado em toda chamada protegida).
    try {
      const s = JSON.parse(localStorage.getItem('angelo_session_hint') || 'null');
      if (s && s.exp > Date.now()) return s;
    } catch (e) {}
    return null;
  },

  async logout() {
    try { await httpJSON('auth.php?action=logout', 'POST', {}); } catch (e) {}
    localStorage.removeItem('angelo_session_hint');
  },

  // -------- Export / Import (backup completo em JSON) --------
  async exportData() {
    const data = await http('export.php');
    return JSON.stringify(data, null, 2);
  },

  async importData(json, { merge = true } = {}) {
    const incoming = typeof json === 'string' ? JSON.parse(json) : json;
    await httpJSON('import.php' + (merge ? '?merge=1' : ''), 'POST', incoming);
    invalidateCats();
    return true;
  },

  // utility
  slugify,
  uid,
};

// ---------- Formatting helpers (idem ao protótipo) ----------
function readingTime(html) {
  const text = (html || '').replace(/<[^>]+>/g, ' ');
  const words = text.split(/\s+/).filter(Boolean).length;
  return Math.max(1, Math.round(words / 220));
}

function fmtDate(iso, opts = {}) {
  if (!iso) return '—';
  const d = new Date(iso);
  const months = ['jan.', 'fev.', 'mar.', 'abr.', 'mai.', 'jun.', 'jul.', 'ago.', 'set.', 'out.', 'nov.', 'dez.'];
  const monthsFull = ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'];
  if (opts.long) return `${d.getDate()} de ${monthsFull[d.getMonth()]} de ${d.getFullYear()}`;
  return `${d.getDate().toString().padStart(2,'0')} ${months[d.getMonth()]} ${d.getFullYear()}`;
}

function fmtDateLong(iso) {
  if (!iso) return '—';
  const d = new Date(iso);
  const dias = ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'];
  return `${dias[d.getDay()]}, ${fmtDate(iso, { long: true })}`;
}

// Cache síncrono de categorias para categoryName/categoryById
// (mantém compatibilidade com home.jsx/article.jsx/ui.jsx que chamam essas
// funções de forma síncrona dentro do render do React).
let _catSyncCache = [];
ensureCategories().then(c => { _catSyncCache = c; }).catch(() => {});

function categoryName(id) {
  const c = _catSyncCache.find(c => c.id === id);
  return c ? c.name : id;
}
function categoryById(id) {
  return _catSyncCache.find(c => c.id === id);
}

// Export para window (mantém compatibilidade com o restante do prototype)
Object.assign(window, { api, readingTime, fmtDate, fmtDateLong, categoryName, categoryById, slugify });
