import crypto from "crypto";
import { db } from "@/lib/db";

export const ACCESS_TOKEN_EXPIRES_IN = 15 * 60;
export const REFRESH_TOKEN_EXPIRES_IN = 30 * 24 * 60 * 60;

function addSeconds(seconds: number) {
  return new Date(Date.now() + seconds * 1000);
}

export function hashToken(token: string) {
  return crypto.createHash("sha256").update(token).digest("hex");
}

export function generateToken() {
  return crypto.randomBytes(48).toString("base64url");
}

export async function createMobileTokenPair(userId: string, refreshFamilyId?: string) {
  const accessToken = generateToken();
  const refreshToken = generateToken();
  const accessTokenExpiresAt = addSeconds(ACCESS_TOKEN_EXPIRES_IN);
  const refreshTokenExpiresAt = addSeconds(REFRESH_TOKEN_EXPIRES_IN);

  const session = await db.session.create({
    data: {
      sessionToken: accessToken,
      userId,
      expires: accessTokenExpiresAt,
    },
  });

  const refreshSession = await db.refreshToken.create({
    data: {
      tokenHash: hashToken(refreshToken),
      userId,
      familyId: refreshFamilyId ?? crypto.randomUUID(),
      expiresAt: refreshTokenExpiresAt,
    },
  });

  return {
    accessToken,
    accessTokenExpiresAt,
    refreshToken,
    refreshTokenExpiresAt,
    refreshTokenId: refreshSession.id,
    refreshFamilyId: refreshSession.familyId,
    sessionId: session.id,
  };
}

export async function revokeRefreshTokenFamily(userId: string, familyId: string) {
  await db.refreshToken.updateMany({
    where: {
      userId,
      familyId,
      revokedAt: null,
    },
    data: {
      revokedAt: new Date(),
    },
  });
}
