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

export class ActivityHandler {
    // set the class variables
    private getActivityServiceObject = async(request: Request) => {
        let variables = await Common.getVariables(request)
        let activityService = new ActivityService(variables);
        return activityService;
    }

    // Handles the creation of a new activity
    create = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { title, description, code, status } = request.payload as ActivityRequestObject;
            const createActivityInput: ActivityCreateServiceInput = { title, description, code, status };
            let activityObject: ActivityObjectInteface = await activityService.createActivity(createActivityInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activityObject }).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 activity
    update = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { title, description, code, status } = request.payload as ActivityRequestObject;
            const { id } = request.params as ActivityIdentifierObject;
            const updateActivityInput: ActivityUpdateServiceInput = { id, title, description, code, status };
            let activityObject: ActivityObjectInteface = await activityService.updateActivity(updateActivityInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activityObject }).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 activity
    delete = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { id } = request.params as ActivityIdentifierObject;
            const deleteActivityInput: ActivityDeleteServiceInput = { id };
            let activity: ActivityObjectInteface = await activityService.deleteActivity(deleteActivityInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activity }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get activity by id
    getById = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { id } = request.params as ActivityIdentifierObject;
            const getByIdInput: ActivityGetByIdServiceInput = { id };
            let activity: ActivityObjectInteface = await activityService.getById(getByIdInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activity }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get activity by code
    getByCode = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { code } = request.params as ActivityStringIdentifierObject;
            const getByCodeInput: ActivityGetByCodeServiceInput = { code };
            let activity: ActivityObjectInteface = await activityService.getByCode(getByCodeInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activity }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list activity with filter
    list = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            let listRequest = request.query as ActivityListRequestObject;
            const getActivitiesInput: ActivityGetActivitiesServiceInput = { listRequest };
            let activitys: ActivityPaginatedList = await activityService.getActivities(getActivitiesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activitys }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all activities with filter
    listAll = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            let listRequest = request.query as ActivityListAllRequestObject;
            const getAllActivitiesInput: ActivityGetAllActivitiesServiceInput = { listRequest };
            let activitys: ActivityObjectSummaryInteface[] = await activityService.getAllActivities(getAllActivitiesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activitys }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list activity revisions
    listRevisions = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            let listRequest = request.query as ActivityListRequestObject;
            const { id } = request.params as ActivityIdentifierObject;
            const getRevisionsInput: ActivityGetRevisionsServiceInput = { id, listRequest };
            let activitys: ActivityPaginatedList = await activityService.getActivityRevisions(getRevisionsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activitys }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // restore activity revision
    restoreRevision = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { id } = request.params as ActivityIdentifierObject;
            const restoreRevisionInput: ActivityRestoreRevisionServiceInput = { id };
            let activity: ActivityObjectInteface = await activityService.restoreRevision(restoreRevisionInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activity }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // set activity sort order
    setSortOrder = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { id } = request.params as ActivityIdentifierObject;
            const { before, after } = request.payload as ActivitySortRequest;
            const setSortOrderInput: ActivitySetSortOrderServiceInput = { id, before, after };
            let sortOrder = await activityService.setSortOrder(setSortOrderInput);
            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 activity status
    updateStatus = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let activityService = await this.getActivityServiceObject(request);
            const { id } = request.params as ActivityIdentifierObject;
            const { status } = request.payload as ActivityStatusObject;
            const updateStatusInput: ActivityUpdateStatusServiceInput = { id, status };
            let activity = await activityService.updateStatus(updateStatusInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: activity }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }
}
