import { createApiClient } from "../lib/apiClient"; import { serializeButtonAppearanceForApi } from "../lib/categoryButtonAppearance"; import type { LabelCategoryCreateInput, LabelCategoryDto, LabelCategoryGetListInput, LabelCategoryUpdateInput, PagedResultDto, } from "../types/labelCategory"; const api = createApiClient({ getToken: () => { try { return localStorage.getItem("access_token") ?? localStorage.getItem("token") ?? null; } catch { return null; } }, }); const PATH = "/label-category"; function normalizeLabelCategoryDto(raw: unknown): LabelCategoryDto { const r = (raw && typeof raw === "object" ? raw : {}) as Record; const parseIds = (v: unknown): string[] | undefined => { if (!Array.isArray(v)) return undefined; return [...new Set(v.map((x) => String(x).trim()).filter(Boolean))]; }; const groupIds = parseIds(r.groupIds ?? r.GroupIds ?? r.regionIds ?? r.RegionIds); const locationIds = parseIds(r.locationIds ?? r.LocationIds); const partnerIds = parseIds(r.partnerIds ?? r.PartnerIds ?? r.companyIds ?? r.CompanyIds); const noRaw = r.noOfLabels ?? r.NoOfLabels; const noOfLabels = typeof noRaw === "number" && Number.isFinite(noRaw) ? noRaw : typeof noRaw === "string" && noRaw.trim() !== "" && Number.isFinite(Number(noRaw)) ? Number(noRaw) : null; const orderRaw = r.orderNum ?? r.OrderNum; const orderNum = typeof orderRaw === "number" && Number.isFinite(orderRaw) ? orderRaw : typeof orderRaw === "string" && orderRaw.trim() !== "" && Number.isFinite(Number(orderRaw)) ? Number(orderRaw) : null; const companyRaw = r.company ?? r.Company; return { ...(r as object), id: String(r.id ?? r.Id ?? ""), appliedPartnerType: String(r.appliedPartnerType ?? r.AppliedPartnerType ?? "").trim() || undefined, partnerIds, companyIds: partnerIds, availabilityType: String(r.availabilityType ?? r.AvailabilityType ?? "").trim() || undefined, groupIds, regionIds: groupIds, locationIds, company: typeof companyRaw === "string" ? companyRaw : null, noOfLabels, orderNum, } as LabelCategoryDto; } function scopeBodyFromInput(input: LabelCategoryCreateInput): Record { const groupIds = [ ...new Set( [...(input.groupIds ?? []), ...(input.regionIds ?? [])] .map((x) => String(x).trim()) .filter(Boolean), ), ]; const locationIds = [ ...new Set((input.locationIds ?? []).map((x) => String(x).trim()).filter(Boolean)), ]; const partnerIds = [ ...new Set( [...(input.partnerIds ?? []), ...(input.companyIds ?? [])] .map((x) => String(x).trim()) .filter(Boolean), ), ]; const body: Record = {}; const appliedPartnerType = String(input.appliedPartnerType ?? "").trim().toUpperCase(); if (appliedPartnerType === "ALL" || appliedPartnerType === "SPECIFIED") { body.appliedPartnerType = appliedPartnerType; } if (partnerIds.length) { body.partnerIds = partnerIds; body.companyIds = partnerIds; } const availabilityType = String(input.availabilityType ?? "ALL").trim().toUpperCase() || "ALL"; body.availabilityType = availabilityType; if (groupIds.length) { body.groupIds = groupIds; body.regionIds = groupIds; } if (locationIds.length) { body.locationIds = locationIds; } return body; } export async function getLabelCategories(input: LabelCategoryGetListInput, signal?: AbortSignal): Promise> { const res = await api.requestJson & { items?: unknown[]; Items?: unknown[] }>({ path: PATH, method: "GET", query: { SkipCount: input.skipCount, MaxResultCount: input.maxResultCount, Sorting: input.sorting, Keyword: input.keyword, State: input.state, GroupId: input.groupId, LocationId: input.locationId, }, signal, }); const itemsRaw = res.items ?? res.Items ?? []; const items = (Array.isArray(itemsRaw) ? itemsRaw : []).map((x) => normalizeLabelCategoryDto(x)); return { ...res, items, totalCount: res.totalCount ?? (res as { TotalCount?: number }).TotalCount ?? items.length }; } export async function getLabelCategory(id: string, signal?: AbortSignal): Promise { const raw = await api.requestJson({ path: `${PATH}/${encodeURIComponent(id)}`, method: "GET", signal, }); return normalizeLabelCategoryDto(raw); } export async function createLabelCategory(input: LabelCategoryCreateInput): Promise { return api.requestJson({ path: PATH, method: "POST", body: { categoryCode: String(input.categoryCode ?? "").trim() || null, categoryName: input.categoryName, categoryPhotoUrl: input.categoryPhotoUrl, displayText: (input.displayText ?? "").trim() || null, buttonBgColor: (input.buttonBgColor ?? "").trim() || null, buttonImageUrl: (input.buttonImageUrl ?? "").trim() || null, buttonAppearance: serializeButtonAppearanceForApi(input.buttonAppearance), buttonStyleJson: (input.buttonStyleJson ?? "").trim() || null, state: input.state ?? true, orderNum: input.orderNum, ...scopeBodyFromInput(input), }, }); } export async function updateLabelCategory(id: string, input: LabelCategoryUpdateInput): Promise { const raw = await api.requestJson({ path: `${PATH}/${encodeURIComponent(id)}`, method: "PUT", body: { categoryCode: String(input.categoryCode ?? "").trim() || null, categoryName: input.categoryName, categoryPhotoUrl: input.categoryPhotoUrl, displayText: (input.displayText ?? "").trim() || null, buttonBgColor: (input.buttonBgColor ?? "").trim() || null, buttonImageUrl: (input.buttonImageUrl ?? "").trim() || null, buttonAppearance: serializeButtonAppearanceForApi(input.buttonAppearance), buttonStyleJson: (input.buttonStyleJson ?? "").trim() || null, state: input.state ?? true, orderNum: input.orderNum, ...scopeBodyFromInput(input), }, }); return normalizeLabelCategoryDto(raw); } export async function deleteLabelCategory(id: string): Promise { await api.requestJson({ path: `${PATH}/${encodeURIComponent(id)}`, method: "DELETE", }); }