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

export class LanguageHandler {
    private getLanguageServiceObject = async (request: Request) => {
        const variables = await Common.getVariables(request);
        return new LanguageService(variables);
    }

    create = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { name, code, isDefault, isDriverEnabled, isCustomerEnabled, status } = request.payload as LanguageRequestObject;
            const createLanguageInput: LanguageCreateServiceInput = { name, code, isDefault, isDriverEnabled, isCustomerEnabled, status };
            const language = await languageService.createLanguage(createLanguageInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(201);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    getById = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { id } = request.params as LanguageIdentifierObject;
            const getLanguageByIdInput: LanguageGetByIdServiceInput = { id };
            const language = await languageService.getById(getLanguageByIdInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    getByCode = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { code } = request.params as LanguageStringIdentifierObject;
            const getLanguageByCodeInput: LanguageGetByCodeServiceInput = { code };
            const language = await languageService.getByCode(getLanguageByCodeInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    update = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { name, code, isDefault, isDriverEnabled, isCustomerEnabled, status } = request.payload as LanguageRequestObject;
            const { id } = request.params as LanguageIdentifierObject;
            const updateLanguageInput: LanguageUpdateServiceInput = { id, name, code, isDefault, isDriverEnabled, isCustomerEnabled, status };
            const language = await languageService.updateLanguage(updateLanguageInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    updateStatus = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { id } = request.params as LanguageIdentifierObject;
            const { status } = request.payload as LanguageStatusObject;
            const updateLanguageStatusInput: LanguageUpdateStatusServiceInput = { id, status };
            const language = await languageService.updateStatus(updateLanguageStatusInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    updateEnablement = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { id } = request.params as LanguageIdentifierObject;
            const { isDriverEnabled, isCustomerEnabled } = request.payload as LanguageEnablementObject;
            const updateLanguageEnablementInput: LanguageUpdateEnablementServiceInput = { id, isDriverEnabled, isCustomerEnabled };
            const language = await languageService.updateEnablement(updateLanguageEnablementInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    delete = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const { id } = request.params as LanguageIdentifierObject;
            const deleteLanguageInput: LanguageDeleteServiceInput = { id };
            const language = await languageService.deleteLanguage(deleteLanguageInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: language }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    list = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const listRequest = request.query as LanguageListRequestObject;
            const getLanguagesInput: LanguageGetLanguagesServiceInput = { listRequest };
            const languages = await languageService.getLanguages(getLanguagesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: languages }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }

    listAll = async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
        try {
            const languageService = await this.getLanguageServiceObject(request);
            const listRequest = request.query as LanguageListAllRequestObject;
            const getAllLanguagesInput: LanguageGetAllLanguagesServiceInput = { listRequest };
            const languages = await languageService.getAllLanguages(getAllLanguagesInput);
            return h.response({ message: "REQUEST_PROCESSED_SUCCESSFULLY", responseData: languages }).code(200);
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_IN_LANGUAGE_SERVICE', err);
        }
    }
}
