/* ============================================================
   MyKollectOr® — api.js — Wrapper fetch + JWT
   fab.mykollector.com
   ============================================================ */

const API_BASE = 'https://api.mykollector.com';

const Api = (() => {
  // ── Token management ──────────────────────────────────────
  const getToken  = () => localStorage.getItem('mko_token');
  const setToken  = (t) => localStorage.setItem('mko_token', t);
  const getRefresh= () => localStorage.getItem('mko_refresh_token');
  const setRefresh= (t) => localStorage.setItem('mko_refresh_token', t);

  const clearAuth = () => {
    localStorage.removeItem('mko_token');
    localStorage.removeItem('mko_refresh_token');
    localStorage.removeItem('mko_user');
  };

  const redirectLogin = () => {
    const isAdmin = window.location.pathname.startsWith('/admin/');
    clearAuth();
    window.location.href = isAdmin ? '/admin/index.html' : '/index.html';
  };

  // ── Internal fetch with JWT ───────────────────────────────
  const _fetch = async (url, options = {}, retry = true) => {
    const token = getToken();
    const headers = {
      'Content-Type': 'application/json',
      ...(token ? { 'Authorization': `Bearer ${token}` } : {}),
      ...(options.headers || {})
    };

    // Remove Content-Type for FormData
    if (options.body instanceof FormData) {
      delete headers['Content-Type'];
    }

    const res = await fetch(url, { ...options, headers });

    // 401 → try refresh
    if (res.status === 401 && retry) {
      const refreshed = await _doRefresh();
      if (refreshed) {
        return _fetch(url, options, false);
      } else {
        redirectLogin();
        throw new Error('Session expirée');
      }
    }

    return res;
  };

  const _doRefresh = async () => {
    const refreshToken = getRefresh();
    if (!refreshToken) return false;
    try {
      const res = await fetch(`${API_BASE}/api/auth/refresh`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ refresh_token: refreshToken })
      });
      if (!res.ok) return false;
      const resp = await res.json();
      const payload = (resp && resp.data) ? resp.data : resp;
      if (payload && payload.token) {
        setToken(payload.token);
        if (payload.refresh_token) setRefresh(payload.refresh_token);
        return true;
      }
      return false;
    } catch { return false; }
  };

  // ── Public methods ────────────────────────────────────────
  const request = async (method, path, body = null, options = {}) => {
    const url = `${API_BASE}${path}`;
    const opts = {
      method,
      ...options,
      ...(body !== null ? {
        body: body instanceof FormData ? body : JSON.stringify(body)
      } : {})
    };
    const res = await _fetch(url, opts);
    if (!res.ok) {
      let errMsg = `Erreur ${res.status}`;
      try {
        const errData = await res.json();
        errMsg = errData.message || errData.error || errMsg;
      } catch {}
      throw new Error(errMsg);
    }
    // Handle empty responses — déwrappe automatiquement { error: false, data: {...} }
    const ct = res.headers.get('Content-Type') || '';
    if (ct.includes('application/json')) {
      const json = await res.json();
      // Si l'API retourne { error: false, data: ... } → retourner data directement
      // Si retour direct (tableau, objet plat) → retourner tel quel
      if (json && typeof json === 'object' && 'error' in json && 'data' in json) {
        return json.data;
      }
      return json;
    }
    return res;
  };

  const get    = (path, opts)       => request('GET',    path, null, opts);
  const post   = (path, body, opts) => request('POST',   path, body, opts);
  const patch  = (path, body, opts) => request('PATCH',  path, body, opts);
  const put    = (path, body, opts) => request('PUT',    path, body, opts);
  const del    = (path, opts)       => request('DELETE', path, null, opts);

  const download = async (path, filename) => {
    const res = await _fetch(`${API_BASE}${path}`, { method: 'GET' });
    if (!res.ok) throw new Error('Téléchargement impossible');
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = filename;
    a.click();
    URL.revokeObjectURL(url);
  };

  return { get, post, patch, put, del, download, getToken, setToken, setRefresh, clearAuth, redirectLogin };
})();

// ── Toast notifications ───────────────────────────────────────
const Toast = (() => {
  let container;

  const init = () => {
    container = document.getElementById('toast-container');
    if (!container) {
      container = document.createElement('div');
      container.id = 'toast-container';
      container.className = 'toast-container';
      document.body.appendChild(container);
    }
  };

  const show = (msg, type = 'info', duration = 3500) => {
    if (!container) init();
    const icons = { success: '', error: '', warning: '', info: 'ℹ' };
    const t = document.createElement('div');
    t.className = `toast ${type}`;
    t.innerHTML = `<span>${icons[type] || ''}</span><span>${msg}</span>`;
    container.appendChild(t);
    setTimeout(() => {
      t.classList.add('fade-out');
      setTimeout(() => t.remove(), 300);
    }, duration);
  };

  return {
    success: (m, d) => show(m, 'success', d),
    error:   (m, d) => show(m, 'error',   d || 5000),
    warning: (m, d) => show(m, 'warning', d),
    info:    (m, d) => show(m, 'info',    d),
  };
})();

// ── Spinner ───────────────────────────────────────────────────
const Spinner = (() => {
  let overlay;
  let count = 0;

  const show = () => {
    count++;
    if (!overlay) {
      overlay = document.createElement('div');
      overlay.className = 'loading-overlay';
      overlay.innerHTML = '<div class="spinner spinner-dark" style="width:36px;height:36px;border-width:3px;"></div>';
      document.body.appendChild(overlay);
    }
    overlay.style.display = 'flex';
  };

  const hide = () => {
    count = Math.max(0, count - 1);
    if (count === 0 && overlay) overlay.style.display = 'none';
  };

  return { show, hide };
})();

// ── Modal confirm ─────────────────────────────────────────────
const Confirm = (title, body) => {
  return new Promise((resolve) => {
    const backdrop = document.createElement('div');
    backdrop.className = 'modal-backdrop';
    backdrop.innerHTML = `
      <div class="modal">
        <div class="modal-title">${title}</div>
        <div class="modal-body">${body}</div>
        <div class="modal-actions">
          <button class="btn btn-ghost btn-cancel">Annuler</button>
          <button class="btn btn-primary btn-confirm">Confirmer</button>
        </div>
      </div>`;
    document.body.appendChild(backdrop);
    backdrop.querySelector('.btn-cancel').onclick  = () => { backdrop.remove(); resolve(false); };
    backdrop.querySelector('.btn-confirm').onclick = () => { backdrop.remove(); resolve(true); };
  });
};
