import { z } from "zod"

import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { createCorsPreflight, jsonWithCors } from "@/server/cors"
import { createConvexClient, ConvexConfigurationError } from "@/server/convex-client"
import { checkRateLimit, RATE_LIMITS, rateLimitHeaders } from "@/server/rate-limit"

const attachmentUrlSchema = z.object({
  machineToken: z.string().min(1),
  ticketId: z.string().min(1),
  storageId: z.string().min(1),
})

const CORS_METHODS = "POST, OPTIONS"

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

// POST /api/machines/chat/attachments/url
// Retorna URL assinada para download/preview de um anexo do chat (validado por machineToken).
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 = attachmentUrlSchema.parse(raw)
  } catch (error) {
    return jsonWithCors(
      { error: "Payload invalido", details: error instanceof Error ? error.message : String(error) },
      400,
      origin,
      CORS_METHODS
    )
  }

  const rateLimit = checkRateLimit(
    `chat-attachment:${payload.machineToken}`,
    RATE_LIMITS.CHAT_MESSAGES.maxRequests,
    RATE_LIMITS.CHAT_MESSAGES.windowMs
  )
  if (!rateLimit.allowed) {
    return jsonWithCors(
      { error: "Rate limit exceeded", retryAfterMs: rateLimit.retryAfterMs },
      429,
      origin,
      CORS_METHODS,
      rateLimitHeaders(rateLimit)
    )
  }

  try {
    const messagesResult = await client.query(api.liveChat.listMachineMessages, {
      machineToken: payload.machineToken,
      ticketId: payload.ticketId as Id<"tickets">,
      limit: 200,
    })

    if (!messagesResult.hasSession) {
      return jsonWithCors({ error: "Chat nao esta ativo" }, 403, origin, CORS_METHODS, rateLimitHeaders(rateLimit))
    }

    const attachmentExists = messagesResult.messages.some((message) =>
      (message.attachments ?? []).some((att) => String(att.storageId) === payload.storageId)
    )

    if (!attachmentExists) {
      return jsonWithCors({ error: "Anexo nao encontrado" }, 404, origin, CORS_METHODS, rateLimitHeaders(rateLimit))
    }

    const url = await client.action(api.files.getUrl, { storageId: payload.storageId as Id<"_storage"> })
    if (!url) {
      return jsonWithCors({ error: "URL nao disponivel" }, 404, origin, CORS_METHODS, rateLimitHeaders(rateLimit))
    }

    return jsonWithCors({ url }, 200, origin, CORS_METHODS, rateLimitHeaders(rateLimit))
  } catch (error) {
    console.error("[machines.chat.attachments.url] Falha ao obter URL de anexo", error)
    const details = error instanceof Error ? error.message : String(error)
    return jsonWithCors({ error: "Falha ao obter URL de anexo", details }, 500, origin, CORS_METHODS, rateLimitHeaders(rateLimit))
  }
}

