import { apiRequest, getAccessToken } from "@/lib/meshkee-api"; export interface MeshkeeBusinessSearchItem { id: string; name: string; nameFa: string | null; slug: string; label: string; ownerName?: string | null; ownerCellNumber?: string | null; } export interface MeshkeeBusinessCategory { id: string; name: string; slug: string; parentId: string | null; } export interface MeshkeeBusinessOwner { id: string; cellNumber: string; firstName: string | null; lastName: string | null; firstNameEn: string | null; lastNameEn: string | null; email: string | null; } export interface MeshkeeBusinessDetail { id: string; name: string; nameFa: string | null; slug: string; categories: MeshkeeBusinessCategory[]; categoryIds: string[]; owner: MeshkeeBusinessOwner | null; logoUrl: string | null; logoMediaId: string | null; bannerUrl: string | null; bannerMediaId: string | null; createdAt?: string; } function mapSearchItem( item: MeshkeeBusinessSearchItem, ): MeshkeeBusinessSearchItem { const name = item.name ?? ""; const nameFa = item.nameFa ?? null; return { ...item, id: String(item.id), name, nameFa, slug: item.slug ?? "", label: item.label || name || item.slug || String(item.id), ownerName: item.ownerName ?? null, ownerCellNumber: item.ownerCellNumber ?? null, }; } export async function searchMeshkeeBusinesses( q: string, signal?: AbortSignal, ) { const params = new URLSearchParams({ q, limit: "20", }); const data = await apiRequest<{ items: MeshkeeBusinessSearchItem[] }>( `/businesses/search?${params}`, { auth: true, signal }, ); return { items: (data.items ?? []).map(mapSearchItem), }; } /** Newest Meshkee businesses (super-admin list, created_at desc). */ export async function listLatestMeshkeeBusinesses( limit = 5, signal?: AbortSignal, ) { const pageSize = Math.min(Math.max(limit, 5), 50); const params = new URLSearchParams({ page: "1", pageSize: String(pageSize), sort: "created", }); const data = await apiRequest<{ items: MeshkeeBusinessSearchItem[] }>( `/businesses?${params}`, { auth: true, signal }, ); return { items: (data.items ?? []).slice(0, limit).map(mapSearchItem), }; } export async function getMeshkeeBusiness( businessId: string, signal?: AbortSignal, ) { const data = await apiRequest( `/businesses/${businessId}`, { auth: true, signal }, ); return { ...data, id: String(data.id), createdAt: data.createdAt, categories: (data.categories ?? []).map((category) => ({ ...category, id: String(category.id), parentId: category.parentId == null ? null : String(category.parentId), })), categoryIds: (data.categoryIds ?? []).map(String), owner: data.owner ? { ...data.owner, id: String(data.owner.id), } : null, }; } export async function createMeshkeeBusiness(body: { name: string; nameFa: string; slug?: string; categoryIds: number[]; ownerFirstName: string; ownerLastName: string; ownerFirstNameEn: string; ownerLastNameEn: string; ownerCellNumber: string; ownerPassword: string; }) { const data = await apiRequest(`/businesses`, { method: "POST", auth: true, body, }); return { ...data, id: String(data.id) }; } export async function uploadBusinessMedia( businessId: string, file: File, ): Promise<{ id: string; publicUrl: string }> { const token = getAccessToken(); const form = new FormData(); form.append("files", file); const base = process.env.NEXT_PUBLIC_MESHKEE_API_URL?.replace(/\/$/, "") || "http://localhost:3010/api/v1"; const response = await fetch(`${base}/businesses/${businessId}/media`, { method: "POST", headers: token ? { Authorization: `Bearer ${token}` } : undefined, body: form, }); 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(", ") : `Upload failed (${response.status})`; throw new Error(message); } const item = Array.isArray(payload?.items) ? payload.items[0] : Array.isArray(payload) ? payload[0] : payload; return { id: String(item.id), publicUrl: String(item.publicUrl ?? item.url ?? ""), }; } export async function updateBusinessBanner( businessId: string, bannerMediaId: string | null, ) { return updateBusinessProfile(businessId, { bannerMediaId: bannerMediaId == null ? null : Number(bannerMediaId), }); } export type BusinessPhoneType = "landline" | "cell"; export interface BusinessPhoneNumber { type: BusinessPhoneType; number: string; /** Optional; supported after Meshkee deploy with label field */ label?: string; } export interface BusinessAddress { id?: string; /** Display name / label for the address */ name: string; province: string; city: string; address: string; postalCode: string; landline?: string | null; } export interface BusinessProfile { businessId: string; profile: { nameEn: string; nameFa: string; title: string; about: string; vision: string; emails: string[]; phoneNumbers: BusinessPhoneNumber[]; socialMedia: Record; logoMediaId: string | null; logoUrl: string | null; bannerMediaId: string | null; bannerUrl: string | null; categoryIds: string[]; }; addresses: BusinessAddress[]; } export type UpdateBusinessProfileInput = { nameEn?: string; nameFa?: string; title?: string; about?: string; vision?: string; phoneNumbers?: BusinessPhoneNumber[]; logoMediaId?: number | null; bannerMediaId?: number | null; categoryIds?: number[]; addresses?: BusinessAddress[]; }; export async function getBusinessProfile(businessId: string) { const data = await apiRequest( `/businesses/${businessId}/profile`, { auth: true }, ); return { businessId: String(data.businessId), profile: { ...data.profile, logoMediaId: data.profile.logoMediaId == null ? null : String(data.profile.logoMediaId), bannerMediaId: data.profile.bannerMediaId == null ? null : String(data.profile.bannerMediaId), categoryIds: (data.profile.categoryIds ?? []).map(String), phoneNumbers: (data.profile.phoneNumbers ?? []).map((phone) => ({ type: phone.type === "landline" ? "landline" : "cell", number: phone.number ?? "", ...(phone.label?.trim() ? { label: phone.label.trim() } : {}), })), emails: data.profile.emails ?? [], about: data.profile.about ?? "", vision: data.profile.vision ?? "", nameEn: data.profile.nameEn ?? "", nameFa: data.profile.nameFa ?? "", title: data.profile.title ?? "", logoUrl: data.profile.logoUrl ?? null, bannerUrl: data.profile.bannerUrl ?? null, socialMedia: data.profile.socialMedia ?? {}, }, addresses: (data.addresses ?? []).map((address) => ({ ...address, id: address.id == null ? undefined : String(address.id), name: String( (address as BusinessAddress & { label?: string | null }).name ?? (address as { label?: string | null }).label ?? "", ), landline: address.landline ?? "", postalCode: address.postalCode ?? "", })), }; } export async function updateBusinessProfile( businessId: string, body: UpdateBusinessProfileInput, ) { return apiRequest(`/businesses/${businessId}/profile`, { method: "PATCH", auth: true, body, }); }