// public/assets/api.js
/* English comments: centralized API wrapper */

(function () {
  function normalizeDateString(value) {
    if (typeof value !== 'string') return value;
    const s = value.trim();
    if (s === '') return value;
    const isoDate = /^\d{4}-\d{2}-\d{2}$/;
    const isoDateTime = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}/;
    const dotDate = /^\d{2}\.\d{2}\.\d{4}$/;
    const dotDateTime = /^\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2}:\d{2}$/;
    let v = s;
    if (isoDate.test(v)) v = `${v} 00:00:00`;
    if (dotDate.test(v)) {
      const parts = v.split('.');
      v = `${parts[2]}-${parts[1]}-${parts[0]} 00:00:00`;
    } else if (dotDateTime.test(v)) {
      const [datePart, timePart] = v.split(/\s+/, 2);
      const parts = datePart.split('.');
      v = `${parts[2]}-${parts[1]}-${parts[0]} ${timePart}`;
    }
    if (isoDateTime.test(v)) {
      const d = new Date(v.replace(' ', 'T') + 'Z');
      if (!Number.isNaN(d.getTime())) {
        return d.toISOString().slice(0, 19).replace('T', ' ');
      }
    }
    return v;
  }

  function normalizeDates(payload) {
    if (payload === null || payload === undefined) return payload;
    if (Array.isArray(payload)) return payload.map(normalizeDates);
    if (typeof payload !== 'object') return payload;
    const out = {};
    Object.keys(payload).forEach((key) => {
      const value = payload[key];
      if (value && typeof value === 'object') {
        out[key] = normalizeDates(value);
      } else if (typeof value === 'string' && (key === 'ts' || key.endsWith('_at') || key.endsWith('_ts'))) {
        out[key] = normalizeDateString(value);
      } else {
        out[key] = value;
      }
    });
    return out;
  }

  async function request(path, opts = {}) {
    const headers = { ...(opts.headers || {}) };
    const hasBodyObject = opts.body && typeof opts.body === 'object' && !(opts.body instanceof FormData);
    const body = hasBodyObject ? JSON.stringify(normalizeDates(opts.body)) : opts.body;
    if (hasBodyObject && !headers['Content-Type']) {
      headers['Content-Type'] = 'application/json';
    }
    if (window.Auth?.isAccessExpired?.() && window.Auth?.refreshTokens) {
      await window.Auth.refreshTokens();
    }
    const token = window.Auth?.getAccessToken?.();
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }
    let res = await fetch(path, { credentials: 'same-origin', ...opts, headers, body });
    if (res.status === 401 && window.Auth?.refreshTokens) {
      const refreshed = await window.Auth.refreshTokens();
      if (refreshed) {
        const newToken = window.Auth.getAccessToken();
        if (newToken) headers['Authorization'] = `Bearer ${newToken}`;
        res = await fetch(path, { credentials: 'same-origin', ...opts, headers, body });
      } else if (window.Auth?.redirectToLogin) {
        window.Auth.redirectToLogin();
      }
    }
    const json = await res.json().catch(() => null);
    if (!json || json.ok !== true) {
      const msg = json?.error?.message || `Request failed: ${res.status}`;
      throw new Error(msg);
    }
    return json;
  }

  window.Api = {
    request,
  };
})();
