import { ApiValidationError } from "../../Models/Server.Error.model";
import { Body, Controller, Middlewares, Post, Response, Route, SuccessResponse } from "tsoa";
import { ClientsService } from "./Clients.Service";
import {
    IClient,
    CreateCustomClientParams,
    UpdateClientParams,
    PaginateOrganizationClientsParams,
    OrganizationClientsResults,
    FindClientByIdParams,
    OrganizationClientView,
    ClientMergeParams,
    DeleteClientParams,
} from "../../Models/Clients/Clients.Interface";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import {
    TextObjectFilterParams,
    TextObjectFilterResult,
} from "../../Models/TextObjectFilter.model";

@Route("clients/delete")
@Middlewares(authenticateMiddleware)
export class DeleteClientController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El cliente fue eliminado con éxito")
    @Post()
    public async deleteClient(
        @Body() requestBody: DeleteClientParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new ClientsService().deleteClient(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Done",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/merge")
@Middlewares(authenticateMiddleware)
export class MergeClientController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El cliente fue fusionado con éxito")
    @Post()
    public async mergeClient(
        @Body() requestBody: ClientMergeParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new ClientsService().clientMerge(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Done",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/create")
@Middlewares(authenticateMiddleware)
export class CreateCustomClientController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El empleado fue creado con exito")
    @Post()
    public async createCustomClient(
        @Body() requestBody: CreateCustomClientParams
    ): Promise<IClient | ApiValidationError> {
        try {
            const client = await new ClientsService().createCustomClient(requestBody);
            this.setStatus(200);
            return client;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/update")
@Middlewares(authenticateMiddleware)
export class UpdateCustomClientController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El empleado fue creado con exito")
    @Post()
    public async updateCustomClient(
        @Body() requestBody: UpdateClientParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new ClientsService().updateClient(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Done",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/find")
export class FindOrganizationClientsController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findOrganizationClients(
        @Body() requestBody: PaginateOrganizationClientsParams
    ): Promise<OrganizationClientsResults | ApiValidationError> {
        try {
            const clients = await new ClientsService().findOrganizationClients(requestBody);
            this.setStatus(200);
            return clients;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/filter-all")
export class AllOrganizationClientsController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async allOrganizationClients(
        @Body() requestBody: TextObjectFilterParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const clients = await new ClientsService().textObjectFilter(requestBody);
            this.setStatus(200);
            return clients;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("clients/find-by-id")
export class FindClientByIdController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findClientById(
        @Body() requestBody: FindClientByIdParams
    ): Promise<OrganizationClientView | ApiValidationError> {
        try {
            const client = await new ClientsService().findClientById(requestBody);
            this.setStatus(200);
            return client;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
