import { create } from 'zustand' import { ItemPriceResponse, OrderItemPriceResponse, OrderFilledResponse } from '../client/response' import * as ItemController from '../client/controllers/ItemController' import { CreateItemQuery } from '../client/queries/CreateItemQuery' import { SetItemPriceQuery } from '../client/queries/SetItemPriceQuery' import { blob } from 'stream/consumers' export type ItemData = { items: ItemPriceResponse[], orderItems: OrderItemPriceResponse[] } export type ItemActions = { sync: () => Promise createItem: (itemName: string, inSeason: boolean, itemPrice: number) => Promise setItemPrice: (itemId: number, price: number) => Promise getCurrentPrice: (itemId: number) => Promise addItemToOrder: (itemId: number, orderId: number, quantity: number) => Promise getOrderItems: (orderId: number) => Promise setItemMade: (orderId: number, itemId: number, made: number) => Promise setItemQuantity: (orderId: number, itemId: number, quantity: number) => Promise deleteOrderItem: (orderId: number, itemId: number) => Promise deleteItem: (itemId: number) => Promise } export const useItemStore = create((set, get) => ({ items: [], orderItems: [], sync: async (): Promise => { const itemPrices = await ItemController.GetItems() set((state) => ({ ...state, items: itemPrices })) }, createItem: async (itemName: string, inSeason: boolean, itemPrice: number): Promise => { const itemQuery: CreateItemQuery = { item_name: itemName, in_season: inSeason ? "1" : "0", item_price: itemPrice.toString() } const itemResponse = await ItemController.CreateItem(itemQuery) set((state) => ({ ...state, items: [...state.items, itemResponse] })) return itemResponse }, setItemPrice: async (itemId: number, price: number): Promise => { const itemPriceQuery: SetItemPriceQuery = { item_id: itemId.toString(), item_price: price.toString() } await ItemController.SetItemPrice(itemPriceQuery) set((state) => { const item = state.items.filter((i) => i.ItemId === itemId)[0] let itemsWithoutItem = state.items.filter((i) => i.ItemId !== itemId) item.ItemPrice = price if(!Array.isArray(itemsWithoutItem)) itemsWithoutItem = [itemsWithoutItem] return { ...state, items: [...itemsWithoutItem, item].sort((a,b) => { if(a.InSeason && !b.InSeason) return 1 if(!a.InSeason && b.InSeason) return -1 return a.ItemId - b.ItemId }) } }) }, getCurrentPrice: async (itemId: number): Promise => { const store = get() const priceObjectArray = store.items.filter((i: ItemPriceResponse) => i.ItemId === itemId) if(priceObjectArray.length > 0) { return priceObjectArray[0] } const resp = await ItemController.GetCurrentPrice({item_id: itemId.toString()}) set((state) => ({ ...state, items: [...state.items, resp] })) return resp }, addItemToOrder: async (itemId: number, orderId: number, quantity: number): Promise => { const resp = await ItemController.AddItemToOrder({item_id: itemId.toString(), order_id: orderId.toString(), quantity: quantity.toString()}) set((state) => ({ ...state, orderItems: [...state.orderItems, resp] })) return resp }, getOrderItems: async (orderId: number): Promise => { const state = get() const fetchedOrderItems = state.orderItems const orderOrderItems = fetchedOrderItems.filter((i) => i.OrderId === orderId) if(orderOrderItems.length > 0) { return orderOrderItems } const resp = await ItemController.GetOrderItems({order_id: orderId.toString()}) set((state) => ({ orderItems: [...state.orderItems, ...resp] })) return resp }, setItemMade: async (orderId: number, itemId: number, made: number): Promise => { const order_filled: OrderFilledResponse = await ItemController.SetItemMade({ order_id: orderId, item_id: itemId, made: made }) set((state) => { // TODO: Update order filled once order store is made const orderItem = state.orderItems.filter((oi) => oi.ItemId === itemId && oi.OrderId === orderId)[0] const orderItemsWithoutOrderItem = state.orderItems.filter((oi) => oi.ItemId !== itemId || oi.OrderId !== orderId) orderItem.Made = made return { ...state, orderItems: [...orderItemsWithoutOrderItem, orderItem] } }) return order_filled }, setItemQuantity: async (orderId: number, itemId: number, quantity: number): Promise => { const order_filled: OrderFilledResponse = await ItemController.SetItemQuantity({ order_id: orderId, item_id: itemId, quantity: quantity }) set((state) => { // TODO: Update order filled once order store is made const orderItem = state.orderItems.filter((oi) => oi.ItemId === itemId && oi.OrderId === orderId)[0] const orderItemsWithoutOrderItem = state.orderItems.filter((oi) => oi.ItemId !== itemId || oi.OrderId !== orderId) orderItem.Quantity = quantity return { ...state, orderItems: [...orderItemsWithoutOrderItem, orderItem] } }) return order_filled }, deleteOrderItem: async (orderId: number, itemId: number): Promise => { await ItemController.DeleteOrderItem({order_id: orderId, item_id: itemId}) set((state) => ({ ...state, orderItems: [...(state.orderItems.filter((i) => i.OrderId !== orderId || i.ItemId !== itemId))] })) }, deleteItem: async (itemId: number): Promise => { await ItemController.DeleteItem(itemId) set((state) => { const itemsWithoutItem = state.items.filter((i) => i.ItemId !== itemId) const orderItemsWithoutItem = state.orderItems.filter((i) => i.ItemId !== itemId) return { ...state, items: itemsWithoutItem, orderItems: orderItemsWithoutItem } }) } }))