/**
 * /public_html/test_erp/ui/js/erp_csrf.js
 * ERP CSRF Helper v1.1 — Test environment
 *
 * Load once in a page:
 *   <script src="js/erp_csrf.js"></script>
 *
 * It automatically adds X-CSRF-Token to same-origin write requests made
 * through window.fetch. Existing fetch(...) calls do not need to be renamed.
 */
(function (global) {
  'use strict';

  if (global.erpCsrf && global.erpCsrf.version) return;

  var CSRF_KEY = 'erp_csrf_token_test';
  var nativeFetch = global.fetch.bind(global);
  var currentScript = document.currentScript;
  var appRoot;

  if (currentScript && currentScript.src) {
    appRoot = new URL('../../', currentScript.src);
  } else {
    var marker = '/ui/';
    var path = global.location.pathname || '/';
    var index = path.indexOf(marker);
    appRoot = new URL(index >= 0 ? path.slice(0, index + 1) : '/', global.location.origin);
  }

  var CSRF_URL = new URL('api/auth/csrf_token.php', appRoot).href;

  function getStoredToken() {
    try { return sessionStorage.getItem(CSRF_KEY) || ''; }
    catch (e) { return ''; }
  }

  function setStoredToken(token) {
    try {
      if (token) sessionStorage.setItem(CSRF_KEY, token);
      else sessionStorage.removeItem(CSRF_KEY);
    } catch (e) {}
  }

  function clearStoredToken() {
    setStoredToken('');
  }

  async function fetchToken() {
    var response = await nativeFetch(CSRF_URL, {
      method: 'GET',
      credentials: 'same-origin',
      cache: 'no-store',
      headers: { 'Accept': 'application/json' }
    });

    if (!response.ok) throw new Error('CSRF token request failed');

    var data = await response.json();
    var token = (data && data.data && data.data.csrf_token) ||
      response.headers.get('X-CSRF-Token') || '';

    if (!token) throw new Error('CSRF token is empty');

    setStoredToken(token);
    return token;
  }

  async function ensureToken() {
    return getStoredToken() || fetchToken();
  }

  function requestUrl(input) {
    return new URL(input instanceof Request ? input.url : String(input), global.location.href);
  }

  function requestMethod(input, options) {
    return String(
      (options && options.method) ||
      (input instanceof Request ? input.method : 'GET')
    ).toUpperCase();
  }

  function cloneInput(input) {
    return input instanceof Request ? input.clone() : input;
  }

  async function erpFetch(input, options) {
    options = options ? Object.assign({}, options) : {};

    var url = requestUrl(input);
    var method = requestMethod(input, options);
    var isSameOrigin = url.origin === global.location.origin;
    var needsCsrf = isSameOrigin && !['GET', 'HEAD', 'OPTIONS'].includes(method);
    var isTokenRequest = url.href === CSRF_URL;

    var baseHeaders = input instanceof Request ? input.headers : undefined;
    var headers = new Headers(options.headers || baseHeaders || {});

    options.credentials = options.credentials ||
      (input instanceof Request ? input.credentials : 'same-origin') ||
      'same-origin';

    if (!headers.has('Content-Type') && typeof options.body === 'string') {
      var trimmed = options.body.trim();
      if (trimmed.charAt(0) === '{' || trimmed.charAt(0) === '[') {
        headers.set('Content-Type', 'application/json');
      }
    }

    if (needsCsrf && !isTokenRequest) {
      headers.set('X-CSRF-Token', await ensureToken());
    }

    options.headers = headers;

    var response = await nativeFetch(cloneInput(input), options);
    var responseToken = response.headers.get('X-CSRF-Token');
    if (responseToken) setStoredToken(responseToken);

    if (response.status === 419 && needsCsrf && !isTokenRequest) {
      clearStoredToken();
      headers.set('X-CSRF-Token', await fetchToken());
      options.headers = headers;
      response = await nativeFetch(cloneInput(input), options);

      responseToken = response.headers.get('X-CSRF-Token');
      if (responseToken) setStoredToken(responseToken);
    }

    if (response.status === 401) clearStoredToken();
    return response;
  }

  function captureLoginToken(loginResponseData) {
    if (loginResponseData && loginResponseData.csrf_token) {
      setStoredToken(loginResponseData.csrf_token);
    }
  }

  global.fetch = erpFetch;
  global.erpFetch = erpFetch;
  global.erpCsrf = {
    version: '1.1-test',
    url: CSRF_URL,
    get: getStoredToken,
    set: setStoredToken,
    clear: clearStoredToken,
    refresh: fetchToken,
    captureLoginToken: captureLoginToken
  };
})(window);
