import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import crypto from "node:crypto";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";

const SESSION_COOKIE = "food_tracker_session";

function getAuthSecret() {
  return process.env.AUTH_SECRET ?? "development-auth-secret";
}

function signValue(value: string) {
  return crypto.createHmac("sha256", getAuthSecret()).update(value).digest("hex");
}

function encodeSession(userId: number) {
  const value = String(userId);
  return `${value}.${signValue(value)}`;
}

function decodeSession(raw: string | undefined) {
  if (!raw) {
    return null;
  }

  const [value, signature] = raw.split(".");

  if (!value || !signature || signValue(value) !== signature) {
    return null;
  }

  const userId = Number(value);
  return Number.isInteger(userId) ? userId : null;
}

export async function loginUser(email: string, password: string) {
  const user = await prisma.user.findUnique({
    where: { email }
  });

  if (!user) {
    return null;
  }

  const isValid = await bcrypt.compare(password, user.password);

  if (!isValid) {
    return null;
  }

  const cookieStore = await cookies();
  cookieStore.set(SESSION_COOKIE, encodeSession(user.id), {
    httpOnly: true,
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
    path: "/",
    maxAge: 60 * 60 * 24 * 30
  });

  return user;
}

export async function logoutUser() {
  const cookieStore = await cookies();
  cookieStore.delete(SESSION_COOKIE);
}

export async function getCurrentUser() {
  const cookieStore = await cookies();
  const raw = cookieStore.get(SESSION_COOKIE)?.value;
  const userId = decodeSession(raw);

  if (!userId) {
    return null;
  }

  return prisma.user.findUnique({
    where: { id: userId }
  });
}

export async function requireUser() {
  const user = await getCurrentUser();

  if (!user) {
    redirect("/login");
  }

  return user;
}
