import { ApiValidationError } from "../../Models/Server.Error.model";
import { Body, Controller, Middlewares, Post, Response, Route, SuccessResponse } from "tsoa";
import { EmployeesService } from "./Employees.Service";
import {
    IEmployee,
    CreateEmployeeParams,
    FindEmployeesParams,
    PaginateEmployeesParams,
    PaginateEmployeesResults,
    ValidateEmployeeParams,
    CompanyEmployeesView,
    FindEmployeesByIdParams,
    UpdateEmployeeRolesParams,
    UpdateEmployeeParams,
    IncompleteCollaboratorView,
} from "../../Models/Employees/Employees.Interface";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import {
    CreateEmployeeServiceParams,
    UpdateEmployeeServiceParams,
    FindEmployeesServicesParams,
    DeleteEmployeeServiceParams,
    IEmployeeService,
    FindCollaboratorServicesParams,
    CollaboratorServiceView,
    UpdateCollaboratorServicesParams,
    FindEmployeesByServiceParams,
} from "../../Models/EmployeesServices/EmployeesServices.Interface";
import { TextObjectFilterResult } from "../../Models/TextObjectFilter.model";

@Route("employees/create")
@Middlewares(authenticateMiddleware)
export class CreateEmplyeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El empleado fue creado con exito")
    @Post()
    public async createEmplyee(
        @Body() requestBody: CreateEmployeeParams
    ): Promise<IEmployee | ApiValidationError> {
        try {
            const employee = await new EmployeesService().createEmployee(requestBody);
            this.setStatus(200);
            return employee;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/update-roles")
@Middlewares(authenticateMiddleware)
export class UpdateEmplyeeRolesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Los roles fueron actualizados con éxito")
    @Post()
    public async updateEmplyeeRoles(
        @Body() requestBody: UpdateEmployeeRolesParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().updateEmployeeRoles(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("employees/get-all-services")
export class GetAllCollaboratorServicesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async getAllCollaboratorServices(
        @Body() requestBody: FindCollaboratorServicesParams
    ): Promise<CollaboratorServiceView | ApiValidationError> {
        try {
            const services = await new EmployeesService().findAllServicesByCollaborator(
                requestBody
            );
            this.setStatus(200);
            return services;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/get-by-company")
export class GetEmployeesByCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findByCompanyId(
        @Body() requestBody: FindEmployeesParams
    ): Promise<CompanyEmployeesView[] | ApiValidationError> {
        try {
            const employees = await new EmployeesService().findByCompanyId(requestBody);
            this.setStatus(200);
            return employees;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/get-by-id")
export class GetEmployeesByIdController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findEmployeeById(
        @Body() requestBody: FindEmployeesByIdParams
    ): Promise<CompanyEmployeesView | ApiValidationError> {
        try {
            const employee = await new EmployeesService().findById(requestBody);
            this.setStatus(200);
            return employee;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/paginate")
export class PaginateEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async paginateUsers(
        @Body() requestBody: PaginateEmployeesParams
    ): Promise<PaginateEmployeesResults | ApiValidationError> {
        try {
            const users = await new EmployeesService().paginateEmployees(requestBody);
            this.setStatus(200);
            return users;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/validate-guest")
@Middlewares(authenticateMiddleware)
export class ValidateGuestEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async validateGuest(
        @Body() requestBody: ValidateEmployeeParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().validateGuest(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("employees/reject-guest")
@Middlewares(authenticateMiddleware)
export class RejectGuestEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async rejectGuest(
        @Body() requestBody: ValidateEmployeeParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().rejectGuest(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("employees/validate-host")
@Middlewares(authenticateMiddleware)
export class ValidateHostEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async validateHost(
        @Body() requestBody: ValidateEmployeeParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().validateHost(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("employees/update-collaborator-services")
@Middlewares(authenticateMiddleware)
export class UpdateCollaboratorServicesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async updateCollaboratorServices(
        @Body() requestBody: UpdateCollaboratorServicesParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().updateCollaboratorServices(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("employees/add-service")
@Middlewares(authenticateMiddleware)
export class AddServiceEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async validateHost(
        @Body() requestBody: CreateEmployeeServiceParams
    ): Promise<IEmployeeService | ApiValidationError> {
        try {
            const emplyeeService = await new EmployeesService().addService(requestBody);
            this.setStatus(200);
            return emplyeeService;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/update-service")
@Middlewares(authenticateMiddleware)
export class UpdateServiceEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async updateService(
        @Body() requestBody: UpdateEmployeeServiceParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().updateService(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("employees/get-services")
export class GetEmployeeServicesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async getServices(
        @Body() requestBody: FindEmployeesServicesParams
    ): Promise<IEmployeeService[] | ApiValidationError> {
        try {
            const emplyeesServices = await new EmployeesService().getServices(requestBody);
            this.setStatus(200);
            return emplyeesServices;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/quit-service")
@Middlewares(authenticateMiddleware)
export class QuitEmployeeServiceController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async deleteService(
        @Body() requestBody: DeleteEmployeeServiceParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().deleteServices(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("employees/filter-all")
export class AllOrganizationEmployeeController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async allOrganizationEmployee(
        @Body() requestBody: FindEmployeesParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const clients = await new EmployeesService().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("employees/services-filter-all")
export class AllOrganizationEmployeeServicesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async allOrganizationEmployeeServices(
        @Body() requestBody: FindEmployeesServicesParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const clients = await new EmployeesService().textObjectFilterServicesByCollaborator(
                requestBody
            );
            this.setStatus(200);
            return clients;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/employees-by-service")
export class FindEmployeesByServiceController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findEmployeesByService(
        @Body() requestBody: FindEmployeesByServiceParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const employees = await new EmployeesService().findByService(requestBody);
            this.setStatus(200);
            return employees;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("employees/update")
export class EmployeesUpdateController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async updateEmployeeService(
        @Body() requestBody: UpdateEmployeeParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new EmployeesService().updateEmployee(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("employees/get-incomplete-setup")
export class GetIncompleteSetupController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    @Middlewares(authenticateMiddleware)
    public async getIncompleteSetup(
        @Body() requestBody: { sessionUser: string }
    ): Promise<IncompleteCollaboratorView[] | ApiValidationError> {
        try {
            const result = await new EmployeesService().getIncompleteSetup(requestBody.sessionUser);
            this.setStatus(200);
            return result;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
