import crypto from 'node:crypto'
import { prisma } from './prisma.js'
import { sendLoginCodeEmail } from './email.js'

export function normalizeEmail(email) {
  return String(email || '').trim().toLowerCase()
}

export function randomCode6() {
  return String(Math.floor(100000 + Math.random() * 900000))
}

export function sha256(input) {
  return crypto.createHash('sha256').update(input).digest('hex')
}

export async function issueEmailCode({ email, purpose, userId = null }) {
  const code = randomCode6()
  const expiresAt = new Date(Date.now() + 10 * 60 * 1000)
  await prisma.authCode.create({
    data: {
      email,
      purpose,
      userId,
      codeHash: sha256(`${email}:${purpose}:${code}:${userId ?? ''}`),
      expiresAt,
    },
  })
  await sendLoginCodeEmail({ to: email, code })
}

function parseEnvBool(raw) {
  const v = String(raw ?? '').trim().toLowerCase()
  return v === 'true' || v === '1' || v === 'yes'
}

/** Тестовые стенды: принять код из переменной DEFAULT_CODE без записи в БД. */
export function isDefaultLoginCodeAccepted(codeInput) {
  if (!parseEnvBool(process.env.IS_DEFAULT_CODE_ENABLED)) return false
  const expected = String(process.env.DEFAULT_CODE ?? '').trim()
  if (!expected || expected.length < 4) return false
  return String(codeInput ?? '').trim() === expected
}

export async function verifyEmailCode({ email, purpose, code, userId = null }) {
  if (purpose === 'login' && isDefaultLoginCodeAccepted(code)) return true

  const now = new Date()
  const codeHash = sha256(`${email}:${purpose}:${code}:${userId ?? ''}`)

  const found = await prisma.authCode.findFirst({
    where: {
      email,
      purpose,
      userId,
      codeHash,
      usedAt: null,
      expiresAt: { gt: now },
    },
    orderBy: { createdAt: 'desc' },
  })
  if (!found) return false

  await prisma.authCode.update({
    where: { id: found.id },
    data: { usedAt: now },
  })
  return true
}


