import { NextFunction, Request, Response } from "express";
import { ROLE, STATE } from "../types/common.types";
import Authority, { AuthorityCreateSchema } from "../models/authority.model";
import { parseFields, validAttributes, validSort } from "../libs/utils";
import createHttpError from "http-errors";
import { CustomRequest } from "../types/custom.types";

export default class AuthorityController {
    static async create(request: Request, response: Response, next: NextFunction) {
        try {
            const data: AuthorityCreateSchema = {};
            if (request?.body?.email) data.email = request?.body?.email;
            if (request?.body?.role) data.role = request?.body?.role === 'MODERATOR' ? ROLE.MODERATOR : ROLE.ADMIN;
            if (request?.body?.status) data.status = request?.body?.status === 'INACTIVE' ? STATE.INACTIVE : STATE.ACTIVE;
            const result = await Authority.create(data);
            response.status(203).json(result?.dataValues);
        } catch (error) {
            next(error)
        }
    }
    static async getAll(request: Request, response: Response, next: NextFunction) {
        try {
            const query = request?.query;
            const sortFields = parseFields(String(query?.sort));
            const order = validSort(sortFields, Authority.getAttributes());
            const fields = parseFields(String(query?.fields || ''));
            const result = await Authority.findAll({
                order: order || [['role', 'DESC'], ['createdAt', 'DESC']],
                attributes: validAttributes(fields, Authority.getAttributes()),
            });
            response.status(203).json(result);
        } catch (error) {
            next(error)
        }
    }
    static async getById(request: Request, response: Response, next: NextFunction) {
        try {
            const result = await Authority.findByPk(request?.params?.id);
            response.status(203).json(result?.dataValues);
        } catch (error) {
            next(error)
        }
    }
    static async updateById(request: Request, response: Response, next: NextFunction) {
        try {
            const id = Number(request?.params?.id);
            const authority = await Authority.findByPk(id);
            if (!authority?.dataValues?.id) throw createHttpError.NotFound('Authority not found.');
            const data: any = {};
            if (request?.body?.email) data.email = request?.body?.email;
            if (request?.body?.role) data.role = request?.body?.role === 'MODERATOR' ? ROLE.MODERATOR : ROLE.ADMIN;
            if (request?.body?.status) data.status = request?.body?.status === 'INACTIVE' ? STATE.INACTIVE : STATE.ACTIVE;
            await authority.update(data);
            response.status(203).json({
                message: 'Authority updated.'
            });
        } catch (error) {
            next(error)
        }
    }
    static async deleteById(request: Request, response: Response, next: NextFunction) {
        try {
            const id = Number(request?.params?.id);
            const result = await Authority.destroy({
                where: { id }
            });
            response.status(203).json({
                message: 'Authority removed.'
            });
        } catch (error) {
            next(error)
        }
    }
    static async myProfile(request: CustomRequest, response: Response, next: NextFunction) {
        try {
            const email = request.user?.email;
            const authority = await Authority.findOne({
                where: {
                    email: email
                }
            });
            if (!authority?.dataValues?.id) throw createHttpError.BadRequest('Only for authority');
            response.status(200).json({
                ...authority.dataValues,
                ...request.user,
            })
        } catch (error) {
            next(error)
        }
    }
}