"use server";

/** نظرات، کدهای تخفیف و تنظیمات ارسال */
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { z } from "zod";
import { db } from "@/lib/db";
import { toLatinDigits } from "@/lib/persian";
import { refreshStorefront } from "./cache";
import { requireStaff } from "./guard";

const num = (max = 1_000_000_000) => z.preprocess((v) => (v === "" || v == null ? undefined : Number(toLatinDigits(String(v)).replace(/[^\d]/g, ""))), z.number().int().min(0).max(max));
const optNum = (max?: number) => z.preprocess((v) => (v === "" || v == null ? undefined : v), num(max).optional());

// ── نظرات ─────────────────────────────────────────────

/** میانگین امتیاز و تعداد نظرات تأییدشده محصول دوباره محاسبه می‌شود */
async function recomputeRating(productId: number) {
  const agg = await db.review.aggregate({ where: { productId, status: "APPROVED" }, _avg: { rating: true }, _count: { _all: true } });
  await db.product.update({
    where: { id: productId },
    data: { ratingAvg: Math.round((agg._avg.rating ?? 0) * 10) / 10, reviewCount: agg._count._all },
  });
}

export async function moderateReviewAction(formData: FormData) {
  await requireStaff("reviews");
  const { id, decision } = z.object({ id: z.string().min(1).max(40), decision: z.enum(["APPROVED", "REJECTED", "DELETE"]) }).parse({
    id: formData.get("id"),
    decision: formData.get("decision"),
  });
  const review = await db.review.findUniqueOrThrow({ where: { id }, select: { productId: true } });
  if (decision === "DELETE") await db.review.delete({ where: { id } });
  else await db.review.update({ where: { id }, data: { status: decision } });
  await recomputeRating(review.productId);
  refreshStorefront();
  revalidatePath("/admin/reviews");
}

// ── کدهای تخفیف ───────────────────────────────────────

const discountSchema = z
  .object({
    code: z.string().trim().toUpperCase().regex(/^[A-Z0-9]{3,20}$/, "کد فقط حروف لاتین و عدد (۳ تا ۲۰ کاراکتر)"),
    label: z.string().trim().min(3, "توضیح کوتاه لازم است").max(80),
    type: z.enum(["PERCENT", "FIXED"]),
    value: num().refine((n) => n > 0, "مقدار تخفیف لازم است"),
    minSubtotal: num(),
    maxAmount: optNum(),
    usageLimit: optNum(1_000_000),
    endsAt: z.preprocess((v) => (v ? v : undefined), z.coerce.date().optional()),
  })
  .refine((d) => d.type !== "PERCENT" || d.value <= 100, { message: "درصد تخفیف حداکثر ۱۰۰ است", path: ["value"] });

export async function createDiscountAction(formData: FormData) {
  await requireStaff("discounts");
  const parsed = discountSchema.safeParse(Object.fromEntries(formData));
  if (!parsed.success) redirect(`/admin/discounts?error=${encodeURIComponent(parsed.error.issues[0].message)}`);
  const exists = await db.discountCode.findUnique({ where: { code: parsed.data.code } });
  if (exists) redirect(`/admin/discounts?error=${encodeURIComponent("این کد قبلاً ثبت شده است")}`);
  await db.discountCode.create({ data: parsed.data });
  revalidatePath("/admin/discounts");
  redirect("/admin/discounts?saved=1");
}

export async function toggleDiscountAction(formData: FormData) {
  await requireStaff("discounts");
  const id = z.string().min(1).max(40).parse(formData.get("id"));
  const d = await db.discountCode.findUniqueOrThrow({ where: { id }, select: { isActive: true } });
  await db.discountCode.update({ where: { id }, data: { isActive: !d.isActive } });
  revalidatePath("/admin/discounts");
}

// ── تنظیمات ارسال ─────────────────────────────────────

export async function saveShippingAction(formData: FormData) {
  await requireStaff("shipping");
  const threshold = num().parse(formData.get("freeShippingThreshold"));
  const methods = await db.shippingMethod.findMany({ select: { id: true } });
  await db.$transaction([
    db.setting.upsert({ where: { key: "freeShippingThreshold" }, create: { key: "freeShippingThreshold", value: threshold }, update: { value: threshold } }),
    ...methods.map((m) =>
      db.shippingMethod.update({
        where: { id: m.id },
        data: {
          price: num().parse(formData.get(`price_${m.id}`)),
          eta: z.string().trim().min(2).max(60).parse(formData.get(`eta_${m.id}`)),
          isActive: formData.get(`active_${m.id}`) === "on",
        },
      }),
    ),
  ]);
  refreshStorefront();
  redirect("/admin/settings?saved=1");
}
