import type { ApiResponse, CafeDiscoverDto, CafePublicDto, PublicMenuDto, CafeReviewDto, NlpHints, DiscoverFilters, } from "@/lib/types"; const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "https://api.meezi.ir"; async function get(path: string, opts?: RequestInit): Promise { try { const res = await fetch(`${API_URL}${path}`, { next: { revalidate: 60 }, ...opts, }); if (!res.ok) return null; const json = (await res.json()) as ApiResponse; return json.success ? json.data : null; } catch { return null; } } // ── Discover / search ───────────────────────────────────────────────────────── export async function discoverCafes( filters: DiscoverFilters ): Promise { const params = new URLSearchParams(); if (filters.city) params.set("city", filters.city); if (filters.q) params.set("q", filters.q); if (filters.minRating) params.set("minRating", String(filters.minRating)); if (filters.sort) params.set("sort", filters.sort); if (filters.themes?.length) params.set("themes", filters.themes.join(",")); if (filters.vibes?.length) params.set("vibes", filters.vibes.join(",")); if (filters.occasions?.length) params.set("occasions", filters.occasions.join(",")); if (filters.spaceFeatures?.length) params.set("spaceFeatures", filters.spaceFeatures.join(",")); if (filters.noise) params.set("noise", filters.noise); if (filters.priceTier) params.set("priceTier", filters.priceTier); if (filters.size) params.set("size", filters.size); if (filters.openNow) params.set("openNow", "true"); const qs = params.toString(); const result = await get( `/api/public/discover${qs ? `?${qs}` : ""}`, { next: { revalidate: 30 } } ); return result ?? []; } // ── Individual cafe ─────────────────────────────────────────────────────────── export async function getCafe(slug: string): Promise { return get(`/api/public/cafes/${slug}`, { next: { revalidate: 300 }, }); } // ── Menu ────────────────────────────────────────────────────────────────────── export async function getCafeMenu(slug: string): Promise { return get(`/api/public/cafes/${slug}/menu`, { next: { revalidate: 300 }, }); } // ── Reviews ─────────────────────────────────────────────────────────────────── export async function getCafeReviews( slug: string, page = 1 ): Promise { const result = await get( `/api/public/cafes/${slug}/reviews?page=${page}&pageSize=10`, { next: { revalidate: 120 } } ); return result ?? []; } // ── NLP parse (server-side only; for ISR hint pre-population) ───────────────── export async function nlpParse(q: string): Promise { return get( `/api/public/discover/nlp-parse?q=${encodeURIComponent(q)}`, { cache: "no-store" } ); } // ── Slugs for static generation ─────────────────────────────────────────────── export async function getAllCafeSlugs(): Promise { // Fetch all cafes without filters to get slugs for static generation const cafes = await get("/api/public/discover?requireProfile=false", { next: { revalidate: 3600 }, }); return cafes?.map((c) => c.slug) ?? []; }