import "server-only";
import { cookies } from "next/headers";
import { db } from "./db";
import { productCardInclude, variantAvailability } from "./catalog";
import { getCurrentUser } from "./auth";

const CART = "vl_cart";
export const MAX_QTY_PER_LINE = 10;

export async function cartId(create = false): Promise<string | null> {
  const jar = await cookies();
  const existing = jar.get(CART)?.value;
  if (existing) {
    const found = await db.cart.findUnique({ where: { id: existing }, select: { id: true } });
    if (found) return found.id;
  }
  if (!create) return null;
  const user = await getCurrentUser();
  const cart = await db.cart.create({ data: { userId: user?.id ?? null } });
  jar.set(CART, cart.id, { httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", path: "/", maxAge: 60 * 60 * 24 * 30 });
  return cart.id;
}

export async function clearCartCookie() {
  (await cookies()).delete(CART);
}

export async function loadCart() {
  const id = await cartId(false);
  if (!id) return { id: null, lines: [], count: 0, subtotal: 0 };
  const items = await db.cartItem.findMany({
    where: { cartId: id },
    include: { variant: { include: { batch: true, images: true, product: { include: productCardInclude } } } },
    orderBy: { id: "asc" },
  });
  const now = new Date();
  const lines = items
    .filter((i) => i.variant.product.status === "PUBLISHED" && i.variant.active)
    .map((i) => {
      const v = i.variant;
      const p = v.product;
      const unitPrice = v.price ?? p.basePrice;
      const avail = variantAvailability({ ...v, batch: v.batch }, now);
      const img =
        p.images.find((im) => im.variantId === v.id) ??
        p.images.find((im) => im.color && im.color === v.color) ??
        p.images[0];
      // Limit quantity by what is actually left
      let maxQty = MAX_QTY_PER_LINE;
      if (v.mode === "READY_STOCK") maxQty = Math.min(maxQty, v.stockQty);
      if (v.mode === "PRE_ORDER" && v.batch) maxQty = Math.min(maxQty, Math.max(0, v.batch.capacity - v.batch.heldQty - v.batch.committedQty));
      return {
        itemId: i.id,
        variantId: v.id,
        productId: p.id,
        slug: p.slug,
        name: p.name,
        variantLabel: [v.color, v.size].filter(Boolean).join(" / "),
        sku: v.sku,
        image: img?.url ?? null,
        imageAlt: img?.alt ?? p.name,
        unitPrice,
        qty: i.qty,
        maxQty,
        lineTotal: unitPrice * i.qty,
        mode: v.mode,
        availability: avail,
        batch: v.batch,
        categorySlug: p.category.slug,
        problem: !avail.purchasable ? `${avail.label}. Remove this item to continue.` : i.qty > maxQty ? `Only ${maxQty} available. Reduce the quantity to continue.` : null,
      };
    });
  return { id, lines, count: lines.reduce((s, l) => s + l.qty, 0), subtotal: lines.reduce((s, l) => s + l.lineTotal, 0) };
}

export type LoadedCart = Awaited<ReturnType<typeof loadCart>>;
export type CartLine = LoadedCart["lines"][number];
