import { getAccessToken } from "@/lib/meshkee-api"; const API_BASE_URL = process.env.NEXT_PUBLIC_MARKETPLACE_API_URL?.replace(/\/$/, "") || "http://localhost:3001/api/v1"; function apiOrigin() { return API_BASE_URL.replace(/\/api\/v1$/, ""); } export type WebsiteBlogCategory = { id: string; name: string; nameFa?: string | null; description?: string | null; parentId: string | null; createdAt?: string; }; export type UpsertWebsiteBlogCategoryInput = { name: string; nameFa?: string; description?: string; parentId?: string | null; }; export type WebsiteBlogPost = { id: string; title: string; abstract?: string | null; mainTextHtml?: string | null; imageUrl?: string | null; categoryId: string; categoryName: string; tags: string[]; createdAt: string; updatedAt: string; }; export type CreateWebsiteBlogPostInput = { title: string; categoryId: string; abstract?: string; mainTextHtml?: string; imageUrl?: string; tags?: string[]; }; async function parseResponse(response: Response): Promise { const payload = await response.json().catch(() => null); if (!response.ok) { const message = typeof payload?.message === "string" ? payload.message : Array.isArray(payload?.message) ? payload.message.join(", ") : `Request failed (${response.status})`; throw new Error(message); } return payload as T; } function authHeaders(json = false): HeadersInit { const headers: Record = {}; if (json) headers["Content-Type"] = "application/json"; const token = getAccessToken(); if (token) headers.Authorization = `Bearer ${token}`; return headers; } export function toStoredMediaUrl(url: string) { if (!url) return url; const origin = apiOrigin(); if (url.startsWith(origin)) return url.slice(origin.length); return url; } export function toDisplayMediaUrl(url: string) { if (!url) return url; if (url.startsWith("http://") || url.startsWith("https://")) return url; if (url.startsWith("/api/v1/")) return `${apiOrigin()}${url}`; return url; } function rewriteSrc( html: string, map: (src: string) => string, ) { return html.replace( /(]*\bsrc=["'])([^"']*)(["'])/gi, (_match, start: string, src: string, end: string) => `${start}${map(src)}${end}`, ); } export function toStoredHtml(html: string) { return rewriteSrc(html, toStoredMediaUrl); } export function toEditorHtml(html: string) { return rewriteSrc(html, toDisplayMediaUrl); } export async function listWebsiteBlogCategories() { const response = await fetch(`${API_BASE_URL}/website/blog/categories`, { cache: "no-store", headers: authHeaders(), }); const data = await parseResponse<{ items: WebsiteBlogCategory[] }>(response); return (data.items ?? []).map(normalizeCategory); } function normalizeCategory(item: WebsiteBlogCategory): WebsiteBlogCategory { return { ...item, id: String(item.id), parentId: item.parentId == null ? null : String(item.parentId), nameFa: item.nameFa ?? null, description: item.description ?? null, }; } function categoryBody(input: UpsertWebsiteBlogCategoryInput) { return { name: input.name, nameFa: input.nameFa?.trim() || undefined, description: input.description?.trim() || undefined, ...(input.parentId ? { parentId: input.parentId } : {}), }; } export async function createWebsiteBlogCategory( input: UpsertWebsiteBlogCategoryInput, ) { const response = await fetch(`${API_BASE_URL}/website/blog/categories`, { method: "POST", headers: authHeaders(true), body: JSON.stringify(categoryBody(input)), }); const item = await parseResponse(response); return normalizeCategory(item); } export async function updateWebsiteBlogCategory( id: string, input: UpsertWebsiteBlogCategoryInput, ) { const response = await fetch( `${API_BASE_URL}/website/blog/categories/${encodeURIComponent(id)}`, { method: "PATCH", headers: authHeaders(true), body: JSON.stringify(categoryBody(input)), }, ); const item = await parseResponse(response); return normalizeCategory(item); } export async function deleteWebsiteBlogCategory(id: string) { const response = await fetch( `${API_BASE_URL}/website/blog/categories/${encodeURIComponent(id)}`, { method: "DELETE", headers: authHeaders(), }, ); return parseResponse<{ ok: boolean }>(response); } export async function listWebsiteBlogPosts() { const response = await fetch(`${API_BASE_URL}/website/blog/posts`, { cache: "no-store", headers: authHeaders(), }); const data = await parseResponse<{ items: WebsiteBlogPost[]; total: number; }>(response); return { total: data.total ?? data.items?.length ?? 0, items: (data.items ?? []).map((item) => ({ ...item, id: String(item.id), categoryId: String(item.categoryId), imageUrl: item.imageUrl ? toDisplayMediaUrl(item.imageUrl) : item.imageUrl, tags: item.tags ?? [], })), }; } export async function createWebsiteBlogPost(input: CreateWebsiteBlogPostInput) { const response = await fetch(`${API_BASE_URL}/website/blog/posts`, { method: "POST", headers: authHeaders(true), body: JSON.stringify({ ...input, imageUrl: input.imageUrl ? toStoredMediaUrl(input.imageUrl) : undefined, mainTextHtml: input.mainTextHtml ? toStoredHtml(input.mainTextHtml) : undefined, }), }); return parseResponse(response); } export async function deleteWebsiteBlogPost(id: string) { const response = await fetch( `${API_BASE_URL}/website/blog/posts/${encodeURIComponent(id)}`, { method: "DELETE", headers: authHeaders(), }, ); return parseResponse<{ ok: boolean }>(response); }