import { describe, expect, it, vi } from "vitest"

import { buildCommentAuthorSummary } from "../convex/tickets"
import type { Doc, Id } from "../convex/_generated/dataModel"

function makeId<TableName extends string>(value: string) {
  return value as unknown as Id<TableName>
}

function makeComment(overrides: Partial<Doc<"ticketComments">> = {}) {
  const base = {
    _id: makeId<"ticketComments">(`comment-${Math.random().toString(16).slice(2)}`),
    _creationTime: Date.now(),
    ticketId: makeId<"tickets">(`ticket-${Math.random().toString(16).slice(2)}`),
    authorId: makeId<"users">(`user-${Math.random().toString(16).slice(2)}`),
    visibility: "PUBLIC",
    body: "Teste",
    attachments: [],
    createdAt: Date.now(),
    updatedAt: Date.now(),
  } satisfies Partial<Doc<"ticketComments">>
  return { ...base, ...overrides } as Doc<"ticketComments">
}

function makeUser(overrides: Partial<Doc<"users">> = {}) {
  const base = {
    _id: makeId<"users">(`user-${Math.random().toString(16).slice(2)}`),
    _creationTime: Date.now(),
    tenantId: "tenant-1",
    email: "autor@example.com",
    name: "Autor",
    role: "AGENT",
    teams: ["Suporte N1"],
  } satisfies Partial<Doc<"users">>
  return { ...base, ...overrides } as Doc<"users">
}

describe("buildCommentAuthorSummary", () => {
  it("retorna dados do autor quando o usuário existe", () => {
    const user = makeUser({
      name: "Ana",
      email: "ana@example.com",
      avatarUrl: "https://example.com/avatar.png",
      teams: ["Suporte N1"],
    })
    const comment = makeComment({
      authorId: user._id,
      ticketId: makeId<"tickets">("ticket-existing"),
    })

    const summary = buildCommentAuthorSummary(comment, user, {
      ticketId: comment.ticketId,
      commentId: comment._id,
    })

    expect(summary).toMatchObject({
      id: user._id,
      name: "Ana",
      email: "ana@example.com",
      avatarUrl: "https://example.com/avatar.png",
      teams: ["Chamados"],
    })
  })

  it("usa snapshot quando o autor não existe mais", () => {
    const warn = vi.spyOn(console, "warn").mockImplementation(() => {})
    const comment = makeComment({
      _id: makeId<"ticketComments">("comment-snapshot"),
      ticketId: makeId<"tickets">("ticket-snapshot"),
      authorId: makeId<"users">("user-snapshot"),
      authorSnapshot: {
        name: "Bruno Antigo",
        email: "bruno@example.com",
        avatarUrl: "https://example.com/bruno.png",
        teams: ["Suporte N2"],
      },
    })

    const summary = buildCommentAuthorSummary(comment, null, {
      ticketId: comment.ticketId,
      commentId: comment._id,
    })

    expect(summary).toMatchObject({
      id: comment.authorId,
      name: "Bruno Antigo",
      email: "bruno@example.com",
      avatarUrl: "https://example.com/bruno.png",
      teams: ["Laboratório"],
    })
    warn.mockRestore()
  })

  it("gera placeholder quando não há snapshot disponível", () => {
    const warn = vi.spyOn(console, "warn").mockImplementation(() => {})
    const comment = makeComment({
      _id: makeId<"ticketComments">("comment-placeholder"),
      ticketId: makeId<"tickets">("ticket-placeholder"),
      authorId: makeId<"users">("user-placeholder"),
    })

    const summary = buildCommentAuthorSummary(comment, null, {
      ticketId: comment.ticketId,
      commentId: comment._id,
    })

    expect(summary).toMatchObject({
      id: comment.authorId,
      name: "Usuário removido",
      email: "author-user-placeholder@example.invalid",
      teams: [],
    })
    warn.mockRestore()
  })
})
