import { defineStore } from 'pinia' import { computed, ref } from 'vue' import { apiRequest } from '@/services/http' const STORAGE_KEY = 'ft_catalog_requests' export type CatalogRequestItem = { productId: string productName: string productCode: string quantity: number } /** UI statuses (legacy) + server statuses mapped in */ export type CatalogRequestStatus = | 'submitted' | 'reviewing' | 'preparing' | 'shipped' | 'delivered' | 'new' | 'approved' | 'ready_to_ship' | 'returned' | 'cancelled' export type CatalogRequest = { id: string createdAt: string status: CatalogRequestStatus note?: string items: CatalogRequestItem[] } const SERVER_TO_UI: Record = { new: 'submitted', approved: 'reviewing', ready_to_ship: 'preparing', delivered: 'delivered', returned: 'delivered', cancelled: 'submitted', } function readAll(): CatalogRequest[] { try { const raw = localStorage.getItem(STORAGE_KEY) if (!raw) return [] const parsed = JSON.parse(raw) as unknown return Array.isArray(parsed) ? (parsed as CatalogRequest[]) : [] } catch { return [] } } function writeAll(list: CatalogRequest[]) { localStorage.setItem(STORAGE_KEY, JSON.stringify(list)) } const STATUS_LABELS: Record = { submitted: 'ثبت‌شده', reviewing: 'در حال بررسی', preparing: 'آماده‌سازی', shipped: 'ارسال‌شده', delivered: 'تحویل‌شده', new: 'درخواست جدید', approved: 'تأیید شده', ready_to_ship: 'آماده ارسال', returned: 'بازگردانده شده', cancelled: 'لغو شده', } function mapServerRow(row: { id: string createdAt: string status: string note?: string items: Array<{ productId: string productName: string productCode: string quantity: number }> }): CatalogRequest { return { id: row.id, createdAt: row.createdAt, status: SERVER_TO_UI[row.status] ?? (row.status as CatalogRequestStatus), note: row.note, items: row.items.map((i) => ({ productId: i.productId, productName: i.productName, productCode: i.productCode, quantity: i.quantity, })), } } export const useCatalogRequestsStore = defineStore('catalogRequests', () => { const requests = ref(readAll()) const useApi = ref(true) const sorted = computed(() => [...requests.value].sort((a, b) => b.createdAt.localeCompare(a.createdAt)), ) function statusLabel(status: CatalogRequest['status']) { return STATUS_LABELS[status] ?? status } async function hydrate() { if (!useApi.value) { requests.value = readAll() return } try { const rows = await apiRequest< Array<{ id: string createdAt: string status: string note?: string items: Array<{ productId: string productName: string productCode: string quantity: number }> }> >('/catalog-requests') requests.value = rows.map(mapServerRow) writeAll(requests.value) } catch { useApi.value = false requests.value = readAll() } } async function create(input: { items: CatalogRequestItem[]; note?: string }) { const items = input.items .filter((i) => i.productId && i.quantity > 0) .map((i) => ({ ...i, quantity: Math.max(1, Math.floor(i.quantity)), })) if (!items.length) { return { success: false as const, message: 'حداقل یک قلم با تعداد معتبر لازم است.' } } if (useApi.value) { try { const row = await apiRequest<{ id: string createdAt: string status: string note?: string items: Array<{ productId: string productName: string productCode: string quantity: number }> }>('/catalog-requests', { method: 'POST', body: { note: input.note?.trim() || undefined, items: items.map((i) => ({ productId: i.productId, quantity: i.quantity, })), }, }) const mapped = mapServerRow(row) requests.value = [mapped, ...requests.value.filter((r) => r.id !== mapped.id)] writeAll(requests.value) return { success: true as const, request: mapped } } catch (err) { useApi.value = false // fall through to local } } const row: CatalogRequest = { id: `cr-${Date.now()}`, createdAt: new Date().toISOString(), status: 'submitted', note: input.note?.trim() || undefined, items, } requests.value = [row, ...requests.value] writeAll(requests.value) return { success: true as const, request: row } } function getById(id: string) { return requests.value.find((r) => r.id === id) ?? null } return { requests, sorted, statusLabel, create, getById, hydrate, } })