import { authenticate } from '../../plugins/auth.js'
import { getMitraById } from '../../services/mitra.service.js'
import { completeMitraPhoneSignIn } from '../../services/auth.service.js'
import { requestOtp, verifyOtp } from '../../services/otp.service.js'
import { UserType } from '../../constants.js'

const extractDeviceInfo = (request) => ({
  user_agent: request.headers['user-agent'] || null,
  ip: request.ip || null,
})

const sendAuthError = (reply, err) => {
  if (!err.statusCode) reply.request.log.error({ err }, 'Unhandled auth error')
  return reply.code(err.statusCode || 500).send({
    success: false,
    error: {
      code: err.code || 'INTERNAL',
      message: err.message,
      ...(err.details && { details: err.details }),
    },
  })
}

export const mitraAuthRoutes = async (app) => {
  app.post('/otp/request', async (request, reply) => {
    const { phone, channel } = request.body || {}
    try {
      const result = await requestOtp({
        phone,
        userType: UserType.MITRA,
        ipAddress: request.ip,
        channel,
      })
      return reply.send({ success: true, data: result })
    } catch (err) {
      return sendAuthError(reply, err)
    }
  })

  app.post('/otp/verify', async (request, reply) => {
    const { otp_request_id, code } = request.body || {}
    try {
      const { phone, user_type } = await verifyOtp({ otpRequestId: otp_request_id, code })
      if (user_type !== UserType.MITRA) {
        return reply.code(400).send({
          success: false,
          error: { code: 'WRONG_FLOW', message: 'This OTP was issued for a different user type' },
        })
      }
      const { tokens, profile } = await completeMitraPhoneSignIn({
        phone,
        deviceInfo: extractDeviceInfo(request),
      })
      if (!profile.is_active) {
        return reply.code(403).send({
          success: false,
          error: { code: 'ACCOUNT_INACTIVE', message: 'Account is inactive. Contact your administrator.' },
        })
      }
      return reply.send({ success: true, data: { ...tokens, profile } })
    } catch (err) {
      return sendAuthError(reply, err)
    }
  })

  app.get('/me', { preHandler: authenticate }, async (request, reply) => {
    if (request.auth.userType !== UserType.MITRA) {
      return reply.code(403).send({
        success: false,
        error: { code: 'FORBIDDEN', message: 'Mitra account required' },
      })
    }
    const mitra = await getMitraById(request.auth.userId)
    if (!mitra) {
      return reply.code(404).send({
        success: false,
        error: { code: 'NOT_FOUND', message: 'Mitra account not found' },
      })
    }
    return reply.send({ success: true, data: mitra })
  })
}
