/**
 * AI assistant dispatch — ai-assistant.
 *
 * `dispatchToAiAssistant` is called by the comms-inbound queue consumer when
 * `tenantConfig.aiAssistantEnabled === true`. It checks the channel and tier,
 * then enqueues the appropriate AI job.
 *
 * - Telegram messages → `ai_telegram_message` queue (Business+)
 * - WhatsApp messages → `runAssistantTurn` inline + reply via WhatsApp adapter (Enterprise+)
 *
 * Called from comms-inbound via closure:
 *   dispatchToAiAssistant: (msg) => realDispatchToAiAssistant(env, msg, tenantConfig, tenantId)
 *
 * Tier enforcement:
 *  - Business+ required for Telegram
 *  - Enterprise+ required for WhatsApp
 * Below-tier → no reply, silent return (no error).
 */
import type { Env } from '@zync/types'
import type { InboundMessage } from '@zync/types'
import type { TenantCommsConfig } from '@zync/db/queries'
import { createDb, getTenantById } from '@zync/db/queries'
import type { TenantId } from '@zync/types'
import type { AiTelegramMessageJob } from '../queues/ai-telegram-message'
import { runAssistantTurn } from '@zync/ai/chat'
import { loadAdapterCredential } from '@zync/notifications'

const BUSINESS_TIERS = new Set(['business', 'enterprise', 'white_label'])
const ENTERPRISE_TIERS = new Set(['enterprise', 'white_label'])

async function sendWhatsAppReply(
  wabaChatId: string,
  reply: string,
  token: string,
): Promise<void> {
  const res = await fetch('https://graph.facebook.com/v18.0/me/messages', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      messaging_product: 'whatsapp',
      to: wabaChatId,
      type: 'text',
      text: { body: reply },
    }),
  })
  if (!res.ok) {
    const body = await res.text()
    throw new Error(`WhatsApp send failed: ${res.status} ${body}`)
  }
}

/**
 * Dispatch an inbound message to the AI assistant.
 *
 * Called by comms-inbound with tenantId captured from the queue message.
 * The `tenantConfig` carries `aiAssistantEnabled` check (already verified by caller).
 * The channel is inferred from message metadata set by webhook handlers.
 */
export async function dispatchToAiAssistant(
  env: Env,
  msg: InboundMessage,
  tenantConfig: TenantCommsConfig,
  tenantId: string,
): Promise<void> {
  if (!tenantConfig.aiAssistantEnabled) return

  const db = createDb(env)
  const tenant = await getTenantById(db, tenantId as TenantId)
  const tier = tenant?.tier ?? 'freelancer'

  // Channel is set by the webhook handler in message metadata
  const channel = (msg.metadata['channel'] as 'telegram' | 'whatsapp' | undefined) ?? 'telegram'

  if (channel === 'telegram') {
    // Tier gate: Business+
    if (!BUSINESS_TIERS.has(tier)) return
    if (!tenantConfig.telegramAiChatId || tenantConfig.telegramAiChatId !== msg.chatId) return

    const job: AiTelegramMessageJob = {
      tenantId,
      telegramChatId: msg.chatId,
      message: msg.text,
    }
    await env.QUEUE.send(job)
  } else if (channel === 'whatsapp') {
    // Tier gate: Enterprise+
    if (!ENTERPRISE_TIERS.has(tier)) return

    const { reply } = await runAssistantTurn(env, {
      tenantId,
      channel: 'whatsapp',
      message: msg.text,
      whatsappChatId: msg.chatId,
      tier,
    })

    const wabaToken = await loadAdapterCredential(
      db,
      tenantId,
      'whatsapp',
      env.INTEGRATION_ENCRYPTION_KEY,
    )
    if (!wabaToken) {
      console.warn('[dispatch-to-assistant] No WhatsApp token for tenant:', tenantId)
      return
    }

    await sendWhatsAppReply(msg.chatId, reply, wabaToken)
  }
}
