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

import type { Doc, Id } from "../convex/_generated/dataModel"
import { getByIdHandler } from "../convex/machines"

const FIXED_NOW = 1_706_071_200_000

function buildMachine(overrides: Partial<Doc<"machines">> = {}): Doc<"machines"> {
  const machine: Record<string, unknown> = {
    _id: "machine_1" as Id<"machines">,
    tenantId: "tenant-1",
    companyId: undefined,
    companySlug: undefined,
    authUserId: undefined,
    authEmail: undefined,
    persona: undefined,
    assignedUserId: undefined,
    assignedUserEmail: undefined,
    assignedUserName: undefined,
    assignedUserRole: undefined,
    hostname: "desktop-01",
    osName: "Windows",
    osVersion: "11",
    architecture: "x86_64",
    macAddresses: ["001122334455"],
    serialNumbers: ["SN123"],
    fingerprint: "fingerprint",
    metadata: {
      metrics: { cpu: { usage: 12 }, memory: { total: 8 * 1024 ** 3 } },
      inventory: { cpu: { model: "Intel" }, os: { name: "Windows" } },
      postureAlerts: [{ kind: "CPU_HIGH", severity: "warning" }],
      lastPostureAt: FIXED_NOW - 5000,
    },
    lastHeartbeatAt: FIXED_NOW - 1000,
    status: undefined,
    isActive: true,
    createdAt: FIXED_NOW - 10_000,
    updatedAt: FIXED_NOW - 5_000,
    registeredBy: "agent:desktop",
    linkedUserIds: [],
    remoteAccess: null,
  }
  return { ...(machine as Doc<"machines">), ...overrides }
}

describe("convex.machines.getById", () => {
  it("returns machine details including metadata when includeMetadata=true", async () => {
    vi.useFakeTimers()
    vi.setSystemTime(FIXED_NOW)

    const machine = buildMachine()

    const db = {
      get: vi.fn(async (id: Id<"machines">) => {
        if (id === machine._id) return machine
        return null
      }),
      query: vi.fn((table: string) => {
        // Mock para machineHeartbeats - retorna o lastHeartbeatAt da nova tabela
        if (table === "machineHeartbeats") {
          return {
            withIndex: vi.fn((_name: string, _cb: unknown) => ({
              first: vi.fn(async () => ({ machineId: machine._id, lastHeartbeatAt: FIXED_NOW - 1000 })),
              collect: vi.fn(async () => [{ machineId: machine._id, lastHeartbeatAt: FIXED_NOW - 1000 }]),
              take: vi.fn(async () => [{ machineId: machine._id, lastHeartbeatAt: FIXED_NOW - 1000 }]),
            })),
          }
        }
        // Mock para machineTokens e outras tabelas
        return {
          withIndex: vi.fn((_name: string, _cb: unknown) => ({
            first: vi.fn(async () => null),
            collect: vi.fn(async () => [
              { revoked: false, expiresAt: FIXED_NOW + 60_000, lastUsedAt: FIXED_NOW - 1000, usageCount: 5 },
            ]),
            take: vi.fn(async () => [
              { revoked: false, expiresAt: FIXED_NOW + 60_000, lastUsedAt: FIXED_NOW - 1000, usageCount: 5 },
            ]),
          })),
          collect: vi.fn(async () => []),
          take: vi.fn(async () => []),
        }
      }),
    }

    const ctx = { db } as unknown as Parameters<typeof getByIdHandler>[0]
    const result = await getByIdHandler(ctx, { id: machine._id, includeMetadata: true })

    expect(result).toBeTruthy()
    expect(result?.metrics).toBeTruthy()
    expect(result?.inventory).toBeTruthy()
    expect(result?.postureAlerts?.length).toBeGreaterThan(0)
    expect(result?.token).toBeTruthy()
  })
})
