/**
 * کنترل دسترسی پنل مدیریت.
 * - فقط نشستی که با «شماره + رمز» در صفحه ورود پنل ساخته شده به پنل راه دارد (ورود پیامکی فروشگاه کافی نیست)
 * - هر عضو تیم فقط به بخش‌هایی که مدیر عامل داده دسترسی دارد؛ مدیر عامل (OWNER) به همه بخش‌ها
 * هر صفحه و هر Server Action جداگانه بررسی می‌شود (بررسی فقط در layout کافی نیست چون Actionها مستقیماً قابل فراخوانی‌اند).
 */
import "server-only";
import { redirect } from "next/navigation";
import { getCurrentUser } from "@/server/auth/session";
import { SECTION_KEYS, type AdminSection } from "@/lib/admin-sections";

type CurrentUser = NonNullable<Awaited<ReturnType<typeof getCurrentUser>>>;

export const isStaffRole = (role: string) => role === "OWNER" || role === "ADMIN" || role === "STAFF";

/** بخش‌هایی که کاربر به آن‌ها دسترسی دارد */
export function allowedSections(user: Pick<CurrentUser, "role" | "permissions">): AdminSection[] {
  if (user.role === "OWNER") return [...SECTION_KEYS, "team"];
  if (!isStaffRole(user.role)) return [];
  return user.permissions.filter((p): p is AdminSection => (SECTION_KEYS as string[]).includes(p));
}

function canAccess(user: CurrentUser, section?: AdminSection | AdminSection[]) {
  if (!user.adminAuth || !isStaffRole(user.role)) return false;
  if (!section) return true;
  const allowed = allowedSections(user);
  return (Array.isArray(section) ? section : [section]).some((s) => allowed.includes(s));
}

/** برای صفحات: کاربر بدون ورود پنل به صفحه ورود پنل، و کاربر بدون دسترسی به داشبورد هدایت می‌شود */
export async function requireStaffPage(path: string, section?: AdminSection | AdminSection[]) {
  const user = await getCurrentUser();
  if (!user || !user.adminAuth || !isStaffRole(user.role)) redirect(`/admin/login?next=${encodeURIComponent(path)}`);
  if (!canAccess(user, section)) redirect("/admin?denied=1");
  return user;
}

/** برای Server Actionها: در صورت عدم دسترسی خطا پرتاب می‌شود */
export async function requireStaff(section?: AdminSection | AdminSection[]) {
  const user = await getCurrentUser();
  if (!user || !canAccess(user, section)) throw new Error("دسترسی غیرمجاز");
  return user;
}
