/* ══════════════════════════════════════════════════════════════════════════
   MyKollectOr® — js/api.js   v1.3
   Wrapper fetch + JWT + refresh + unwrap { error, data }
   ══════════════════════════════════════════════════════════════════════════ */
(function (global) {
  'use strict';

  var API_BASE    = 'https://api.mykollector.com';
  var TOKEN_KEY   = 'mko_token';
  var REFRESH_KEY = 'mko_refresh_token';

  function getToken()        { try { return localStorage.getItem(TOKEN_KEY)   || null; } catch(e){ return null; } }
  function getRefreshToken() { try { return localStorage.getItem(REFRESH_KEY) || null; } catch(e){ return null; } }
  function setTokens(t, r)   { try { if(t) localStorage.setItem(TOKEN_KEY, t); if(r) localStorage.setItem(REFRESH_KEY, r); } catch(e){} }
  function clearTokens()     { try { localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(REFRESH_KEY); } catch(e){} }

  /* Désenveloppe { error:false, data:{...} } — standard MKO API */
  function unwrap(raw) {
    if (raw && typeof raw === 'object' && 'error' in raw && 'data' in raw) {
      if (raw.error) {
        var e = new Error(raw.message || raw.code || 'api_error');
        e.code = raw.code; e.body = raw; throw e;
      }
      return raw.data;
    }
    return raw;
  }

  var refreshPromise = null;
  function refreshAccessToken() {
    if (refreshPromise) return refreshPromise;
    var rt = getRefreshToken();
    if (!rt) return Promise.reject(new Error('no_refresh_token'));
    refreshPromise = fetch(API_BASE + '/api/auth/refresh', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: rt })
    }).then(function(res) {
      if (!res.ok) throw new Error('refresh_failed');
      return res.json();
    }).then(function(raw) {
      var data = unwrap(raw);
      if (!data || !data.token) throw new Error('refresh_invalid');
      setTokens(data.token, data.refresh_token || rt);
      refreshPromise = null;
      return data.token;
    }).catch(function(err) { refreshPromise = null; throw err; });
    return refreshPromise;
  }

  function request(path, options) {
    options = options || {};
    var method  = options.method || 'GET';
    var headers = Object.assign({}, options.headers || {});
    var body    = options.body;

    if (body && typeof body === 'object' && !(body instanceof FormData)) {
      headers['Content-Type'] = headers['Content-Type'] || 'application/json';
      body = JSON.stringify(body);
    }

    var token = getToken();
    if (token && !options.noAuth) headers['Authorization'] = 'Bearer ' + token;

    var url = path.indexOf('http') === 0 ? path : API_BASE + path;

    return fetch(url, { method: method, headers: headers, body: body, credentials: 'omit' })
      .then(function(res) {
        if (res.status === 401 && !options.noAuth && !options._retried) {
          return refreshAccessToken().then(function() {
            return request(path, Object.assign({}, options, { _retried: true }));
          }).catch(function() {
            /* Ne pas rediriger — la page gère elle-même via handleAuthExpired() */
            throw new Error('auth_expired');
          });
        }
        return parseResponse(res);
      });
  }

  function parseResponse(res) {
    var ct = res.headers.get('content-type') || '';
    var isJson = ct.indexOf('application/json') !== -1;
    if (!res.ok) {
      return (isJson ? res.json() : res.text()).then(function(data) {
        var msg = (data && data.message) || (data && data.code) || ('http_error_' + res.status);
        var e = new Error(msg); e.status = res.status; e.code = data && data.code; e.body = data; throw e;
      }).catch(function(e) { if (e.status) throw e; throw new Error('http_error_' + res.status); });
    }
    if (res.status === 204) return null;
    if (isJson) return res.json().then(unwrap);
    return res.text();
  }

  function get(p, o)    { return request(p, Object.assign({ method:'GET' },    o||{})); }
  function post(p,b,o)  { return request(p, Object.assign({ method:'POST',   body:b }, o||{})); }
  function patch(p,b,o) { return request(p, Object.assign({ method:'PATCH',  body:b }, o||{})); }
  function put(p,b,o)   { return request(p, Object.assign({ method:'PUT',    body:b }, o||{})); }
  function del(p,b,o)   { return request(p, Object.assign({ method:'DELETE', body:b }, o||{})); }

  global.MKO_API = {
    BASE: API_BASE, TOKEN_KEY: TOKEN_KEY, REFRESH_KEY: REFRESH_KEY,
    getToken: getToken, getRefreshToken: getRefreshToken,
    setTokens: setTokens, clearTokens: clearTokens,
    request: request, get: get, post: post, patch: patch, put: put, delete: del,
    refresh: refreshAccessToken, unwrap: unwrap
  };
})(window);
