/**
 * Source-aware staff reply routing — crm-support-center.
 */
import { decryptCredential } from '@zync/auth'
import {
  getContactById,
  listPortalUsers,
  loadAdapterCredentialRow,
  createNotification,
} from '@zync/db/queries'
import type { TicketObject } from '@zync/db/queries'
import {
  createTelegramAdapter,
  deliverNotification,
  loadAdapterCredential,
  sendEmail,
} from '@zync/notifications'
import type { Env } from '@zync/types'
import type { Db } from '@zync/db/queries'

function htmlToPlainText(html: string): string {
  return html
    .replace(/<br\s*\/?>/gi, '\n')
    .replace(/<\/p>/gi, '\n')
    .replace(/<[^>]+>/g, '')
    .replace(/\n{3,}/g, '\n\n')
    .trim()
}

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

export async function routeTicketReplyToChannel(
  env: Env,
  db: Db,
  tenantId: string,
  ticket: TicketObject,
  htmlContent: string,
): Promise<void> {
  const plainText = htmlToPlainText(htmlContent)

  switch (ticket.source) {
    case 'email': {
      let toEmail: string | null = null
      let customerName = 'Customer'
      if (ticket.contact_id) {
        const contact = await getContactById(db, tenantId, ticket.contact_id)
        toEmail = contact?.email ?? null
        customerName = contact?.name ?? customerName
      }
      if (!toEmail) {
        console.warn('[route-ticket-reply] No contact email for ticket', ticket.id)
        return
      }
      await sendEmail(
        {
          to: toEmail,
          templateKey: 'ticket_reply',
          vars: {
            subject: `Re: ${ticket.title}`,
            customerName,
            ticketSubject: ticket.title,
            replyBody: plainText,
            ticketRef: ticket.id.slice(0, 8).toUpperCase(),
          },
          locale: 'he-IL',
          ...(ticket.external_thread_id
            ? { tags: { in_reply_to: ticket.external_thread_id } }
            : {}),
        },
        env,
      )
      return
    }

    case 'telegram': {
      if (!ticket.external_thread_id) {
        console.warn('[route-ticket-reply] Missing external_thread_id for telegram ticket', ticket.id)
        return
      }
      const token = await loadAdapterCredential(
        db,
        tenantId,
        'telegram',
        env.INTEGRATION_ENCRYPTION_KEY,
      )
      if (!token) {
        console.warn('[route-ticket-reply] No Telegram bot token for tenant', tenantId)
        return
      }
      const adapter = createTelegramAdapter(token)
      await adapter.send({
        to: ticket.external_thread_id,
        body: plainText,
      })
      return
    }

    case 'whatsapp': {
      if (!ticket.external_thread_id) {
        console.warn('[route-ticket-reply] Missing external_thread_id for whatsapp ticket', ticket.id)
        return
      }
      const credRow = await loadAdapterCredentialRow(db, tenantId, 'whatsapp')
      if (!credRow) {
        console.warn('[route-ticket-reply] No WhatsApp credentials for tenant', tenantId)
        return
      }
      const credJson = await decryptCredential(
        { ciphertext: credRow.ciphertext, iv: credRow.iv, authTag: credRow.authTag },
        env.INTEGRATION_ENCRYPTION_KEY,
      )
      const cred = JSON.parse(credJson) as { access_token?: string }
      if (!cred.access_token) {
        console.warn('[route-ticket-reply] WhatsApp access_token missing for tenant', tenantId)
        return
      }
      await sendWhatsAppText(ticket.external_thread_id, plainText, cred.access_token)
      return
    }

    case 'portal': {
      if (!ticket.customer_id) {
        console.warn('[route-ticket-reply] Portal ticket missing customer_id', ticket.id)
        return
      }
      const portalUsers = await listPortalUsers(db, tenantId, ticket.customer_id)
      for (const portalUser of portalUsers) {
        if (portalUser.status !== 'active') continue
        const notification = {
          type: 'ticket_replied' as const,
          title: `Reply on ${ticket.title}`,
          body: plainText.slice(0, 500),
          entityType: 'ticket',
          entityId: ticket.id,
        }
        await createNotification(db, {
          tenantId,
          userId: portalUser.userId,
          type: 'ticket_replied',
          titleKey: notification.title,
          bodyKey: notification.body,
          entityType: 'ticket',
          entityId: ticket.id,
        })
        await deliverNotification(portalUser.userId, notification, db, env, tenantId)
      }
      return
    }

    case 'web':
      return
  }
}
