import crypto from 'node:crypto';
import { prisma } from './db';

export type TokenType = 'verify' | 'reset';
export const TOKEN_TTL_MS: Record<TokenType, number> = { verify: 48 * 3600_000, reset: 60 * 60_000 };
const hash = (t: string) => crypto.createHash('sha256').update(t).digest('hex');

/** Tek kullanımlık jeton üretir; veritabanında yalnızca SHA-256 özeti tutulur. Aynı türdeki eski jetonlar geçersizleşir. */
export async function issueToken(userId: string, type: TokenType) {
  const raw = crypto.randomBytes(32).toString('base64url');
  await prisma.$transaction([
    prisma.authToken.updateMany({ where: { userId, type, usedAt: null }, data: { usedAt: new Date() } }),
    prisma.authToken.create({ data: { userId, type, tokenHash: hash(raw), expiresAt: new Date(Date.now() + TOKEN_TTL_MS[type]) } }),
  ]);
  return raw;
}

/** Jetonu doğrular ve atomik olarak tüketir. Geçersiz/süresi dolmuş/kullanılmış ise null. */
export async function consumeToken(raw: string, type: TokenType) {
  if (!raw || raw.length < 20 || raw.length > 100) return null;
  const t = await prisma.authToken.findUnique({ where: { tokenHash: hash(raw) } });
  if (!t || t.type !== type || t.usedAt || t.expiresAt < new Date()) return null;
  const r = await prisma.authToken.updateMany({ where: { id: t.id, usedAt: null }, data: { usedAt: new Date() } });
  return r.count ? t.userId : null;
}

/** Jetonu tüketmeden kontrol eder (form gösterimi için). */
export async function peekToken(raw: string, type: TokenType) {
  if (!raw || raw.length < 20 || raw.length > 100) return false;
  const t = await prisma.authToken.findUnique({ where: { tokenHash: hash(raw) } });
  return !!t && t.type === type && !t.usedAt && t.expiresAt > new Date();
}
