import { and, eq, inArray, isNull } from "drizzle-orm";
import { siteConfig } from "@/config/site";
import { db } from "@/db";
import { menuItems, menuItemSbisLinks, menuItemVariants, sbisCatalogItems } from "@/db/schema";
import { syncSbisCatalog } from "@/lib/sbis-catalog-sync";
import type { CartItem } from "@/lib/types";

export async function calculateDatabaseCart(items: CartItem[], method: "delivery" | "pickup") {
  if (!db) throw new Error("Database is not configured");
  await syncSbisCatalog();
  const ids = items.map((item) => Number(item.dishId)).filter(Number.isInteger);
  const rows = ids.length ? await db.select({ item: menuItems, variant: menuItemVariants, link: menuItemSbisLinks }).from(menuItems).innerJoin(menuItemVariants, eq(menuItemVariants.itemId, menuItems.id)).innerJoin(menuItemSbisLinks, and(eq(menuItemSbisLinks.menuItemId, menuItems.id), isNull(menuItemSbisLinks.unlinkedAt))).where(and(inArray(menuItems.id, ids), eq(menuItemVariants.isAvailable, true))) : [];
  const sbisRows = ids.length ? await db.select().from(sbisCatalogItems) : [];
  const sbisById = new Map(sbisRows.map((row) => [row.sbisId, row]));
  const byItem = new Map(rows.map((row) => [String(row.item.id), row]));
  const lines = items.map((requested) => { const row = byItem.get(requested.dishId); if (!row) return { requested, unavailable: true, reason: "Позиция или вариант недоступны" }; const sbis = sbisById.get(row.link.sbisId); const stockExceeded = sbis?.stockLeft !== null && sbis?.stockLeft !== undefined && requested.quantity > sbis.stockLeft; const forbidden = row.item.isAlcohol || !row.item.isAvailable || !row.item.allowOnlineOrder || !sbis || !sbis.inCurrentPrice || (method === "delivery" && !row.item.allowDelivery) || stockExceeded; return { requested, item: row.item, variant: row.variant, sbisId: row.link.sbisId, unavailable: forbidden, reason: forbidden ? (stockExceeded ? sbis?.unavailableText || "Недостаточно товара в наличии" : "Позиция недоступна для выбранного способа получения") : null, lineTotal: sbis ? sbis.priceKopecks * requested.quantity : row.variant.priceKopecks * requested.quantity }; });
  const invalid = lines.some((line) => line.unavailable || line.requested.quantity < 1);
  const subtotalKopecks = lines.reduce((sum, line) => sum + (line.lineTotal || 0), 0);
  const subtotal = subtotalKopecks / 100;
  const delivery = method === "delivery" && subtotal > 0 && subtotal < siteConfig.order.freeDeliveryFrom ? siteConfig.order.deliveryPrice : 0;
  return { lines, invalid, subtotal, delivery, total: subtotal + delivery, belowMinimum: subtotal > 0 && subtotal < siteConfig.order.minimumAmount };
}
