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

export class FaqHandler {
    // set the class variables
    private getFaqServiceObject = async (request: Request) => {
        let variables = await Common.getVariables(request)
        let faqService = new FaqService(variables);
        return faqService;
    }
    // Handles the creation of a new faq
    create = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { question, answer, categoryCode, status } = request.payload as faqRequest;
            const createFaqInput: FaqCreateServiceInput = { question, answer, categoryCode, status };
            let faq: faqObjectInteface = await faqService.createFaq(createFaqInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).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 faq
    update = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { question, answer, categoryCode, status } = request.payload as faqRequest;
            const { id } = request.params as FaqIdentifierObject;
            const updateFaqInput: FaqUpdateServiceInput = { id, question, answer, categoryCode, status };
            let faq: faqObjectInteface = await faqService.updateFaq(updateFaqInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).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 faq
    delete = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { id } = request.params as FaqIdentifierObject;
            const deleteFaqInput: FaqDeleteServiceInput = { id };
            let faq: faqObjectInteface = await faqService.deleteFaq(deleteFaqInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get faq by id
    getById = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { id } = request.params as FaqIdentifierObject;
            const getFaqByIdInput: FaqGetByIdServiceInput = { id };
            let faq: faqObjectInteface = await faqService.getById(getFaqByIdInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get faq by code
    getByCode = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { code } = request.params as FaqStringIdentifierObject;
            const getFaqByCodeInput: FaqGetByCodeServiceInput = { code };
            let faq: faqObjectInteface = await faqService.getByCode(getFaqByCodeInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list faqs with filter
    list = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            let listRequest = request.query as FaqListRequestObject;
            const getFaqsInput: FaqGetFaqsServiceInput = { listRequest };
            let faqs: FaqPaginatedList = await faqService.getFaqs(getFaqsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faqs }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all faqs with filter
    listAll = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            let listRequest = request.query as FaqListAllRequestObject;
            const getAllFaqsInput: FaqGetAllFaqsServiceInput = { listRequest };
            let faqs: faqObjectSummaryInteface[] = await faqService.getAllFaqs(getAllFaqsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faqs }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all revisions for a faq
    listRevisions = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            let listRequest = request.query as FaqListRequestObject;
            const { id } = request.params as FaqIdentifierObject;
            const getFaqRevisionsInput: FaqGetFaqRevisionsServiceInput = { id, listRequest };
            let faqs: FaqPaginatedList = await faqService.getFaqsRevisions(getFaqRevisionsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faqs }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // restore revision for a faq
    restoreRevision = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { id } = request.params as FaqIdentifierObject;
            const restoreFaqRevisionInput: FaqRestoreRevisionServiceInput = { id };
            let faq = await faqService.restoreRevision(restoreFaqRevisionInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faq }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // set faq sortOrder
    setSortOrder = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { id } = request.params as FaqIdentifierObject;
            const { before, after } = request.payload as FaqSortRequest;
            const setFaqSortOrderInput: FaqSetSortOrderServiceInput = { id, before, after };
            let sortOrder = await faqService.setSortOrder(setFaqSortOrderInput);
            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 faq status
    updateStatus = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            const { id } = request.params as FaqIdentifierObject;
            const { status } = request.payload as FaqStatusObject;
            const updateFaqStatusInput: FaqUpdateStatusServiceInput = { id, status };
            let category = await faqService.updateStatus(updateFaqStatusInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: category }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    //public list faqs with filter
    publicList = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let faqService = await this.getFaqServiceObject(request);
            let listRequest = request.query as FaqListRequestObject;
            const status = 1;
            const publicFaqsInput: FaqGetFaqsServiceInput = { listRequest, status };
            let faqs: FaqPaginatedList = await faqService.getFaqs(publicFaqsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: faqs }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }
}
