import { Controller, Post, Route, SuccessResponse, Body, Middlewares } from "tsoa";
import { ApiValidationError } from "../../Models/Server.Error.model";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import { authenticateMiddleware } from "../../middleware/authentication";
import {
    DeleteTemplateParams,
    FindTemplatesParams,
    GetDefaultTemplateParams,
    ITemplate,
    PaginateTemplatesParams,
    PaginateTemplatesResults,
    SaveTemplateParams,
} from "../../Models/Templates/Templates.Interface";
import { TemplatesService } from "./Templates.Service";
import { TextObjectFilterResult } from "../../Models/TextObjectFilter.model";

@Route("templates")
export class TemplatesController extends Controller {
    @SuccessResponse(201, "Saved")
    @Post("save")
    @Middlewares(authenticateMiddleware)
    public async saveTemplate(
        @Body() requestBody: SaveTemplateParams
    ): Promise<ITemplate | ApiValidationError> {
        try {
            const template = await new TemplatesService().saveTemplate(requestBody);
            this.setStatus(201);
            return template;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }

    @SuccessResponse(200, "Done")
    @Post("delete")
    @Middlewares(authenticateMiddleware)
    public async deleteTemplate(
        @Body() requestBody: DeleteTemplateParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new TemplatesService().deleteTemplate(requestBody);
            this.setStatus(200);
            return { success: true, message: "Plantilla borrada correctamente." };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }

    @SuccessResponse(200, "Done")
    @Post("paginate")
    @Middlewares(authenticateMiddleware)
    public async paginate(
        @Body() requestBody: PaginateTemplatesParams
    ): Promise<PaginateTemplatesResults | ApiValidationError> {
        try {
            const result = await new TemplatesService().paginate(requestBody);
            this.setStatus(200);
            return result;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }

    @SuccessResponse(200, "Done")
    @Post("get")
    @Middlewares(authenticateMiddleware)
    public async get(
        @Body() requestBody: FindTemplatesParams
    ): Promise<ITemplate | ApiValidationError> {
        try {
            const result = await new TemplatesService().getTemplate(requestBody);
            this.setStatus(200);
            return result;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }

    @SuccessResponse(200, "Done")
    @Post("filter-all")
    @Middlewares(authenticateMiddleware)
    public async textObjectFilter(
        @Body() requestBody: FindTemplatesParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const result = await new TemplatesService().textObjectFilter(requestBody);
            this.setStatus(200);
            return result;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }

    @SuccessResponse(200, "Done")
    @Post("get-default")
    @Middlewares(authenticateMiddleware)
    public async getDefaultTemplate(
        @Body() requestBody: GetDefaultTemplateParams
    ): Promise<string | ApiValidationError> {
        try {
            const result = await new TemplatesService().getDefaultTemplate(requestBody);
            this.setStatus(200);
            return result;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
