import { authenticate } from '../../plugins/auth.js'
import { getMessages } from '../../services/chat.service.js'
import { getSessionClosures, hasUserSubmittedClosure } from '../../services/closure.service.js'
import { registerDeviceToken } from '../../services/notification.service.js'
import { flipSessionSensitivity } from '../../services/sensitivity.service.js'
import { getDb } from '../../db/client.js'
import { TopicSensitivity, UserType } from '../../constants.js'

const sql = getDb()

const resolveUser = async (request, reply) => {
  if (request.auth?.userType !== UserType.CUSTOMER && request.auth?.userType !== UserType.MITRA) {
    return reply.code(403).send({
      success: false,
      error: { code: 'FORBIDDEN', message: 'Customer or mitra account required' },
    })
  }
  request.userType = request.auth.userType
  request.userId = request.auth.userId
}

// Verify session belongs to the authenticated user
const verifySessionOwnership = async (request, reply) => {
  const { sessionId } = request.params
  const [session] = await sql`
    SELECT id FROM chat_sessions
    WHERE id = ${sessionId}
      AND (customer_id = ${request.userId} OR mitra_id = ${request.userId})
  `
  if (!session) {
    return reply.code(403).send({
      success: false,
      error: { code: 'FORBIDDEN', message: 'You do not have access to this session' },
    })
  }
}

export const sharedChatRoutes = async (app) => {
  // Get messages for a session (paginated)
  app.get('/chat/:sessionId/messages', { preHandler: [authenticate, resolveUser, verifySessionOwnership] }, async (request, reply) => {
    const { sessionId } = request.params
    const { limit, before } = request.query
    const messages = await getMessages(sessionId, {
      limit: limit ? parseInt(limit) : 50,
      before,
    })
    return reply.send({ success: true, data: messages })
  })

  // Get session info
  app.get('/chat/:sessionId/info', { preHandler: [authenticate, resolveUser, verifySessionOwnership] }, async (request, reply) => {
    const { sessionId } = request.params
    const { getSessionById } = await import('../../services/session.service.js')
    const session = await getSessionById(sessionId)
    if (!session) {
      return reply.code(404).send({ success: false, error: { code: 'NOT_FOUND', message: 'Session not found' } })
    }
    const goodbyeSubmittedByMe = await hasUserSubmittedClosure(sessionId, request.userType)
    return reply.send({ success: true, data: { ...session, goodbye_submitted_by_me: goodbyeSubmittedByMe } })
  })

  // Get full transcript (read-only, for history)
  app.get('/chat/:sessionId/transcript', { preHandler: [authenticate, resolveUser, verifySessionOwnership] }, async (request, reply) => {
    const { sessionId } = request.params
    const messages = await getMessages(sessionId, { limit: 10000 })
    const closures = await getSessionClosures(sessionId)
    return reply.send({ success: true, data: { messages, closures } })
  })

  // Register FCM device token
  app.post('/device-token', { preHandler: [authenticate, resolveUser] }, async (request, reply) => {
    const { token } = request.body
    if (!token) {
      return reply.code(400).send({ success: false, error: { code: 'BAD_REQUEST', message: 'Token is required' } })
    }
    await registerDeviceToken(request.userType, request.userId, token)
    return reply.send({ success: true })
  })

  // Submit goodbye/closure message
  app.post('/sessions/:sessionId/close-message', { preHandler: [authenticate, resolveUser, verifySessionOwnership] }, async (request, reply) => {
    const { sessionId } = request.params
    const { message } = request.body
    if (!message) {
      return reply.code(400).send({ success: false, error: { code: 'BAD_REQUEST', message: 'Message is required' } })
    }
    const { submitClosureMessage } = await import('../../services/closure.service.js')
    const closure = await submitClosureMessage(sessionId, request.userType, request.userId, message)
    return reply.send({ success: true, data: closure })
  })

  // Mitra flips session topic sensitivity (regular <-> sensitive)
  app.patch('/chat/sessions/:sessionId/topic', { preHandler: [authenticate, resolveUser] }, async (request, reply) => {
    if (request.userType !== UserType.MITRA) {
      return reply.code(403).send({
        success: false,
        error: { code: 'FORBIDDEN', message: 'Only mitra can change topic sensitivity' },
      })
    }
    const { sessionId } = request.params
    const { topic_sensitivity } = request.body || {}
    if (topic_sensitivity !== TopicSensitivity.REGULAR && topic_sensitivity !== TopicSensitivity.SENSITIVE) {
      return reply.code(400).send({
        success: false,
        error: { code: 'BAD_REQUEST', message: 'topic_sensitivity must be regular or sensitive' },
      })
    }
    try {
      const result = await flipSessionSensitivity({
        sessionId,
        mitraId: request.userId,
        toValue: topic_sensitivity,
      })
      return reply.send({ success: true, data: result })
    } catch (err) {
      return reply.code(err.statusCode || 500).send({
        success: false,
        error: { code: err.code || 'INTERNAL', message: err.message },
      })
    }
  })
}
