import { NextResponse } from "next/server"
import { ConvexHttpClient } from "convex/browser"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { assertAuthenticatedSession } from "@/lib/auth-server"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { requireConvexUrl } from "@/server/convex-client"

export const runtime = "nodejs"

const MAX_RESULTS = 10

type TicketRecord = {
  id: string | number
  reference: string | number
  subject?: string | null
  status?: string | null
  priority?: string | null
  requester?: { name?: string | null } | null
  assignee?: { name?: string | null } | null
  company?: { name?: string | null } | null
  updatedAt?: number | null
}

function isTicketRecord(value: unknown): value is TicketRecord {
  if (!value || typeof value !== "object") {
    return false
  }
  const record = value as Record<string, unknown>
  const hasValidId = typeof record.id === "string" || typeof record.id === "number"
  const hasValidReference = typeof record.reference === "string" || typeof record.reference === "number"
  return hasValidId && hasValidReference
}

function normalizeRole(role?: string | null) {
  return (role ?? "").toLowerCase()
}

export async function GET(request: Request) {
  const session = await assertAuthenticatedSession()
  if (!session) {
    return NextResponse.json({ items: [] }, { status: 401 })
  }

  const normalizedRole = normalizeRole(session.user.role)
  const isAgentOrAdmin = normalizedRole === "admin" || normalizedRole === "agent"
  const canLinkOwnTickets = normalizedRole === "collaborator"
  if (!isAgentOrAdmin && !canLinkOwnTickets) {
    return NextResponse.json({ items: [] }, { status: 403 })
  }

  const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
  const url = new URL(request.url)
  const rawQuery = url.searchParams.get("q") ?? ""
  const query = rawQuery.trim()

  const client = new ConvexHttpClient(requireConvexUrl())

  // Garantir que o usuário exista no Convex para obter viewerId
  let viewerId: string | null = null
  try {
    const ensured = await client.mutation(api.users.ensureUser, {
      tenantId,
      name: session.user.name ?? session.user.email,
      email: session.user.email,
      avatarUrl: session.user.avatarUrl ?? undefined,
      role: session.user.role.toUpperCase(),
    })
    viewerId = ensured?._id ?? null
  } catch (error) {
    console.error("[mentions] ensureUser failed", error)
    return NextResponse.json({ items: [] }, { status: 500 })
  }
  if (!viewerId) {
    return NextResponse.json({ items: [] }, { status: 403 })
  }

  // Pesquisar pelos tickets visíveis ao viewer (assunto, resumo ou #referência)
  let tickets: TicketRecord[] = []
  try {
    const res = await client.query(api.tickets.list, {
      tenantId,
      viewerId: viewerId as unknown as Id<"users">,
      search: query,
      limit: 40,
    })
    tickets = Array.isArray(res) ? res.filter(isTicketRecord) : []
  } catch (error) {
    console.error("[mentions] tickets.list failed", error)
    return NextResponse.json({ items: [] }, { status: 500 })
  }

  const basePath = isAgentOrAdmin ? "/tickets" : "/portal/tickets"
  const items = tickets.slice(0, MAX_RESULTS).map((t) => ({
    id: String(t.id),
    reference: Number(t.reference),
    subject: String(t.subject ?? ""),
    status: String(t.status ?? "PENDING"),
    priority: String(t.priority ?? "MEDIUM"),
    requesterName: t.requester?.name ?? null,
    assigneeName: t.assignee?.name ?? null,
    companyName: t.company?.name ?? null,
    url: `${basePath}/${String(t.id)}`,
    updatedAt: t.updatedAt ? new Date(t.updatedAt).toISOString() : new Date().toISOString(),
  }))

  return NextResponse.json({ items })
}
