text: const asyncWrapper = require('../middleware/asyncWrapper');
  const ErrorResponse = require('../utils/ErrorResponse');
  const Category = require('../models/Category');
  const Bookmark = require('../models/Bookmark');
  const Config = require('../models/Config');
  const { Sequelize } = require('sequelize');
  
  // @desc      Create new category
  // @route     POST /api/categories
  // @access    Public
  exports.createCategory = asyncWrapper(async (req, res, next) => {
    // Get config from database
    const pinCategories = await Config.findOne({
      where: { key: 'pinCategoriesByDefault' },
    });
  
    let category;
  
    if (pinCategories) {
      if (parseInt(pinCategories.value)) {
        category = await Category.create({
          ...req.body,
          isPinned: true,
        });
      } else {
        category = await Category.create(req.body);
      }
    }
  
    res.status(201).json({
      success: true,
      data: category,
    });
  });
  
  // @desc      Get all categories
  // @route     GET /api/categories
  // @access    Public
  exports.getCategories = asyncWrapper(async (req, res, next) => {
    // Get config from database
    const useOrdering = await Config.findOne({
      where: { key: 'useOrdering' },
    });
  
    const orderType = useOrdering ? useOrdering.value : 'createdAt';
    let categories;
  
    if (orderType == 'name') {
      categories = await Category.findAll({
        include: [
          {
            model: Bookmark,
            as: 'bookmarks',
          },
        ],
        order: [[Sequelize.fn('lower', Sequelize.col('Category.name')), 'ASC']],
      });
    } else {
      categories = await Category.findAll({
        include: [
          {
            model: Bookmark,
            as: 'bookmarks',
          },
        ],
        order: [[orderType, 'ASC']],
      });
    }
  
    res.status(200).json({
      success: true,
      data: categories,
    });
  });
  
  // @desc      Get single category
  // @route     GET /api/categories/:id
  // @access    Public
  exports.getCategory = asyncWrapper(async (req, res, next) => {
    const category = await Category.findOne({
      where: { id: req.params.id },
      include: [
        {
          model: Bookmark,
          as: 'bookmarks',
        },
      ],
    });
  
    if (!category) {
      return next(
        new ErrorResponse(
          `Category with id of ${req.params.id} was not found`,
          404
        )
      );
    }
  
    res.status(200).json({
      success: true,
      data: category,
    });
  });
  
  // @desc      Update category
  // @route     PUT /api/categories/:id
  // @access    Public
  exports.updateCategory = asyncWrapper(async (req, res, next) => {
    let category = await Category.findOne({
      where: { id: req.params.id },
    });
  
    if (!category) {
      return next(
        new ErrorResponse(
          `Category with id of ${req.params.id} was not found`,
          404
        )
      );
    }
  
    category = await category.update({ ...req.body });
  
    res.status(200).json({
      success: true,
      data: category,
    });
  });
  
  // @desc      Delete category
  // @route     DELETE /api/categories/:id
  // @access    Public
  exports.deleteCategory = asyncWrapper(async (req, res, next) => {
    const category = await Category.findOne({
      where: { id: req.params.id },
      include: [
        {
          model: Bookmark,
          as: 'bookmarks',
        },
      ],
    });
  
    if (!category) {
      return next(
        new ErrorResponse(
          `Category with id of ${req.params.id} was not found`,
          404
        )
      );
    }
  
    category.bookmarks.forEach(async (bookmark) => {
      await Bookmark.destroy({
        where: { id: bookmark.id },
      });
    });
  
    await Category.destroy({
      where: { id: req.params.id },
    });
  
    res.status(200).json({
      success: true,
      data: {},
    });
  });
  
  // @desc      Reorder categories
  // @route     PUT /api/categories/0/reorder
  // @access    Public
  exports.reorderCategories = asyncWrapper(async (req, res, next) => {
    req.body.categories.forEach(async ({ id, orderId }) => {
      await Category.update(
        { orderId },
        {
          where: { id },
        }
      );
    });
  
    res.status(200).json({
      success: true,
      data: {},
    });
  });
  