import { NextResponse } from "next/server"
import { z } from "zod"
import { createMachineSession, MachineInactiveError } from "@/server/machines-session"
import { applyCorsHeaders, createCorsPreflight, jsonWithCors } from "@/server/cors"
import {
  MACHINE_CTX_COOKIE,
  serializeMachineCookie,
  type MachineContextCookiePayload,
} from "@/server/machines/context"

const sessionSchema = z.object({
  machineToken: z.string().min(1),
  rememberMe: z.boolean().optional(),
})

const CORS_METHODS = "POST, OPTIONS"

export async function OPTIONS(request: Request) {
  return createCorsPreflight(request.headers.get("origin"), CORS_METHODS)
}

export async function POST(request: Request) {
  const origin = request.headers.get("origin")
  if (request.method !== "POST") {
    return jsonWithCors({ error: "Método não permitido" }, 405, origin, CORS_METHODS)
  }

  let payload
  try {
    const raw = await request.json()
    payload = sessionSchema.parse(raw)
  } catch (error) {
    return jsonWithCors(
      { error: "Payload inválido", details: error instanceof Error ? error.message : String(error) },
      400,
      request.headers.get("origin"),
      CORS_METHODS
    )
  }

  try {
    const session = await createMachineSession(payload.machineToken, payload.rememberMe ?? true)
    const response = NextResponse.json(
      {
        ok: true,
        machine: session.machine,
        session: session.response,
      },
      { status: 200 }
    )

    // Propaga cookies de sessão do Better Auth com segurança.
    // Em alguns ambientes, múltiplos Set-Cookie são colapsados; tentamos cobrir ambos.
    const headersAny = session.headers as unknown as { getSetCookie?: () => string[] }
    const setCookies: string[] = []
    try {
      if (typeof headersAny?.getSetCookie === "function") {
        setCookies.push(...(headersAny.getSetCookie() ?? []))
      } else {
        const single = session.headers.get("set-cookie")
        if (single) setCookies.push(single)
      }
    } catch {
      const single = session.headers.get("set-cookie")
      if (single) setCookies.push(single)
    }

    // Converte os Set-Cookie recebidos em cookies do Next (maior compatibilidade)
    const toPairs = (raw: string) => {
      const [nameValue, ...attrs] = raw.split(/;\s*/)
      const [name, ...v] = nameValue.split("=")
      const value = v.join("=")
      const record: Record<string, string | boolean> = { name, value }
      for (const attr of attrs) {
        const [k, ...vv] = attr.split("=")
        const key = k.toLowerCase()
        const val = vv.join("=")
        if (!val && (key === "httponly" || key === "secure")) {
          record[key] = true
        } else if (val) {
          record[key] = val
        }
      }
      return record
    }
    for (const raw of setCookies) {
      const rec = toPairs(raw)
      const name = String(rec.name)
      const value = String(rec.value)
      const options: Parameters<typeof response.cookies.set>[2] = {
        httpOnly: Boolean(rec["httponly"]) || /httponly/i.test(raw),
        secure: /;\s*secure/i.test(raw),
        path: typeof rec["path"] === "string" ? (rec["path"] as string) : "/",
      }
      if (typeof rec["samesite"] === "string") {
        const s = String(rec["samesite"]).toLowerCase() as "lax" | "strict" | "none"
        options.sameSite = s
      }
      if (typeof rec["domain"] === "string") options.domain = rec["domain"] as string
      if (typeof rec["expires"] === "string") options.expires = new Date(rec["expires"] as string)
      if (typeof rec["max-age"] === "string") options.maxAge = Number(rec["max-age"])
      response.cookies.set(name, value, options)
    }

    const machineCookiePayload: MachineContextCookiePayload = {
      machineId: session.machine.id,
      persona: session.machine.persona ?? null,
      assignedUserId: session.machine.assignedUserId ?? null,
      assignedUserEmail: session.machine.assignedUserEmail ?? null,
      assignedUserName: session.machine.assignedUserName ?? null,
      assignedUserRole: session.machine.assignedUserRole ?? null,
    }
    const isSecure = new URL(request.url).protocol === "https:"
    response.cookies.set({
      name: MACHINE_CTX_COOKIE,
      value: serializeMachineCookie(machineCookiePayload),
      httpOnly: true,
      sameSite: "lax",
      secure: isSecure,
      path: "/",
      maxAge: 60 * 60 * 24 * 30,
    })

    applyCorsHeaders(response, request.headers.get("origin"), CORS_METHODS)

    return response
  } catch (error) {
    if (error instanceof MachineInactiveError) {
      return jsonWithCors(
        { error: "Máquina desativada. Entre em contato com o suporte da Rever para reativar o acesso." },
        423,
        origin,
        CORS_METHODS
      )
    }
    console.error("[machines.sessions] Falha ao criar sessão", error)
    return jsonWithCors({ error: "Falha ao autenticar máquina" }, 500, origin, CORS_METHODS)
  }
}
