import bcrypt from "bcrypt"
import { cookies } from "next/headers"
import {
  createSession,
  deleteSession,
  getSession,
  getUserByEmail,
  getUserById,
  createUser as dbCreateUser,
  cleanExpiredSessions,
  type User,
} from "./db"

const SALT_ROUNDS = 10
const SESSION_COOKIE_NAME = "session"
const SESSION_DURATION_DAYS = 7

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

export async function verifyPassword(password: string, hash: string): Promise<boolean> {
  return bcrypt.compare(password, hash)
}

function generateSessionId(): string {
  const bytes = new Uint8Array(32)
  crypto.getRandomValues(bytes)
  return Array.from(bytes)
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("")
}

export async function login(
  email: string,
  password: string
): Promise<{ success: true; user: User } | { success: false; error: string }> {
  const user = getUserByEmail(email)

  if (!user) {
    return { success: false, error: "Forkert email eller adgangskode" }
  }

  const validPassword = await verifyPassword(password, user.passwordHash)
  if (!validPassword) {
    return { success: false, error: "Forkert email eller adgangskode" }
  }

  // Clean up old sessions periodically
  cleanExpiredSessions()

  // Create new session
  const sessionId = generateSessionId()
  const expiresAt = new Date()
  expiresAt.setDate(expiresAt.getDate() + SESSION_DURATION_DAYS)

  createSession(sessionId, user.id, expiresAt)

  // Set cookie
  const cookieStore = await cookies()
  cookieStore.set(SESSION_COOKIE_NAME, sessionId, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    expires: expiresAt,
    path: "/",
  })

  return {
    success: true,
    user: { id: user.id, email: user.email, name: user.name, createdAt: user.createdAt },
  }
}

export async function logout(): Promise<void> {
  const cookieStore = await cookies()
  const sessionId = cookieStore.get(SESSION_COOKIE_NAME)?.value

  if (sessionId) {
    deleteSession(sessionId)
    cookieStore.delete(SESSION_COOKIE_NAME)
  }
}

export async function getCurrentUser(): Promise<User | null> {
  const cookieStore = await cookies()
  const sessionId = cookieStore.get(SESSION_COOKIE_NAME)?.value

  if (!sessionId) return null

  const session = getSession(sessionId)
  if (!session) return null

  // Check if session is expired
  if (session.expiresAt < new Date()) {
    deleteSession(sessionId)
    return null
  }

  return getUserById(session.userId)
}

export async function isAuthenticated(): Promise<boolean> {
  const user = await getCurrentUser()
  return user !== null
}

// Helper to create users (run from CLI or seed script)
export async function createUserWithPassword(
  email: string,
  password: string,
  name: string
): Promise<User> {
  const passwordHash = await hashPassword(password)
  return dbCreateUser(email, passwordHash, name)
}
