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<T>(path: string, opts?: RequestInit): Promise<T | null> {
  try {
    const res = await fetch(`${API_URL}${path}`, {
      next: { revalidate: 60 },
      ...opts,
    });
    if (!res.ok) return null;
    const json = (await res.json()) as ApiResponse<T>;
    return json.success ? json.data : null;
  } catch {
    return null;
  }
}

// ── Discover / search ─────────────────────────────────────────────────────────

export async function discoverCafes(
  filters: DiscoverFilters
): Promise<CafeDiscoverDto[]> {
  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<CafeDiscoverDto[]>(
    `/api/public/discover${qs ? `?${qs}` : ""}`,
    { next: { revalidate: 30 } }
  );
  return result ?? [];
}

// ── Individual cafe ───────────────────────────────────────────────────────────

export async function getCafe(slug: string): Promise<CafePublicDto | null> {
  return get<CafePublicDto>(`/api/public/cafes/${slug}`, {
    next: { revalidate: 300 },
  });
}

// ── Menu ──────────────────────────────────────────────────────────────────────

export async function getCafeMenu(slug: string): Promise<PublicMenuDto | null> {
  return get<PublicMenuDto>(`/api/public/cafes/${slug}/menu`, {
    next: { revalidate: 300 },
  });
}

// ── Reviews ───────────────────────────────────────────────────────────────────

export async function getCafeReviews(
  slug: string,
  page = 1
): Promise<CafeReviewDto[]> {
  const result = await get<CafeReviewDto[]>(
    `/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<NlpHints | null> {
  return get<NlpHints>(
    `/api/public/discover/nlp-parse?q=${encodeURIComponent(q)}`,
    { cache: "no-store" }
  );
}

// ── Slugs for static generation ───────────────────────────────────────────────

export async function getAllCafeSlugs(): Promise<string[]> {
  // Fetch all cafes without filters to get slugs for static generation
  const cafes = await get<CafeDiscoverDto[]>("/api/public/discover?requireProfile=false", {
    next: { revalidate: 3600 },
  });
  return cafes?.map((c) => c.slug) ?? [];
}
