import type { HttpContext } from '@adonisjs/core/http'
import Category from '#models/category'
import logger from '@adonisjs/core/services/logger'
import { createCategoryValidator, updateCategoryValidator } from '#validators/category'

export default class CategoriesController {
  /**
   * Retrieve all categories.
   *
   * @returns An array of all categories.
   */
  async getAll() {
    return await Category.all()
  }

  /**
   * Retrieve a single category.
   *
   * @param request - The HTTP context containing the request data.
   * @returns The category with the specified id.
   */
  async getOne({ request }: HttpContext) {
    try {
      const id = request.body().id
      return await Category.find(id)
    } catch (error) {
      logger.error('Category retrieval failed: %s', error)
    }
  }

  /**
   * Create a category.
   *
   * @bodyParam *name* -  string | The name of the category.
   * @bodyParam *slug* -  string | The slug of the category.
   * @returns The created category.
   */
  async create({ request, auth }: HttpContext) {
    try {
      const data = await request.validateUsing(createCategoryValidator)
      const category = await Category.create(data)
      logger.info('Category created: %s by %s', category.name, auth.getUserOrFail().email)
      return category
    } catch (error) {
      logger.error('Category creation failed: %s', error)
      throw error
    }
  }

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

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