import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"

vi.mock("../convex/rbac", () => ({
  requireStaff: vi.fn(),
}))

import type { Doc, Id } from "../convex/_generated/dataModel"
import { ticketsByChannelHandler } from "../convex/reports"
import { requireStaff } from "../convex/rbac"
import { createReportsCtx } from "./utils/report-test-helpers"

const TENANT_ID = "tenant-1"
const VIEWER_ID = "user-viewer" as Id<"users">

function buildTicket(overrides: Partial<Doc<"tickets">>): Doc<"tickets"> {
  const base: Record<string, unknown> = {
    _id: "ticket_base" as Id<"tickets">,
    tenantId: TENANT_ID,
    reference: 50000,
    subject: "Chamado",
    summary: null,
    status: "PENDING",
    priority: "MEDIUM",
    channel: "EMAIL",
    queueId: undefined,
    requesterId: "user_req" as Id<"users">,
    requesterSnapshot: { name: "Alice", email: "alice@example.com", avatarUrl: undefined, teams: [] },
    assigneeId: "user_assignee" as Id<"users">,
    assigneeSnapshot: { name: "Bob", email: "bob@example.com", avatarUrl: undefined, teams: [] },
    companyId: undefined,
    companySnapshot: undefined,
    machineId: undefined,
    machineSnapshot: undefined,
    working: false,
    dueAt: undefined,
    firstResponseAt: undefined,
    resolvedAt: undefined,
    closedAt: undefined,
    updatedAt: Date.now(),
    createdAt: Date.now(),
    tags: [],
    customFields: [],
    totalWorkedMs: 0,
    internalWorkedMs: 0,
    externalWorkedMs: 0,
    activeSessionId: undefined,
  }
  return { ...(base as Doc<"tickets">), ...overrides }
}

describe("convex.reports.ticketsByChannel", () => {
  const requireStaffMock = vi.mocked(requireStaff)
  const FIXED_NOW = Date.UTC(2024, 4, 8, 12, 0, 0) // 8 May 2024 12:00 UTC

  beforeAll(() => {
    vi.useFakeTimers()
    vi.setSystemTime(FIXED_NOW)
  })

  afterAll(() => {
    vi.useRealTimers()
  })

  it("builds timeline grouped by channel within the requested range", async () => {
    requireStaffMock.mockResolvedValue({
      role: "ADMIN",
      user: { companyId: undefined },
    } as unknown as Awaited<ReturnType<typeof requireStaff>>)

    const tickets = [
      buildTicket({
        _id: "ticket_email" as Id<"tickets">,
        channel: "EMAIL",
        createdAt: Date.UTC(2024, 4, 7, 10, 0, 0),
      }),
      buildTicket({
        _id: "ticket_chat" as Id<"tickets">,
        channel: "CHAT",
        createdAt: Date.UTC(2024, 4, 7, 12, 0, 0),
      }),
      buildTicket({
        _id: "ticket_other" as Id<"tickets">,
        channel: undefined,
        createdAt: Date.UTC(2024, 4, 6, 9, 0, 0),
      }),
      buildTicket({
        _id: "ticket_outside" as Id<"tickets">,
        createdAt: Date.UTC(2024, 3, 25, 12, 0, 0), // outside 7-day window
      }),
    ]

    const ctx = createReportsCtx({ tickets }) as Parameters<typeof ticketsByChannelHandler>[0]

    const result = await ticketsByChannelHandler(ctx, {
      tenantId: TENANT_ID,
      viewerId: VIEWER_ID,
      range: "7d",
    })

    expect(result.rangeDays).toBe(7)
    expect(result.channels).toEqual(["CHAT", "EMAIL", "OUTRO"])

    const may06 = result.points.find((point) => point.date === "2024-05-06")
    const may07 = result.points.find((point) => point.date === "2024-05-07")

    expect(may06?.values).toEqual({ CHAT: 0, EMAIL: 0, OUTRO: 1 })
    expect(may07?.values).toEqual({ CHAT: 1, EMAIL: 1, OUTRO: 0 })
    expect(may06).toBeTruthy()
    expect(may07).toBeTruthy()
  })
})
