import { Request, ResponseToolkit, ResponseObject } from '@hapi/hapi';
import { RoleService } from "../services/role.service";
import { AppError } from "../../utils/errors";
import { Common } from "../../utils/common"

export class RoleHandler {
    // set the class variables
    private getRoleServiceObject = async (request: Request) => {
        let variables = await Common.getVariables(request);
        let roleService = new RoleService(variables);
        return roleService;
    }

    // Handles the creation of a new Category Type
    create = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { name, description, permissionIds, status } = request.payload as RoleRequestObject;
            const createRoleInput: RoleCreateServiceInput = { name, description, permissionIds, status };
            let role = await roleService.createRole(createRoleInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(201);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // Handles the updation of a Category Type
    update = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { name, description, permissionIds, status } = request.payload as RoleRequestObject;
            const { id } = request.params as RoleIdentifierObject;
            const updateRoleInput: RoleUpdateServiceInput = { id, name, description, permissionIds, status };
            let role = await roleService.updateRole(updateRoleInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // Handles the Deletion of a Category Type
    delete = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { id } = request.params as RoleIdentifierObject;
            const deleteRoleInput: RoleDeleteServiceInput = { id };
            let role = await roleService.deleteRole(deleteRoleInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // Handles the Deletion of a Category Type
    getById = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { id } = request.params as RoleIdentifierObject;
            const getRoleByIdInput: RoleGetByIdServiceInput = { id };
            let role = await roleService.getById(getRoleByIdInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // Handles the Deletion of a Category Type
    getByCode = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { code } = request.params as RoleStringIdentifierObject;
            const getRoleByCodeInput: RoleGetByCodeServiceInput = { code };
            let role = await roleService.getByCode(getRoleByCodeInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list category types with filter
    list = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            let listRequest = request.query as RoleListRequestObject;
            const listRolesInput: RoleListRolesServiceInput = { listRequest };
            let role = await roleService.listRoles(listRolesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // listAll category types with filter
    listAll = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            let listRequest = request.query as RoleListAllRequestObject;
            const listAllRolesInput: RoleListAllRolesServiceInput = { listRequest };
            let role = await roleService.listAllRoles(listAllRolesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all revisions of the content
    listRevisions = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            let listRequest = request.query as RoleListRequestObject;
            let { id } = request.params as RoleIdentifierObject;
            const listRoleRevisionsInput: RoleListRoleRevisionsServiceInput = { id, listRequest };
            let role = await roleService.listRoleRevisions(listRoleRevisionsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all revisions of the content
    restoreRevision = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { id } = request.params as RoleIdentifierObject;
            const restoreRoleRevisionInput: RoleRestoreRevisionServiceInput = { id };
            let role = await roleService.restoreRevision(restoreRoleRevisionInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // set role sortOrder
    setSortOrder = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { id } = request.params as RoleIdentifierObject;
            const { before, after } = request.payload as RoleSortRequest;
            const setRoleSortOrderInput: RoleSetSortOrderServiceInput = { id, before, after };
            let sortOrder = await roleService.setSortOrder(setRoleSortOrderInput);
            if (sortOrder)
                return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY" }).code(200);
            else {
                throw new AppError(400, 'ERROR_WHILE_UPDATING_SORT_ORDER', {});
            }
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // update role status
    updateStatus = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let roleService = await this.getRoleServiceObject(request);
            const { id } = request.params as RoleIdentifierObject;
            const { status } = request.payload as RoleStatusObject;
            const updateRoleStatusInput: RoleUpdateStatusServiceInput = { id, status };
            let role = await roleService.updateStatus(updateRoleStatusInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: role }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }
}
