import prisma from "../prismaClient";
import { randomBytes, createHash } from "crypto";

const APP_BASE_URL = process.env.APP_BASE_URL || "http://localhost:5000";
const RESET_TOKEN_TTL = Number(process.env.RESET_TOKEN_TTL || 3600);

export const generateRawToken = (bytes = 32) => {
  return randomBytes(bytes).toString("hex");
};

export const hashToken = (raw: string) => {
  return createHash("sha256").update(raw).digest("hex");
};

export const createPasswordResetToken = async (userId: string) => {
  const rawToken = generateRawToken();
  const tokenHash = hashToken(rawToken);
  const expiresAt = new Date(Date.now() + RESET_TOKEN_TTL * 1000);

  // Ensure single active token per user (optional)
  await prisma.passwordResetToken.deleteMany({ where: { userId } });

  await prisma.passwordResetToken.create({
    data: {
      userId,
      tokenHash,
      expiresAt,
    },
  });

  const link = `${APP_BASE_URL.replace(
    /\/$/,
    "",
  )}/reset-password?token=${rawToken}`;
  return { rawToken, link, expiresAt };
};

export const consumePasswordResetToken = async (rawToken: string) => {
  const tokenHash = hashToken(rawToken);
  const rec = await prisma.passwordResetToken.findUnique({
    where: { tokenHash },
  });
  if (!rec) return null;
  if (rec.usedAt) return null;
  if (rec.expiresAt.getTime() < Date.now()) return null;
  return rec; // Caller should mark used
};

export const markTokenUsed = async (tokenHash: string) => {
  await prisma.passwordResetToken.update({
    where: { tokenHash },
    data: { usedAt: new Date() },
  });
};
