// composables/useCachedRequest.js
import { useApiCache } from "~/composables/useApiCache";

const tryParseJSON = (str) => {
  if (typeof str !== "string") return str;
  if (!str.trim()) return null;
  try {
    return JSON.parse(str);
  } catch (e) {
    return str; // اگر parse نشد، رشته را همون‌طور برگردون
  }
};

export const useCachedRequest = () => {
  const cache = useApiCache();
  const { $http: httpService } = useNuxtApp();

  // ساختن کلید ساده و یکتا برای هر request
  const getRequestKey = (config = {}) => {
    const method = (config.crud || "GET").toUpperCase();
    const payloadNorm = tryParseJSON(config.payload) ?? null;
    return `${method}:${config.url}:${JSON.stringify(payloadNorm)}`;
  };

  // درخواست با cache و dedupe
  const fetchRequest = async (config = {}) => {
    if (!config?.url) throw new Error("apiConfig.url is required");

    const key = getRequestKey(config);

    // پاک کردن cache منقضی شده
    if (cache.hasData(key) && cache.isExpired(key)) cache.removeData(key);

    // 1. اگر قبلاً داده موجود است → برگردان
    if (cache.hasData(key)) return cache.getData(key);

    // 2. اگر درخواست در حال اجراست → promise را await کن (dedupe)
    const pending = cache.getPending(key);
    if (pending) return await pending;

    // 3. ایجاد request جدید
    const promise = (async () => {
      let response;
      const method = (config.crud || "GET").toUpperCase();

      if (method === "POST") {
        const payload = tryParseJSON(config.payload) ?? {};
        response = await httpService.postRequest(config.url, payload);
      } else {
        response = await httpService.getRequest(config.url);
      }

      const data = response?.data ?? response;

      // ذخیره با TTL در صورت وجود
      const ttl = config.ttlSeconds || 0;
      if (ttl > 0) {
        cache.saveDataWithTTL(key, data, ttl);
      } else {
        cache.saveData(key, data);
      }

      return data;
    })();

    cache.setPending(key, promise);

    try {
      return await promise;
    } finally {
      cache.clearPending(key);
    }
  };

  // پاکسازی دستی cache برای logout یا تغییر داده‌ها
  const invalidate = (configOrKey) => {
    const key =
      typeof configOrKey === "string"
        ? configOrKey
        : getRequestKey(configOrKey || {});
    cache.removeData(key);
  };

  const clearAll = () => cache.clearAllData();

  return { fetchRequest, invalidate, clearAll };
};
