import { NextFunction, Request, Response } from "express";
import createHttpError from "http-errors";
import Category from "../models/category.model";
import { parseFields, validAttributes, validSort } from "../libs/utils";
import { Filterable, WhereOptions } from "sequelize";
import { CustomRequest } from "../types/custom.types";
import { VISIBILITY } from "../types/common.types";

export default class CategoryController {
    static async create(request: Request, response: Response, next: NextFunction) {
        try {
            const data = request.body || {};
            const logo = (request.files as any)?.logo?.[0]?.filename;
            const banner = (request.files as any)?.banner?.[0]?.filename;
            data.logo = logo || null;
            data.banner = banner || null;
            if (data?.id) delete data.id;
            const result = await Category.create(data);
            response.status(200).json(result.dataValues);
        } catch (error) {
            next(error);
        }
    }
    static async getAll(request: CustomRequest, response: Response, next: NextFunction) {
        try {
            const query = request?.query;
            const sortFields = parseFields(String(query?.sort));
            const order = validSort(sortFields, Category.getAttributes());
            const fields = parseFields(String(query?.fields || ''));
            const where : WhereOptions<Category>={};
            if(!request?.authority) where.status = VISIBILITY.VISIBLE;
            const result = await Category.findAll({
                where,
                order : order || [['rank','DESC'],['createdAt','DESC'],['name','ASC']],
                attributes : validAttributes(fields, Category.getAttributes())
            });
            response.status(200).json(result);
        } catch (error) {
            console.log(error)
            next(error);
        }
    }
    static async getByID(request: Request, response: Response, next: NextFunction) {
        try {
            const id = request?.params?.id;
            const data = await Category.findByPk(id);
            if (!data?.dataValues) throw createHttpError.NotFound("Category not found.");
            response.status(200).json(data);
        } catch (error) {
            next(error);
        }
    }
    static async updateById(request: Request, response: Response, next: NextFunction) {
        try {
            const id = request?.params?.id;
            const data = request.body || {};
            const logo = (request.files as any)?.logo?.[0]?.filename;
            const banner = (request.files as any)?.banner?.[0]?.filename;
            if (logo) data.logo = logo || null;
            if (banner) data.banner = banner || null;
            if (data?.id) delete data.id;
            const result = await Category.findByPk(id);
            if (!result?.dataValues) throw createHttpError.NotFound("Category not found.")
            else await result.update(data);
            response.status(203).json({
                message: 'Category updated.'
            });
        } catch (error) {
            next(error);
        }
    }
    static async deleteById(request: Request, response: Response, next: NextFunction) {
        try {
            const id = request?.params?.id;
            await Category.destroy({
                where: {
                    id: id,
                }
            })
            response.status(203).json({
                message: 'Category deleted.'
            });
        } catch (error) {
            next(error);
        }
    }
}