import { subscribe } from '../plugins/valkey.js'
import { sendMessage, markDelivered, markRead } from './chat.service.js'
import { initiateEarlyEnd } from './closure.service.js'
import { sendToSessionParticipant } from '../plugins/websocket.js'
import { UserType, MessageType, WsMessage } from '../constants.js'

// Track typing throttle per session+user
const typingLastSent = new Map()
const TYPING_THROTTLE_MS = 2000

// Active session listeners: sessionId → unsubscribe
const sessionListeners = new Map()

export const startSessionListener = (sessionId) => {
  if (sessionListeners.has(sessionId)) return

  const unsub = subscribe(`session:${sessionId}:incoming`, async (data) => {
    const { type, _sender_type, _sender_id, _session_id, ...payload } = data

    try {
      switch (type) {
        case WsMessage.MESSAGE:
          await sendMessage({
            sessionId: _session_id,
            senderType: _sender_type,
            senderId: _sender_id,
            content: payload.content,
            type: payload.message_type || MessageType.TEXT,
          })
          break

        case WsMessage.TYPING:
          handleTyping(_session_id, _sender_type)
          break

        case WsMessage.DELIVERED:
          await markDelivered(_session_id, _sender_type, payload.message_ids)
          break

        case WsMessage.READ:
          await markRead(_session_id, _sender_type, payload.message_ids)
          break

        case WsMessage.EARLY_END:
          await initiateEarlyEnd(_session_id, _sender_type)
          break
      }
    } catch (err) {
      console.error(`[chat-handler] Error processing ${type}:`, err.message)
      sendToSessionParticipant(_session_id, _sender_type, {
        type: WsMessage.ERROR,
        message: err.message,
        code: err.code,
      })
    }
  })

  sessionListeners.set(sessionId, unsub)
}

export const stopSessionListener = (sessionId) => {
  const unsub = sessionListeners.get(sessionId)
  if (unsub) {
    unsub()
    sessionListeners.delete(sessionId)
  }
}

const handleTyping = (sessionId, senderType) => {
  const key = `${sessionId}:${senderType}`
  const now = Date.now()
  const lastSent = typingLastSent.get(key) || 0

  if (now - lastSent < TYPING_THROTTLE_MS) return

  typingLastSent.set(key, now)

  const recipientType = senderType === UserType.CUSTOMER ? UserType.MITRA : UserType.CUSTOMER
  sendToSessionParticipant(sessionId, recipientType, {
    type: WsMessage.TYPING,
    sender_type: senderType,
  })
}
