import { apiRequest } from '../lib/api' import { getActiveBusinessId } from '../lib/businessContext' import type { UserProductListItem } from '../types/userProduct' export type UserProductCondition = 'new' | 'stock' | 'needs_repair' | 'scrap' export type UserProductPriceCurrency = 'IRT' | 'USD' | 'EUR' | 'AED' export type TechnicalFieldType = | 'text' | 'textarea' | 'select' | 'multi_select' | 'multi_value' export interface UserProductCategoryOption { id: string name: string nameFa: string | null parentId: string | null } export interface TechnicalFormFieldOption { id: string label: string value: string sortOrder: number } export interface TechnicalFormField { id: string label: string key: string type: TechnicalFieldType isRequired: boolean sortOrder: number options: TechnicalFormFieldOption[] } export interface CategoryTechnicalForm { id: string categoryId: string fields: TechnicalFormField[] } export type TechnicalFormValues = Record export interface UserProductTechnicalValueInput { fieldId: string textValue?: string optionId?: string optionIds?: string[] } export interface CreateUserProductInput { titleFa: string titleEn?: string description?: string categoryId: string price?: number priceCurrency?: UserProductPriceCurrency priceByExpert?: boolean countryId: string cityId: string deliveryNote?: string condition: UserProductCondition technicalNotes?: string technicalValues?: UserProductTechnicalValueInput[] featuredMediaId?: string galleryMediaIds?: string[] } export type UpdateUserProductInput = CreateUserProductInput export interface UserProductDetail extends UserProductListItem { countryId: string cityId: string countrySlug: string featuredMediaId: string | null galleryMediaIds: string[] images: Array<{ mediaId: string; url: string }> technicalValues: UserProductTechnicalValueInput[] deliveryNote?: string | null technicalNotes?: string | null } export interface ListMyUserProductsParams { page?: number pageSize?: number } export interface MyUserProductsListResponse { items: UserProductListItem[] total: number page: number pageSize: number } function businessPath(suffix = '') { const businessId = getActiveBusinessId() if (!businessId) { throw new Error('No active business selected. Please sign in again.') } return `/businesses/${businessId}/my-user-products${suffix}` } /** Decode free-text list values stored as JSON in text_value. */ export function decodeMultiValueText(raw: string | null | undefined): string[] { if (raw == null) return [] const trimmed = raw.trim() if (!trimmed) return [] if (trimmed.startsWith('[')) { try { const parsed = JSON.parse(trimmed) as unknown if (Array.isArray(parsed)) { return parsed.map((item) => String(item).trim()).filter(Boolean) } } catch { // fall through } } return [trimmed] } export function hydrateTechnicalFormValues( fields: TechnicalFormField[], values: TechnicalFormValues, ): TechnicalFormValues { const next: TechnicalFormValues = { ...values } for (const field of fields) { if (field.type !== 'multi_value') continue const current = next[field.id] if (Array.isArray(current)) continue if (typeof current === 'string') { next[field.id] = decodeMultiValueText(current) } else { next[field.id] = [] } } return next } export function buildTechnicalValuesPayload( fields: TechnicalFormField[], values: TechnicalFormValues, ): UserProductTechnicalValueInput[] { const payload: UserProductTechnicalValueInput[] = [] for (const field of fields) { const value = values[field.id] if (field.type === 'text' || field.type === 'textarea') { const text = typeof value === 'string' ? value.trim() : '' if (!text) continue payload.push({ fieldId: field.id, textValue: text }) continue } if (field.type === 'multi_value') { const items = Array.isArray(value) ? value.map((item) => String(item).trim()).filter(Boolean) : [] if (!items.length) continue payload.push({ fieldId: field.id, textValue: JSON.stringify(items) }) continue } if (field.type === 'select') { const optionId = typeof value === 'string' ? value.trim() : '' if (!optionId) continue payload.push({ fieldId: field.id, optionId }) continue } const optionIds = Array.isArray(value) ? value.filter(Boolean) : [] if (!optionIds.length) continue payload.push({ fieldId: field.id, optionIds }) } return payload } export async function listMyUserProducts( params: ListMyUserProductsParams = {}, signal?: AbortSignal, ) { const q = new URLSearchParams() if (params.page !== undefined) q.set('page', String(params.page)) if (params.pageSize !== undefined) q.set('pageSize', String(params.pageSize)) const query = q.toString() return apiRequest( `${businessPath()}${query ? `?${query}` : ''}`, { auth: true, signal }, ) } export async function createMyUserProduct(input: CreateUserProductInput) { return apiRequest<{ message: string; product: UserProductListItem }>( businessPath(), { method: 'POST', auth: true, body: input, }, ) } export async function getMyUserProduct( productId: string, signal?: AbortSignal, ) { return apiRequest<{ product: UserProductDetail }>( businessPath(`/${productId}`), { auth: true, signal }, ) } export async function updateMyUserProduct( productId: string, input: UpdateUserProductInput, ) { return apiRequest<{ message: string; product: UserProductListItem }>( businessPath(`/${productId}`), { method: 'PATCH', auth: true, body: input, }, ) } export async function deleteMyUserProduct(productId: string) { return apiRequest<{ message: string }>(businessPath(`/${productId}`), { method: 'DELETE', auth: true, }) } export async function promoteMyUserProduct(productId: string) { return apiRequest<{ message: string; product: UserProductListItem }>( businessPath(`/${productId}/promote`), { method: 'POST', auth: true, }, ) } export async function listMyUserProductCategories(signal?: AbortSignal) { return apiRequest<{ items: UserProductCategoryOption[] }>( businessPath('/categories'), { auth: true, signal }, ) } export async function getMyUserProductCategoryTechnicalForm( categoryId: string, signal?: AbortSignal, ) { return apiRequest<{ form: CategoryTechnicalForm | null }>( businessPath(`/categories/${categoryId}/technical-form`), { auth: true, signal }, ) }