import { NextRequest, NextResponse } from "next/server"
import {
  comparePassword,
  getUserByEmail,
  getUserByUsername,
  mapDbUserToSessionUser,
  recordLoginAttempt,
  incrementFailedAttempts,
  resetFailedAttempts,
  isAccountLocked,
  createSession,
  setSessionContext,
} from "@/lib/auth"

export async function POST(request: NextRequest) {
  try {
    const { email, username, password } = await request.json()

    const credential = email || username

    if (!credential || !password) {
      return NextResponse.json(
        { error: "Email/Username and password are required." },
        { status: 400 }
      )
    }

    if (credential.trim().length === 0 || password.trim().length === 0) {
      return NextResponse.json(
        { error: "Credentials cannot be empty." },
        { status: 400 }
      )
    }

    const ipAddress =
      request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ||
      request.headers.get("x-real-ip") ||
      "127.0.0.1"

    const userAgent = request.headers.get("user-agent") || null

    // Try to find user by email first, then by username
    let dbUser =
      email || credential.includes("@")
        ? await getUserByEmail(credential)
        : null

    if (!dbUser) {
      dbUser = await getUserByUsername(credential)
    }

    if (!dbUser) {
      await recordLoginAttempt(
        null,
        credential,
        ipAddress,
        userAgent,
        false,
        "User not found"
      )
      return NextResponse.json(
        { error: "Invalid email/username or password." },
        { status: 401 }
      )
    }

    const lockStatus = await isAccountLocked(dbUser)
    if (lockStatus.locked) {
      await recordLoginAttempt(
        dbUser.id,
        credential,
        ipAddress,
        userAgent,
        false,
        lockStatus.reason
      )
      return NextResponse.json(
        { error: lockStatus.reason },
        { status: 423 }
      )
    }

    const valid = await comparePassword(password, dbUser.password_hash)
    if (!valid) {
      await incrementFailedAttempts(dbUser.id)
      await recordLoginAttempt(
        dbUser.id,
        credential,
        ipAddress,
        userAgent,
        false,
        "Invalid password"
      )
      return NextResponse.json(
        { error: "Invalid email/username or password." },
        { status: 401 }
      )
    }

    await resetFailedAttempts(dbUser.id)
    await recordLoginAttempt(
      dbUser.id,
      credential,
      ipAddress,
      userAgent,
      true
    )

    await createSession(dbUser.id, dbUser.role_name)
    await setSessionContext(dbUser.id, ipAddress)

    const user = mapDbUserToSessionUser(dbUser)

    return NextResponse.json({ user }, { status: 200 })
  } catch (error) {
    console.error("Login error:", error)
    return NextResponse.json(
      { error: "Authentication service unavailable." },
      { status: 503 }
    )
  }
}
