import { authenticate, requirePermission } from '../../plugins/auth.js'
import {
  getCcUserById,
  createCcUserWithPassword,
  listCcUsers,
  updateCcUserPasswordHash,
} from '../../services/cc-user.service.js'
import {
  hashPassword,
  verifyPassword,
  validatePasswordComplexity,
} from '../../services/password.service.js'
import { UserType } from '../../constants.js'

const attachCcUser = async (request, reply) => {
  if (request.auth?.userType !== UserType.CC_USER) {
    return reply.code(403).send({ success: false, error: { code: 'FORBIDDEN', message: 'Not a control center user' } })
  }
  const user = await getCcUserById(request.auth.userId)
  if (!user) return reply.code(403).send({ success: false, error: { code: 'FORBIDDEN', message: 'Not a control center user' } })
  request.ccUser = user
}

const sendValidation = (reply, err) => reply.code(err.statusCode || 422).send({
  success: false,
  error: { code: err.code || 'VALIDATION_ERROR', message: err.message },
})

export const ccUserRoutes = async (app) => {
  // Create CC user (with initial password)
  app.post('/', {
    preHandler: [authenticate, attachCcUser, requirePermission('control_center_users', 'create')],
  }, async (request, reply) => {
    const { email, display_name, role_id, password } = request.body ?? {}
    if (!email || !display_name || !role_id || !password) {
      return reply.code(422).send({
        success: false,
        error: { code: 'VALIDATION_ERROR', message: 'email, display_name, role_id, and password are required' },
      })
    }
    try {
      validatePasswordComplexity(password)
    } catch (err) {
      return sendValidation(reply, err)
    }
    const passwordHash = await hashPassword(password)
    const user = await createCcUserWithPassword({ email, display_name, role_id, password_hash: passwordHash })
    return reply.code(201).send({ success: true, data: user })
  })

  // List CC users
  app.get('/', {
    preHandler: [authenticate, attachCcUser, requirePermission('control_center_users', 'read')],
  }, async (request, reply) => {
    const { page = 1, limit = 20 } = request.query
    const result = await listCcUsers({ page: Number(page), limit: Number(limit) })
    return reply.send({ success: true, data: result })
  })

  // Self-service password change
  app.patch('/me/password', {
    preHandler: [authenticate, attachCcUser],
  }, async (request, reply) => {
    const { current_password, new_password } = request.body || {}
    if (!current_password || !new_password) {
      return reply.code(422).send({
        success: false,
        error: { code: 'VALIDATION_ERROR', message: 'current_password and new_password are required' },
      })
    }
    const ok = await verifyPassword(current_password, request.ccUser.password_hash)
    if (!ok) {
      return reply.code(401).send({
        success: false,
        error: { code: 'INVALID_CREDENTIALS', message: 'Current password is incorrect' },
      })
    }
    try {
      validatePasswordComplexity(new_password)
    } catch (err) {
      return sendValidation(reply, err)
    }
    const hash = await hashPassword(new_password)
    await updateCcUserPasswordHash(request.ccUser.id, hash)
    return reply.send({ success: true })
  })

  // Admin-forced password reset
  app.patch('/:id/password', {
    preHandler: [authenticate, attachCcUser, requirePermission('control_center_users', 'update')],
  }, async (request, reply) => {
    const { new_password } = request.body || {}
    if (!new_password) {
      return reply.code(422).send({
        success: false,
        error: { code: 'VALIDATION_ERROR', message: 'new_password is required' },
      })
    }
    try {
      validatePasswordComplexity(new_password)
    } catch (err) {
      return sendValidation(reply, err)
    }
    const hash = await hashPassword(new_password)
    await updateCcUserPasswordHash(request.params.id, hash)
    return reply.send({ success: true })
  })
}
