import { NextRequest, NextResponse } from "next/server"
import { getWorkOS, saveSession } from "@workos-inc/authkit-nextjs"
import { z } from "zod"
import { ensureUserExists } from "@/lib/auth"

// input validation schema
const loginRequestSchema = z.discriminatedUnion("type", [
  z.object({
    type: z.literal("password"),
    email: z.string().email("Please enter a valid email address"),
    password: z.string().min(1, "Password is required"),
  }),
  z.object({
    type: z.literal("passwordless_send"),
    email: z.string().email("Please enter a valid email address"),
  }),
  z.object({
    type: z.literal("passwordless_verify"),
    email: z.string().email("Please enter a valid email address"),
    code: z.string().min(1, "Verification code is required"),
  }),
])

function mapWorkOSError(error: unknown): string {
  const err = error as { code?: string; message?: string }
  switch (err.code) {
    case "invalid_credentials":
      return "Invalid email or password"
    case "user_not_found":
      return "No account found with this email"
    case "expired_code":
      return "Code expired. Please request a new one."
    case "invalid_code":
      return "Invalid code. Please try again."
    default:
      return err.message || "An error occurred. Please try again."
  }
}

export async function POST(request: NextRequest) {
  try {
    // validate input
    const body = await request.json()
    const parseResult = loginRequestSchema.safeParse(body)

    if (!parseResult.success) {
      const firstIssue = parseResult.error.issues[0]
      return NextResponse.json(
        { success: false, error: firstIssue?.message || "Invalid input" },
        { status: 400 }
      )
    }

    const data = parseResult.data
    const workos = getWorkOS()

    // check if workos is configured (dev mode fallback)
    const isConfigured =
      process.env.WORKOS_API_KEY &&
      process.env.WORKOS_CLIENT_ID &&
      !process.env.WORKOS_API_KEY.includes("placeholder")

    if (!isConfigured) {
      return NextResponse.json({
        success: true,
        redirectUrl: "/dashboard",
        devMode: true,
      })
    }

    if (data.type === "password") {
      const result = await workos.userManagement.authenticateWithPassword({
        email: data.email,
        password: data.password,
        clientId: process.env.WORKOS_CLIENT_ID!,
      })

      // sync user to our database
      await ensureUserExists({
        id: result.user.id,
        email: result.user.email,
        firstName: result.user.firstName,
        lastName: result.user.lastName,
        profilePictureUrl: result.user.profilePictureUrl,
      })

      // save session with BOTH access and refresh tokens (fixes 30-second logout)
      await saveSession(
        {
          accessToken: result.accessToken,
          refreshToken: result.refreshToken,
          user: result.user,
          impersonator: result.impersonator,
        },
        request
      )

      return NextResponse.json({
        success: true,
        redirectUrl: "/dashboard",
      })
    }

    if (data.type === "passwordless_send") {
      const magicAuth = await workos.userManagement.createMagicAuth({
        email: data.email,
      })

      return NextResponse.json({
        success: true,
        magicAuthId: magicAuth.id,
      })
    }

    if (data.type === "passwordless_verify") {
      const result = await workos.userManagement.authenticateWithMagicAuth({
        code: data.code,
        email: data.email,
        clientId: process.env.WORKOS_CLIENT_ID!,
      })

      // sync user to our database
      await ensureUserExists({
        id: result.user.id,
        email: result.user.email,
        firstName: result.user.firstName,
        lastName: result.user.lastName,
        profilePictureUrl: result.user.profilePictureUrl,
      })

      // save session with BOTH access and refresh tokens
      await saveSession(
        {
          accessToken: result.accessToken,
          refreshToken: result.refreshToken,
          user: result.user,
          impersonator: result.impersonator,
        },
        request
      )

      return NextResponse.json({
        success: true,
        redirectUrl: "/dashboard",
      })
    }

    return NextResponse.json(
      { success: false, error: "Invalid login type" },
      { status: 400 }
    )
  } catch (error) {
    console.error("Login error:", error)
    const err = error as { code?: string }
    const isAuthError = ["invalid_credentials", "user_not_found",
      "expired_code", "invalid_code"].includes(err.code || "")
    return NextResponse.json(
      { success: false, error: mapWorkOSError(error) },
      { status: isAuthError ? 401 : 500 }
    )
  }
}
