import { ConvexHttpClient } from "convex/browser"

import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { env } from "@/lib/env"
import { ensureMachineAccount } from "@/server/machines-auth"
import { auth } from "@/lib/auth"

export type MachineSessionContext = {
  machine: {
    id: Id<"machines">
    hostname: string
    osName: string | null
    osVersion: string | null
    architecture: string | null
    status: string | null
    lastHeartbeatAt: number | null
    companyId: Id<"companies"> | null
    companySlug: string | null
    metadata: Record<string, unknown> | null
    persona: string | null
    assignedUserId: Id<"users"> | null
    assignedUserEmail: string | null
    assignedUserName: string | null
    assignedUserRole: string | null
    isActive: boolean
  }
  headers: Headers
  response: unknown
}

export class MachineInactiveError extends Error {
  constructor(message = "Máquina desativada") {
    super(message)
    this.name = "MachineInactiveError"
  }
}

export async function createMachineSession(machineToken: string, rememberMe = true): Promise<MachineSessionContext> {
  const convexUrl = env.NEXT_PUBLIC_CONVEX_URL
  if (!convexUrl) {
    throw new Error("Convex não configurado")
  }

  const client = new ConvexHttpClient(convexUrl)

  const resolved = await client.mutation(api.machines.resolveToken, { machineToken })
  let machineEmail = resolved.machine.authEmail ?? null

  const machineActive = resolved.machine.isActive ?? true
  if (!machineActive) {
    throw new MachineInactiveError()
  }

  if (!machineEmail) {
    const account = await ensureMachineAccount({
      machineId: resolved.machine._id,
      tenantId: resolved.machine.tenantId ?? DEFAULT_TENANT_ID,
      hostname: resolved.machine.hostname,
      machineToken,
      persona: (resolved.machine.persona ?? null) ?? undefined,
    })

    await client.mutation(api.machines.linkAuthAccount, {
      machineId: resolved.machine._id as Id<"machines">,
      authUserId: account.authUserId,
      authEmail: account.authEmail,
    })

    machineEmail = account.authEmail
  }

  const signIn = await auth.api.signInEmail({
    body: {
      email: machineEmail,
      password: machineToken,
      rememberMe,
    },
    returnHeaders: true,
  })

  return {
    machine: {
      id: resolved.machine._id as Id<"machines">,
      hostname: resolved.machine.hostname,
      osName: resolved.machine.osName ?? null,
      osVersion: resolved.machine.osVersion ?? null,
      architecture: resolved.machine.architecture ?? null,
      status: resolved.machine.status ?? null,
      lastHeartbeatAt: resolved.machine.lastHeartbeatAt ?? null,
      companyId: (resolved.machine.companyId ?? null) as Id<"companies"> | null,
      companySlug: resolved.machine.companySlug ?? null,
      metadata: (resolved.machine.metadata ?? null) as Record<string, unknown> | null,
      persona: (resolved.machine.persona ?? null) as string | null,
      assignedUserId: (resolved.machine.assignedUserId ?? null) as Id<"users"> | null,
      assignedUserEmail: resolved.machine.assignedUserEmail ?? null,
      assignedUserName: resolved.machine.assignedUserName ?? null,
      assignedUserRole: resolved.machine.assignedUserRole ?? null,
      isActive: machineActive,
    },
    headers: signIn.headers,
    response: signIn.response,
  }
}
