"use server";

/**
 * تنظیمات نرخ دلار (بخش «نرخ دلار» پنل): بروزرسانی دستی، نرخ دستی، فاصله بروزرسانی، حاشیه سود و گرد کردن.
 * Server Actionها در Next.js بررسی مبدأ (Origin) دارند، پس در برابر CSRF محافظت‌شده‌اند؛ دسترسی هم جداگانه بررسی می‌شود.
 */
import { z } from "zod";
import { toLatinDigits } from "@/lib/persian";
import { getCurrencySettings, refreshRate, repriceOriginal, saveCurrencySettings, type RefreshResult } from "@/server/services/currency";
import { refreshStorefront } from "./cache";
import { requireStaff } from "./guard";

const num = (min: number, max: number) =>
  z.preprocess((v) => (typeof v === "string" ? Number(toLatinDigits(v).replace(/[,٬\s]/g, "")) : v), z.number().finite().min(min).max(max));

const settingsSchema = z.object({
  useManual: z.boolean(),
  manualRate: z.preprocess((v) => (v === "" || v == null ? null : v), num(10_000, 10_000_000).nullable()),
  intervalMinutes: num(10, 60).pipe(z.number().int()),
  marginPercent: num(0, 100),
  roundTo: z.coerce.number().pipe(z.union([z.literal(1), z.literal(100), z.literal(1000), z.literal(10000)])),
  roundMode: z.enum(["nearest", "up", "down"]),
});

export type CurrencySettingsInput = z.input<typeof settingsSchema>;

export async function saveCurrencySettingsAction(input: CurrencySettingsInput): Promise<{ ok: true; repriced: number } | { ok: false; error: string }> {
  await requireStaff("currency");
  const parsed = settingsSchema.safeParse(input);
  if (!parsed.success) {
    const i = parsed.error.issues[0];
    const field = { manualRate: "نرخ دستی", intervalMinutes: "فاصله بروزرسانی", marginPercent: "حاشیه سود", roundTo: "گرد کردن" }[String(i.path[0])] ?? "";
    return { ok: false, error: `${field} نامعتبر است` };
  }
  if (parsed.data.useManual && !parsed.data.manualRate) return { ok: false, error: "برای استفاده از نرخ دستی، نرخ را وارد کنید" };
  const next = { ...(await getCurrencySettings()), ...parsed.data };
  await saveCurrencySettings(next);
  const repriced = await repriceOriginal(next);
  refreshStorefront();
  return { ok: true, repriced };
}

/** دکمه «بروزرسانی دستی نرخ»؛ allowJump فقط وقتی مدیر تغییر بیش از ۲۰٪ را تأیید کند */
export async function refreshRateAction(allowJump = false): Promise<RefreshResult> {
  await requireStaff("currency");
  const result = await refreshRate({ allowJump: allowJump === true });
  if (result.ok) {
    // حتی اگر نرخ تغییر نکرده، برای اطمینان قیمت‌ها با تنظیمات فعلی هماهنگ می‌شوند
    await repriceOriginal();
    refreshStorefront();
  }
  return result;
}
