'use strict';

(() => {
  const USER_TOKEN_KEY = 'veg_user_token';
  const ADMIN_TOKEN_KEY = 'veg_admin_token';

  function getToken(admin = false) {
    return localStorage.getItem(admin ? ADMIN_TOKEN_KEY : USER_TOKEN_KEY);
  }

  function setToken(token, admin = false) {
    localStorage.setItem(admin ? ADMIN_TOKEN_KEY : USER_TOKEN_KEY, token);
  }

  function clearToken(admin = false) {
    localStorage.removeItem(admin ? ADMIN_TOKEN_KEY : USER_TOKEN_KEY);
  }

  async function request(path, options = {}) {
    const { admin = false, body, headers = {}, redirectOnUnauthorized = true, ...fetchOptions } = options;
    const token = getToken(admin);
    const requestHeaders = { Accept: 'application/json', ...headers };
    if (body !== undefined) requestHeaders['Content-Type'] = 'application/json';
    if (token) requestHeaders.Authorization = `Bearer ${token}`;

    let response;
    try {
      response = await fetch(path, {
        ...fetchOptions,
        headers: requestHeaders,
        body: body === undefined ? undefined : JSON.stringify(body),
      });
    } catch (_) {
      throw new Error('تعذر الاتصال بالسيرفر. تحقق من الشبكة ثم أعد المحاولة.');
    }

    const contentType = response.headers.get('content-type') || '';
    const data = contentType.includes('application/json') ? await response.json() : await response.text();
    if (!response.ok) {
      if (response.status === 401 && redirectOnUnauthorized) {
        clearToken(admin);
        window.location.replace(admin ? '/admin/login.html' : '/login.html');
      }
      const error = new Error(data?.message || 'تعذر تنفيذ الطلب.');
      error.status = response.status;
      error.data = data;
      throw error;
    }
    return data;
  }

  async function download(path, filename) {
    const token = getToken(false);
    const response = await fetch(path, { headers: token ? { Authorization: `Bearer ${token}` } : {} });
    if (response.status === 401) {
      clearToken(false);
      window.location.replace('/login.html');
      throw new Error('انتهت الجلسة.');
    }
    if (!response.ok) {
      let message = 'تعذر تنزيل الملف.';
      try { message = (await response.json()).message || message; } catch (_) {}
      throw new Error(message);
    }
    const blob = await response.blob();
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.download = filename || 'file.xlsx';
    document.body.appendChild(anchor);
    anchor.click();
    anchor.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }

  function escapeHtml(value) {
    return String(value ?? '')
      .replaceAll('&', '&amp;')
      .replaceAll('<', '&lt;')
      .replaceAll('>', '&gt;')
      .replaceAll('"', '&quot;')
      .replaceAll("'", '&#039;');
  }

  function formatNumber(value, decimals = 2) {
    if (value === null || value === undefined || value === '') return '';
    const number = Number(value);
    if (!Number.isFinite(number)) return '';
    return new Intl.NumberFormat('en-US', {
      minimumFractionDigits: decimals,
      maximumFractionDigits: decimals,
    }).format(number);
  }

  function formatFlexible(value, maxDecimals = 3) {
    if (value === null || value === undefined || value === '') return '';
    const number = Number(value);
    if (!Number.isFinite(number)) return '';
    return new Intl.NumberFormat('en-US', { maximumFractionDigits: maxDecimals }).format(number);
  }

  function formatDate(value) {
    if (!value) return '';
    const dateText = String(value).slice(0, 10);
    const date = new Date(`${dateText}T12:00:00Z`);
    return new Intl.DateTimeFormat('ar-SA', { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
  }

  function formatDateTime(value) {
    if (!value) return '';
    const text = String(value);
    const date = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(text)
      ? new Date(`${text.replace(' ', 'T')}Z`)
      : new Date(value);
    return new Intl.DateTimeFormat('ar-SA', {
      year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit',
    }).format(date);
  }

  function toast(message, type = 'success') {
    const container = document.getElementById('toastContainer');
    if (!container) return;
    const element = document.createElement('div');
    element.className = `toast ${type}`;
    element.textContent = message;
    container.appendChild(element);
    setTimeout(() => element.remove(), 4500);
  }

  function setButtonLoading(button, loading, loadingText = 'جاري التنفيذ...') {
    if (!button) return;
    if (loading) {
      button.dataset.originalText = button.textContent;
      button.textContent = loadingText;
      button.disabled = true;
    } else {
      button.textContent = button.dataset.originalText || button.textContent;
      button.disabled = false;
    }
  }

  document.addEventListener('click', (event) => {
    const button = event.target.closest('[data-password-toggle]');
    if (!button) return;
    const input = document.getElementById(button.dataset.passwordToggle);
    if (!input) return;
    const showing = input.type === 'text';
    input.type = showing ? 'password' : 'text';
    button.setAttribute('aria-label', showing ? 'إظهار كلمة المرور' : 'إخفاء كلمة المرور');
  });

  window.VegApi = {
    getToken, setToken, clearToken, request, download, escapeHtml,
    formatNumber, formatFlexible, formatDate, formatDateTime, toast, setButtonLoading,
  };
})();
