/**
 * Hooks customizados para queries/mutations do Convex com token de maquina
 *
 * Estes hooks encapsulam a logica de passar o machineToken automaticamente
 * para as queries e mutations do Convex, proporcionando uma API simples
 * e reativa para os componentes de chat.
 */

import { useQuery, useMutation, useAction } from "convex/react"
import { api } from "@convex/_generated/api"
import type { Id } from "@convex/_generated/dataModel"
import { useMachineToken } from "./ConvexMachineProvider"

// ============================================
// TIPOS
// ============================================

export type MachineSession = {
  sessionId: Id<"liveChatSessions">
  ticketId: Id<"tickets">
  ticketRef: number
  ticketSubject: string
  agentName: string
  agentEmail?: string
  agentAvatarUrl?: string
  unreadCount: number
  lastActivityAt: number
  startedAt: number
}

export type MachineMessage = {
  id: Id<"ticketChatMessages">
  body: string
  authorName: string
  authorAvatarUrl?: string
  isFromMachine: boolean
  createdAt: number
  attachments: Array<{
    storageId: Id<"_storage">
    name: string
    size?: number
    type?: string
  }>
}

export type MachineMessagesResult = {
  messages: MachineMessage[]
  hasSession: boolean
  unreadCount: number
}

export type MachineUpdatesResult = {
  hasActiveSessions: boolean
  sessions: Array<{
    ticketId: Id<"tickets">
    ticketRef: number
    unreadCount: number
    lastActivityAt: number
  }>
  totalUnread: number
}

// ============================================
// HOOKS
// ============================================

/**
 * Hook para listar sessoes ativas da maquina
 * Subscription reativa - atualiza automaticamente quando ha mudancas
 */
export function useMachineSessions() {
  const machineToken = useMachineToken()

  const sessions = useQuery(
    api.liveChat.listMachineSessions,
    machineToken ? { machineToken } : "skip"
  )

  return {
    sessions: sessions as MachineSession[] | undefined,
    isLoading: sessions === undefined && !!machineToken,
    hasToken: !!machineToken,
  }
}

/**
 * Hook para listar mensagens de um ticket especifico
 * Subscription reativa - atualiza automaticamente quando ha novas mensagens
 */
export function useMachineMessages(ticketId: Id<"tickets"> | null, options?: { limit?: number }) {
  const machineToken = useMachineToken()

  const result = useQuery(
    api.liveChat.listMachineMessages,
    machineToken && ticketId
      ? { machineToken, ticketId, limit: options?.limit }
      : "skip"
  )

  return {
    messages: (result as MachineMessagesResult | undefined)?.messages ?? [],
    hasSession: (result as MachineMessagesResult | undefined)?.hasSession ?? false,
    unreadCount: (result as MachineMessagesResult | undefined)?.unreadCount ?? 0,
    isLoading: result === undefined && !!machineToken && !!ticketId,
    hasToken: !!machineToken,
  }
}

/**
 * Hook para verificar updates (polling leve)
 * Usado como fallback ou para verificar status rapidamente
 */
export function useMachineUpdates() {
  const machineToken = useMachineToken()

  const result = useQuery(
    api.liveChat.checkMachineUpdates,
    machineToken ? { machineToken } : "skip"
  )

  return {
    hasActiveSessions: (result as MachineUpdatesResult | undefined)?.hasActiveSessions ?? false,
    sessions: (result as MachineUpdatesResult | undefined)?.sessions ?? [],
    totalUnread: (result as MachineUpdatesResult | undefined)?.totalUnread ?? 0,
    isLoading: result === undefined && !!machineToken,
    hasToken: !!machineToken,
  }
}

/**
 * Hook para enviar mensagem
 */
export function usePostMachineMessage() {
  const machineToken = useMachineToken()
  const postMessage = useMutation(api.liveChat.postMachineMessage)

  return async (args: {
    ticketId: Id<"tickets">
    body: string
    attachments?: Array<{
      storageId: Id<"_storage">
      name: string
      size?: number
      type?: string
    }>
  }) => {
    if (!machineToken) {
      throw new Error("Token da maquina nao disponivel")
    }

    return postMessage({
      machineToken,
      ticketId: args.ticketId,
      body: args.body,
      attachments: args.attachments,
    })
  }
}

/**
 * Hook para marcar mensagens como lidas
 */
export function useMarkMachineMessagesRead() {
  const machineToken = useMachineToken()
  const markRead = useMutation(api.liveChat.markMachineMessagesRead)

  return async (args: {
    ticketId: Id<"tickets">
    messageIds: Id<"ticketChatMessages">[]
  }) => {
    if (!machineToken) {
      throw new Error("Token da maquina nao disponivel")
    }

    return markRead({
      machineToken,
      ticketId: args.ticketId,
      messageIds: args.messageIds,
    })
  }
}

/**
 * Hook para gerar URL de upload
 */
export function useGenerateMachineUploadUrl() {
  const machineToken = useMachineToken()
  const generateUrl = useAction(api.liveChat.generateMachineUploadUrl)

  return async (args: {
    fileName: string
    fileType: string
    fileSize: number
  }) => {
    if (!machineToken) {
      throw new Error("Token da maquina nao disponivel")
    }

    return generateUrl({
      machineToken,
      fileName: args.fileName,
      fileType: args.fileType,
      fileSize: args.fileSize,
    })
  }
}
