/**
 * نشست کاربر با کوکی httpOnly.
 * کوکی فقط یک توکن تصادفی است؛ در دیتابیس فقط هش آن ذخیره می‌شود تا با نشت دیتابیس نشست‌ها قابل استفاده نباشند.
 */
import "server-only";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { cache } from "react";
import { db } from "@/lib/db";
import { randomToken, sha256 } from "@/lib/crypto";

const COOKIE = "zh_session";
const MAX_AGE_DAYS = 30;

/** adminAuth: نشست ساخته‌شده با شماره و رمز در صفحه ورود پنل (فقط این نشست به پنل مدیریت راه دارد) */
export async function createSession(userId: string, opts: { adminAuth?: boolean } = {}) {
  const token = randomToken();
  // نشست پنل مدیریت کوتاه‌تر است (۱۲ ساعت)
  const expiresAt = new Date(Date.now() + (opts.adminAuth ? 12 * 3_600_000 : MAX_AGE_DAYS * 86_400_000));
  await db.session.create({ data: { tokenHash: sha256(token), userId, expiresAt, adminAuth: !!opts.adminAuth } });
  (await cookies()).set(COOKIE, token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    path: "/",
    expires: expiresAt,
  });
}

/** کاربر جاری (در هر درخواست یک بار از دیتابیس خوانده می‌شود) */
export const getCurrentUser = cache(async () => {
  const token = (await cookies()).get(COOKIE)?.value;
  if (!token) return null;
  const session = await db.session.findUnique({
    where: { tokenHash: sha256(token) },
    include: { user: { select: { id: true, phone: true, name: true, role: true, permissions: true } } },
  });
  if (!session || session.expiresAt < new Date()) return null;
  return { ...session.user, adminAuth: session.adminAuth };
});

export async function destroySession() {
  const jar = await cookies();
  const token = jar.get(COOKIE)?.value;
  if (token) await db.session.deleteMany({ where: { tokenHash: sha256(token) } });
  jar.delete(COOKIE);
}

/** برای صفحات نیازمند ورود: اگر کاربر وارد نشده، به صفحه ورود با مسیر بازگشت هدایت می‌شود */
export async function requireUser(nextPath: string) {
  const user = await getCurrentUser();
  if (!user) redirect(`/auth?next=${encodeURIComponent(nextPath)}`);
  return user;
}
