import { NextResponse } from "next/server"
import { requireStaff } from "@/server/auth"
import { addSmtpUser, editSmtpUser, emailBounces, removeSmtpUser, viewSmtpUsers } from "@/server/smtp2go"

const SMTP_DESCRIPTION_MAX = 120

async function enrichUsersWithBouncesLimited(users: Array<Record<string, unknown>>) {
  const results: Array<Record<string, unknown>> = []
  const queue = [...users]
  const workers = Array.from({ length: 3 }).map(async () => {
    while (queue.length > 0) {
      const user = queue.shift()
      if (!user) continue
      const username = typeof user.username === "string" ? user.username : ""
      if (!username) {
        results.push({ ...user })
        continue
      }
      try {
        const stats = await emailBounces({ username })
        results.push({ ...user, spam: stats })
      } catch {
        results.push({ ...user, spam: null })
      }
    }
  })
  await Promise.all(workers)
  return results
}

export async function GET(
  _req: Request,
  { params }: { params: Promise<{ subaccountId: string }> }
) {
  const { subaccountId } = await params
  try {
    await requireStaff()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    console.warn("admin/subaccounts/smtp-users: unauthorized access attempt", msg)
    return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 })
  }

  if (!subaccountId) {
    return NextResponse.json({ error: "MISSING_SUBACCOUNT_ID" }, { status: 400 })
  }

  try {
    const data = await viewSmtpUsers({ subaccount_id: subaccountId })
    const users = (data?.results ?? []) as Array<Record<string, unknown>>
    const enriched = await enrichUsersWithBouncesLimited(users)
    return NextResponse.json({ results: enriched })
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    return NextResponse.json({ error: msg || "SMTP_USERS_ERROR" }, { status: 500 })
  }
}

export async function POST(
  req: Request,
  { params }: { params: Promise<{ subaccountId: string }> }
) {
  const { subaccountId } = await params
  try {
    await requireStaff()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    console.warn("admin/subaccounts/smtp-users: unauthorized access attempt", msg)
    return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 })
  }

  if (!subaccountId) {
    return NextResponse.json({ error: "MISSING_SUBACCOUNT_ID" }, { status: 400 })
  }

  const body = await req.json().catch(() => null)
  const username = String(body?.username ?? "").trim()
  const description = body?.description ? String(body.description).trim() : null
  if (!username) {
    return NextResponse.json({ error: "MISSING_USERNAME" }, { status: 400 })
  }
  if (description && description.length > SMTP_DESCRIPTION_MAX) {
    return NextResponse.json({ error: `DESCRIPTION_TOO_LONG_${SMTP_DESCRIPTION_MAX}` }, { status: 400 })
  }

  try {
    const data = await addSmtpUser({
      subaccount_id: subaccountId,
      username,
      email_password: body?.email_password ? String(body.email_password) : null,
      description,
      status: body?.status ? String(body.status) : "allowed",
      feedback_domain: body?.feedback_domain ? String(body.feedback_domain) : "default",
    })
    return NextResponse.json({ ok: true, data })
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    const status = msg.includes("SMTP2GO_HTTP_400") ? 400 : 500
    return NextResponse.json({ error: msg || "SMTP_ADD_USER_ERROR" }, { status })
  }
}

export async function DELETE(
  req: Request,
  { params }: { params: Promise<{ subaccountId: string }> }
) {
  const { subaccountId } = await params
  try {
    await requireStaff()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    console.warn("admin/subaccounts/smtp-users: unauthorized access attempt", msg)
    return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 })
  }

  if (!subaccountId) {
    return NextResponse.json({ error: "MISSING_SUBACCOUNT_ID" }, { status: 400 })
  }

  const body = await req.json().catch(() => null)
  const username = String(body?.username ?? "").trim()
  if (!username) {
    return NextResponse.json({ error: "MISSING_USERNAME" }, { status: 400 })
  }

  try {
    const data = await removeSmtpUser({ subaccount_id: subaccountId, username })
    return NextResponse.json({ ok: true, data })
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    const status = msg.includes("SMTP2GO_HTTP_400") ? 400 : 500
    return NextResponse.json({ error: msg || "SMTP_REMOVE_USER_ERROR" }, { status })
  }
}

export async function PATCH(
  req: Request,
  { params }: { params: Promise<{ subaccountId: string }> }
) {
  const { subaccountId } = await params
  try {
    await requireStaff()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    console.warn("admin/subaccounts/smtp-users: unauthorized access attempt", msg)
    return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 })
  }

  if (!subaccountId) {
    return NextResponse.json({ error: "MISSING_SUBACCOUNT_ID" }, { status: 400 })
  }

  const body = await req.json().catch(() => null)
  const username = String(body?.username ?? "").trim()
  const description = body?.description ? String(body.description).trim() : null
  if (!username) {
    return NextResponse.json({ error: "MISSING_USERNAME" }, { status: 400 })
  }
  if (description && description.length > SMTP_DESCRIPTION_MAX) {
    return NextResponse.json({ error: `DESCRIPTION_TOO_LONG_${SMTP_DESCRIPTION_MAX}` }, { status: 400 })
  }

  try {
    const data = await editSmtpUser({
      subaccount_id: subaccountId,
      username,
      email_password: body?.email_password ? String(body.email_password) : null,
      description,
    })
    return NextResponse.json({ ok: true, data })
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : String(e ?? "")
    const status = msg.includes("SMTP2GO_HTTP_400") ? 400 : 500
    return NextResponse.json({ error: msg || "SMTP_EDIT_USER_ERROR" }, { status })
  }
}
