import { SignJWT, jwtVerify } from 'jose'
import { cookies } from 'next/headers'
import { prisma } from './db'
import type { Role, User } from '@prisma/client'

const JWT_SECRET = new TextEncoder().encode(
  process.env.JWT_SECRET || 'skg-ucp-secret-key-change-in-production'
)

export interface SessionPayload {
  userId: string
  discordId: string
  username: string
  role: Role
  exp?: number
}

export async function createSession(user: User): Promise<string> {
  const payload: SessionPayload = {
    userId: user.id,
    discordId: user.discordId,
    username: user.username,
    role: user.role,
  }

  const token = await new SignJWT(payload as unknown as Record<string, unknown>)
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('7d')
    .sign(JWT_SECRET)

  return token
}

export async function verifySession(token: string): Promise<SessionPayload | null> {
  try {
    const { payload } = await jwtVerify(token, JWT_SECRET)
    return payload as unknown as SessionPayload
  } catch {
    return null
  }
}

export async function getSession(): Promise<SessionPayload | null> {
  const cookieStore = await cookies()
  const token = cookieStore.get('session')?.value

  if (!token) return null

  return verifySession(token)
}

export async function getCurrentUser() {
  try {
    const session = await getSession()
    if (!session) {
      console.log('[Auth] No session found')
      return null
    }

    console.log('[Auth] Session found for user:', session.userId)

    const user = await prisma.user.findUnique({
      where: { id: session.userId },
      include: {
        discordAccount: true,
      },
    })

    if (!user) {
      console.log('[Auth] User not found in database:', session.userId)
      return null
    }

    console.log('[Auth] User found:', user.username)
    return user
  } catch (error) {
    console.error('[Auth] Error getting current user:', error)
    return null
  }
}

export async function requireAuth() {
  const user = await getCurrentUser()
  if (!user) {
    throw new Error('Unauthorized')
  }
  return user
}

export async function requireRole(roles: Role[]) {
  const user = await requireAuth()
  if (!roles.includes(user.role)) {
    throw new Error('Forbidden')
  }
  return user
}

export async function requireAdmin() {
  return requireRole(['ADMIN', 'SUPERADMIN'])
}

export async function requireSuperAdmin() {
  return requireRole(['SUPERADMIN'])
}

export function isAdmin(role: Role): boolean {
  return role === 'ADMIN' || role === 'SUPERADMIN'
}

export function isSuperAdmin(role: Role): boolean {
  return role === 'SUPERADMIN'
}
