import { z } from "zod"

import { api } from "@/convex/_generated/api"
import { createCorsPreflight, jsonWithCors } from "@/server/cors"
import { createConvexClient, ConvexConfigurationError } from "@/server/convex-client"

const getPolicySchema = z.object({
  machineToken: z.string().min(1),
})

const reportStatusSchema = z.object({
  machineToken: z.string().min(1),
  status: z.enum(["PENDING", "APPLYING", "APPLIED", "FAILED"]),
  error: z.string().nullable().optional(),
  currentPolicy: z.string().nullable().optional(),
})

const CORS_METHODS = "GET, POST, OPTIONS"

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

export async function GET(request: Request) {
  const origin = request.headers.get("origin")

  let client
  try {
    client = createConvexClient()
  } catch (error) {
    if (error instanceof ConvexConfigurationError) {
      return jsonWithCors({ error: error.message }, 500, origin, CORS_METHODS)
    }
    throw error
  }

  const url = new URL(request.url)
  const machineToken = url.searchParams.get("machineToken")

  if (!machineToken) {
    return jsonWithCors({ error: "machineToken e obrigatorio" }, 400, origin, CORS_METHODS)
  }

  try {
    const pendingPolicy = await client.query(api.usbPolicy.getPendingUsbPolicy, { machineToken })

    if (!pendingPolicy) {
      return jsonWithCors({ pending: false }, 200, origin, CORS_METHODS)
    }

    return jsonWithCors({
      pending: true,
      policy: pendingPolicy.policy,
      appliedAt: pendingPolicy.appliedAt,
    }, 200, origin, CORS_METHODS)
  } catch (error) {
    console.error("[machines.usb-policy] Falha ao buscar politica USB", error)
    const details = error instanceof Error ? error.message : String(error)
    return jsonWithCors({ error: "Falha ao buscar politica USB", details }, 500, origin, CORS_METHODS)
  }
}

export async function POST(request: Request) {
  const origin = request.headers.get("origin")

  let client
  try {
    client = createConvexClient()
  } catch (error) {
    if (error instanceof ConvexConfigurationError) {
      return jsonWithCors({ error: error.message }, 500, origin, CORS_METHODS)
    }
    throw error
  }

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

  try {
    const response = await client.mutation(api.usbPolicy.reportUsbPolicyStatus, payload)
    return jsonWithCors(response, 200, origin, CORS_METHODS)
  } catch (error) {
    console.error("[machines.usb-policy] Falha ao reportar status de politica USB", error)
    const details = error instanceof Error ? error.message : String(error)
    return jsonWithCors({ error: "Falha ao reportar status", details }, 500, origin, CORS_METHODS)
  }
}
