import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
import logger from '@adonisjs/core/services/logger'
import { createUserValidator, updateUserValidator } from '#validators/user'

export default class UsersController {
  /**
   * Retrieve all users.
   *
   * @returns An array of all users.
   */
  async getAll() {
    return await User.all()
  }

  /**
   * Retrieve a single user.
   *
   * @param request - The HTTP context containing the request data.
   * @param response - The HTTP context's response object.
   * @returns The user with the specified id.
   */
  async getOne({ request, response }: HttpContext) {
    try {
      const id = request.body().id
      const user = await User.find(id)
      if (!user) {
        return response.notFound({ message: 'User not found' })
      }
      return user
    } catch (error) {
      logger.error('User retrieval failed: %s', error)
      return response.internalServerError({ message: 'User retrieval failed' })
    }
  }
  async create({ request, auth, response }: HttpContext) {
    try {
      const data = await request.validateUsing(createUserValidator)
      const user = await User.create(data)
      logger.info('User created: %s by %s', user.email, auth.getUserOrFail().email)
      return user
    } catch (error) {
      logger.error('User creation failed: %s', error)
      return response.internalServerError({ message: 'User creation failed' })
    }
  }

  /**
   * Update a user.
   *
   * @bodyParam *id* -  number | The id of the user to update.
   * @bodyParam *email* -  string | The new email of the user.
   * @bodyParam *fullName* -  string | The new full name of the user.
   * @bodyParam *role* -  string | The new role of the user.
   */
  async update({ request, auth, response }: HttpContext) {
    try {
      const data = await request.validateUsing(updateUserValidator)
      const user = await User.find(data.id)
      if (!user) {
        return response.notFound({ message: 'User not found' })
      }
      user.merge(data)
      await user.save()
      logger.info('User updated: %s by %s', user.email, auth.getUserOrFail().email)
      return user
    } catch (error) {
      logger.error('User update failed: %s', error)
      return response.internalServerError({ message: 'User update failed' })
    }
  }

  /**
   * Delete a user.
   *
   * @bodyParam *id* - number | The id of the user to delete.
   */
  async delete({ request, auth, response }: HttpContext) {
    const id = request.body().id
    try {
      const user = await User.find(id)
      if (!user) {
        return response.notFound({ message: 'User not found' })
      }
      await user.delete()
      logger.info('User deleted: %s by %s', user.email, auth.getUserOrFail().email)
      return response.ok({ message: 'User deleted' })
    } catch (error) {
      logger.error('User deletion failed: %s', error)
      return response.internalServerError({ message: 'User deletion failed' })
    }
  }
}
