import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import { prisma } from '@/lib/db'

export async function createUser(email: string, password: string, name?: string) {
  const passwordHash = await bcrypt.hash(password, 10)
  return prisma.user.create({
    data: { email, passwordHash, name }
  })
}

export async function validateUser(email: string, password: string) {
  const user = await prisma.user.findUnique({ where: { email } })
  if (!user) return null

  const isValid = await bcrypt.compare(password, user.passwordHash)
  return isValid ? user : null
}

export function generateToken(userId: string): string {
  return jwt.sign({ userId }, process.env.JWT_SECRET!, { expiresIn: '7d' })
}

export async function verifyToken(token: string) {
  try {
    console.log('Server: Verifying token with JWT_SECRET exists:', !!process.env.JWT_SECRET)
    const payload = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string }
    console.log('Server: Token verification successful, userId:', payload.userId)
    return payload
  } catch (error) {
    console.log('Server: Token verification failed:', (error as any)?.message || error)
    throw new Error('Invalid token')
  }
}

export async function getUserFromToken(token: string) {
  try {
    console.log('Server: Getting user from token...')
    const payload = await verifyToken(token)
    console.log('Server: Token payload userId:', payload.userId)

    // Use raw query to avoid Prisma client sync issues
    const users = await prisma.$queryRaw`
      SELECT id, email, name, role, theme, "fontSize", "createdAt", "updatedAt", "lastLoginAt"
      FROM "User"
      WHERE id = ${payload.userId}
    `
    const user = Array.isArray(users) && users.length > 0 ? users[0] : null
    console.log('Server: User query result:', !!user)
    if (user) {
      console.log('Server: User found - email:', user.email)
    } else {
      console.log('Server: No user found with id:', payload.userId)
    }
    return user
  } catch (error) {
    console.log('Server: getUserFromToken error:', (error as any)?.message || error)
    return null
  }
}

export function isTokenExpired(token: string): boolean {
  try {
    const payload = jwt.decode(token) as { exp?: number }
    if (!payload || !payload.exp) return true

    const currentTime = Math.floor(Date.now() / 1000)
    return payload.exp < currentTime
  } catch (error) {
    return true
  }
}
