/**
 * قیمت‌گذاری سبد خرید: جمع اقلام، کد تخفیف، هزینه ارسال و مبلغ نهایی.
 * همه مبالغ، کدهای تخفیف و روش‌های ارسال از دیتابیس خوانده می‌شوند.
 */
import "server-only";
import { db } from "@/lib/db";
import { faNumber } from "@/lib/format";
import { getVariantsForCart } from "./catalog";
import { getShippingSettings } from "./settings";
import type { ProductSummary, ProductVariant } from "@/types/catalog";

export interface PricedLine {
  variantId: string;
  qty: number;
  product: ProductSummary;
  variant: ProductVariant;
  lineTotal: number;
  /** اگر تعداد درخواستی بیش از موجودی باشد، این مقدار کمتر از qty است */
  availableQty: number;
}

export interface CartPricing {
  lines: PricedLine[];
  subtotal: number;
  discount: number;
  discountLabel?: string;
  discountError?: string;
  shipping: { methodId: string; name: string; price: number; free: boolean; eta: string }[];
  shippingCost: number;
  freeShippingThreshold: number;
  remainingForFreeShipping: number;
  total: number;
}

/** بررسی اعتبار کد تخفیف و محاسبه مبلغ آن */
async function evaluateDiscount(code: string, subtotal: number) {
  const d = await db.discountCode.findUnique({ where: { code: code.toUpperCase() } });
  const now = new Date();
  if (!d || !d.isActive || (d.startsAt && d.startsAt > now) || (d.endsAt && d.endsAt < now)) return { error: "کد تخفیف معتبر نیست" };
  if (d.usageLimit !== null && d.usedCount >= d.usageLimit) return { error: "ظرفیت استفاده از این کد تمام شده است" };
  if (subtotal < d.minSubtotal) return { error: `این کد برای خریدهای بالای ${faNumber(d.minSubtotal)} تومان است` };
  let amount = d.type === "PERCENT" ? Math.round((subtotal * d.value) / 100) : d.value;
  if (d.maxAmount) amount = Math.min(amount, d.maxAmount);
  return { amount: Math.min(amount, subtotal), label: d.label };
}

export async function priceCart(input: {
  lines: { variantId: string; qty: number }[];
  discountCode?: string;
  shippingMethodId?: string;
  province?: string;
}): Promise<CartPricing> {
  const [found, settings] = await Promise.all([getVariantsForCart(input.lines.map((l) => l.variantId)), getShippingSettings()]);
  const lines: PricedLine[] = input.lines.flatMap((l) => {
    const match = found.find((f) => f.variant.id === l.variantId);
    if (!match) return [];
    const availableQty = Math.min(l.qty, match.variant.stock);
    return [{ ...match, variantId: l.variantId, qty: l.qty, availableQty, lineTotal: availableQty * match.variant.price }];
  });
  const subtotal = lines.reduce((s, l) => s + l.lineTotal, 0);

  let discount = 0;
  let discountLabel: string | undefined;
  let discountError: string | undefined;
  if (input.discountCode) {
    const r = await evaluateDiscount(input.discountCode, subtotal);
    if ("error" in r) discountError = r.error;
    else ({ amount: discount, label: discountLabel } = r);
  }

  // ارسال رایگان بر اساس مبلغ پس از تخفیف
  const afterDiscount = subtotal - discount;
  const free = afterDiscount >= settings.freeShippingThreshold;
  const isTehran = input.province === "تهران";
  const shipping = settings.methods
    .filter((m) => !m.tehranOnly || isTehran || !input.province)
    .map((m) => ({ methodId: m.id, name: m.name, price: free ? 0 : m.price, free, eta: m.eta }));
  const shippingCost = shipping.find((m) => m.methodId === input.shippingMethodId)?.price ?? 0;

  return {
    lines,
    subtotal,
    discount,
    discountLabel,
    discountError,
    shipping,
    shippingCost,
    freeShippingThreshold: settings.freeShippingThreshold,
    remainingForFreeShipping: Math.max(0, settings.freeShippingThreshold - afterDiscount),
    total: afterDiscount + shippingCost,
  };
}
