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

export class EmailTemplateHandler {
    // set the class variables
    private getEmailTemplateServiceObject = async (request: Request) => {
        let variables = await Common.getVariables(request)
        let emailTemplateService = new EmailTemplateService(variables);
        return emailTemplateService;
    }

    // Handles the creation of a new Email Template
    create = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { title, code, subject, body, status, emailTemplateAttachmentIds } = request.payload as EmailTemplateRequestObject;
            const createEmailTemplateInput: EmailTemplateCreateServiceInput = { title, code, subject, body, status, emailTemplateAttachmentIds };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.createEmailTemplate(createEmailTemplateInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).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 Email Template
    update = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { title, code, subject, body, status, emailTemplateAttachmentIds } = request.payload as EmailTemplateRequestObject;
            const { id } = request.params as EmailTemplateIdentifierObject;
            const updateEmailTemplateInput: EmailTemplateUpdateServiceInput = { id, title, code, subject, body, status, emailTemplateAttachmentIds };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.updateEmailTemplate(updateEmailTemplateInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).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 Email Template
    delete = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { id } = request.params as EmailTemplateIdentifierObject;
            const deleteEmailTemplateInput: EmailTemplateDeleteServiceInput = { id };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.deleteEmailTemplate(deleteEmailTemplateInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get email template by id
    getById = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { id } = request.params as EmailTemplateIdentifierObject;
            const getEmailTemplateByIdInput: EmailTemplateGetByIdServiceInput = { id };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.getById(getEmailTemplateByIdInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // get email template by code
    getByCode = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { code } = request.params as { code: string };
            const getEmailTemplateByCodeInput: EmailTemplateGetByCodeServiceInput = { code };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.getByCode(getEmailTemplateByCodeInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list email Templates with filter
    list = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            let listRequest = request.query as EmailTemplateListRequestObject;
            const getEmailTemplatesInput: EmailTemplateGetListServiceInput = { listRequest };
            let emailTemplates: EmailTemplatePaginatedList = await emailTypeService.getEmailTemplates(getEmailTemplatesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplates }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list all email Templates with filter
    listAll = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            let listRequest = request.query as EmailTemplateListAllRequestObject;
            const getAllEmailTemplatesInput: EmailTemplateGetAllListServiceInput = { listRequest };
            let emailTemplates: EmailTemplateObjectSummaryInteface[] = await emailTypeService.getAllEmailTemplates(getAllEmailTemplatesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplates }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // list  revisions of the email template
    listRevisions = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            let listRequest = request.query as EmailTemplateListRequestObject;
            let { id } = request.params as EmailTemplateIdentifierObject;
            const getEmailTemplateRevisionsInput: EmailTemplateGetRevisionsServiceInput = { id, listRequest };
            let emailTemplates: EmailTemplatePaginatedList = await emailTypeService.getEmailTemplatesRevisions(getEmailTemplateRevisionsInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplates }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // restore email template revision
    restoreRevision = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { id } = request.params as EmailTemplateIdentifierObject;
            const restoreRevisionInput: EmailTemplateRestoreRevisionServiceInput = { id };
            let emailTemplate: EmailTemplateObjectInteface = await emailTypeService.restoreRevision(restoreRevisionInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // send a test email
    sendTestMail = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let { emailTemplateCode, replacements } = request.payload as { emailTemplateCode: string, replacements: Object }
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            emailTypeService.sendEmailTemplate(emailTemplateCode, [process.env.TEST_TO_EMAIL!], replacements, [1], [process.env.TEST_CC_EMAIL!], [process.env.TEST_BCC_EMAIL!]);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY"}).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_SERVICE', err);
        }
    }

    // set email template sort order
    setSortOrder = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { id } = request.params as EmailTemplateIdentifierObject;
            const { before, after } = request.payload as EmailTemplateSortRequest;
            const setSortOrderInput: EmailTemplateSetSortOrderServiceInput = { id, before, after };
            let sortOrder = await emailTypeService.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 email Template status
    updateStatus = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            let emailTypeService = await this.getEmailTemplateServiceObject(request);
            const { id } = request.params as EmailTemplateIdentifierObject;
            const { status } = request.payload as EmailTemplateStatusObject;
            const updateEmailTemplateStatusInput: EmailTemplateUpdateStatusServiceInput = { id, status };
            let emailTemplate = await emailTypeService.updateStatus(updateEmailTemplateStatusInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: emailTemplate }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_HANDLER', err);
        }
    }
}
