import "server-only";
import { API_URL, REVALIDATE } from "./site";
import type { Lang } from "@/config/constants";

/**
 * جلب من واجهة ايفوري على الخادم — نفس العناوين التي يستدعيها المتصفح
 * (`${URL}/...` حيث URL = `${NEXT_PUBLIC_IVORY_API}/${lang}`)، مع تخزين ISR.
 * لا يرمي أخطاء: أي فشل يعيد null فتعود الصفحة لسلوك SPA الأصلي (تحميل في المتصفح).
 */
export const apiBase = (lang: Lang) => `${API_URL}/${lang}`;

export async function apiGet<T = any>(lang: Lang, path: string, revalidate = REVALIDATE): Promise<T | null> {
    const r = await apiGetWithStatus<T>(lang, path, revalidate);
    return r.ok ? r.data : null;
}

/**
 * مثل apiGet لكن يميّز بين "غير موجود" وبين "فشل الاتصال":
 *  - notFound: الـ API ردّ صراحةً بـ 404 → الصفحة تعيد 404 حقيقية
 *  - غير ذلك (مهلة، خطأ شبكة، 5xx): لا نحكم بعدم الوجود، فتعود الصفحة لسلوك التحميل في المتصفح
 */
export async function apiGetWithStatus<T = any>(
    lang: Lang,
    path: string,
    revalidate = REVALIDATE
): Promise<{ ok: true; data: T; notFound: false } | { ok: false; data: null; notFound: boolean }> {
    try {
        const res = await fetch(`${apiBase(lang)}${path.startsWith("/") ? path : `/${path}`}`, {
            headers: { Accept: "application/json" },
            next: { revalidate, tags: ["ivory-api"] },
            signal: AbortSignal.timeout(8000),
        });
        if (!res.ok) return { ok: false, data: null, notFound: res.status === 404 };
        return { ok: true, data: (await res.json()) as T, notFound: false };
    } catch {
        return { ok: false, data: null, notFound: false };
    }
}

/** يجمع كل صفحات قائمة مرقّمة (data.data[] + data.meta.last_page) — لـ sitemap */
export async function apiGetAll(lang: Lang, path: string, maxPages = 30): Promise<any[]> {
    const sep = path.includes("?") ? "&" : "?";
    const first = await apiGet<any>(lang, `${path}${sep}page=1&per_page=100`, 3600);
    if (!first) return [];
    const pick = (j: any) => (Array.isArray(j?.data?.data) ? j.data.data : Array.isArray(j?.data) ? j.data : []);
    const items = [...pick(first)];
    const last = Math.min(Number(first?.data?.meta?.last_page || first?.meta?.last_page || 1), maxPages);
    const rest = await Promise.all(
        Array.from({ length: Math.max(0, last - 1) }, (_, i) => apiGet<any>(lang, `${path}${sep}page=${i + 2}&per_page=100`, 3600))
    );
    rest.forEach((j) => items.push(...pick(j)));
    return items;
}
