import { SignJWT, jwtVerify } from 'jose'
import { cookies } from 'next/headers'
import { prisma } from './db'
import bcrypt from 'bcryptjs'
import { JWT_SECRET } from './jwt-secret'

export interface UserPayload {
  id: string
  email: string
  name: string
  role: 'SERVER_ADMIN' | 'TENANT_ADMIN' | 'OPERATOR' | 'VIEWER'
  tenantId?: string
  tenantSlug?: string
  emailVerified?: boolean
}

// Zentrale Session-Laufzeiten (Sekunden) – EINE Quelle für Token-Ablauf UND Cookie-maxAge,
// damit beide nie auseinanderdriften.
export const SESSION_MAX_AGE_SECONDS = 60 * 60 * 24 // 24 Stunden (Standard)
export const SESSION_MAX_AGE_REMEMBER_SECONDS = 60 * 60 * 24 * 14 // 14 Tage ("angemeldet bleiben")

export async function createToken(user: UserPayload, rememberMe = false): Promise<string> {
  const maxAge = rememberMe ? SESSION_MAX_AGE_REMEMBER_SECONDS : SESSION_MAX_AGE_SECONDS
  return await new SignJWT({ user })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime(`${maxAge}s`)
    .sign(JWT_SECRET)
}

export async function verifyToken(token: string): Promise<UserPayload | null> {
  try {
    const { payload } = await jwtVerify(token, JWT_SECRET)
    return payload.user as UserPayload
  } catch {
    return null
  }
}

export async function getSession(): Promise<UserPayload | null> {
  const cookieStore = await cookies()
  const token = cookieStore.get('auth-token')?.value
  
  if (!token) return null
  
  return await verifyToken(token)
}

export async function login(
  email: string,
  password: string
): Promise<{ success: boolean; user?: UserPayload; error?: string }> {
  const user = await (prisma.user.findUnique({
    where: { email },
    select: {
      id: true,
      email: true,
      name: true,
      password: true,
      role: true,
      emailVerified: true,
      isActive: true,
    },
  }) as any)

  if (!user) {
    return { success: false, error: 'E-Mail oder Passwort falsch' }
  }

  const isValidPassword = await bcrypt.compare(password, user.password)
  if (!isValidPassword) {
    return { success: false, error: 'E-Mail oder Passwort falsch' }
  }

  // Gesperrte Benutzer dürfen sich nicht anmelden (isActive === false).
  // Tolerant: nur blockieren, wenn explizit false (alte Datensätze ohne Wert bleiben aktiv).
  if (user.isActive === false) {
    return { success: false, error: 'Ihr Konto wurde deaktiviert. Bitte kontaktieren Sie den Administrator.' }
  }

  // Track email verification status (allow login regardless)
  const emailVerified = (user as any).emailVerified !== false

  // Get first tenant membership for non-server-admins
  let tenantId: string | undefined
  let tenantSlug: string | undefined
  if ((user.role as string) !== 'SERVER_ADMIN') {
    const membership = await (prisma as any).tenantMembership.findFirst({
      where: { userId: user.id },
      include: { tenant: true },
      orderBy: { createdAt: 'asc' },
    })
    if (membership) {
      // Check if tenant is active
      if (!membership.tenant.isActive) {
        return { success: false, error: 'Ihr Mandant wurde gesperrt. Bitte kontaktieren Sie den Administrator.' }
      }
      tenantId = membership.tenantId
      tenantSlug = membership.tenant.slug
    }
  }

  const userPayload: UserPayload = {
    id: user.id,
    email: user.email,
    name: user.name,
    role: (user.role === 'ADMIN' ? 'SERVER_ADMIN' : user.role) as UserPayload['role'],
    tenantId,
    tenantSlug,
    emailVerified,
  }

  return { success: true, user: userPayload }
}

export async function hashPassword(password: string): Promise<string> {
  return await bcrypt.hash(password, 12)
}

export function canEdit(role: string): boolean {
  return role === 'SERVER_ADMIN' || role === 'TENANT_ADMIN' || role === 'OPERATOR'
}

export function isAdmin(role: string): boolean {
  return role === 'SERVER_ADMIN' || role === 'TENANT_ADMIN'
}

export function isServerAdmin(role: string): boolean {
  return role === 'SERVER_ADMIN'
}

export function isTenantAdmin(role: string): boolean {
  return role === 'TENANT_ADMIN'
}
