import { ApiValidationError } from "../../Models/Server.Error.model";
import {
    Body,
    FormField,
    UploadedFile,
    Controller,
    Middlewares,
    Post,
    Response,
    Route,
    SuccessResponse,
} from "tsoa";
import { CompaniesService } from "./Companies.Service";
import {
    ICompany,
    CreateCompanyParams,
    UpdateCompanyParams,
    PaginateCompaniesParams,
    PaginateCompaniesResults,
    DeleteCompanyFileParams,
    MyOranizationsViewParams,
    MyOranizationsView,
    OranizationsViewByIdParams,
    DeleteCompanyParams,
    SetOrganizationPublishedStatusParams,
    SetNotificationAutoParams,
    FixCompanyPostParams,
    MoveCompanyFixedPostParams,
} from "../../Models/Companies/Companies.Interface";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import { TextObjectFilterResult } from "../../Models/TextObjectFilter.model";

@Route("companies/toggle-fixed-post")
@Middlewares(authenticateMiddleware)
export class ToggleCompanyFixedPostController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async toggleFixedCompanyPost(
        @Body() requestBody: FixCompanyPostParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().toggleFixedPost(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("companies/move-fixed-post")
@Middlewares(authenticateMiddleware)
export class MoveCompanyFixedPostController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async moveFixedCompanyPost(
        @Body() requestBody: MoveCompanyFixedPostParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().moveFixedPost(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("companies/set-notifications-status")
@Middlewares(authenticateMiddleware)
export class SetNotificationsStatusCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async setNotificationAuto(
        @Body() requestBody: SetNotificationAutoParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().setNotificationAuto(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("companies/set-published-status")
@Middlewares(authenticateMiddleware)
export class SetPublishedStatusCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async setPublishedStatus(
        @Body() requestBody: SetOrganizationPublishedStatusParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().setPublishedStatus(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("companies/create")
@Middlewares(authenticateMiddleware)
export class CreateCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "La compañia fue creada con exito")
    @Post()
    public async createCompany(
        @Body() requestBody: CreateCompanyParams
    ): Promise<ICompany | ApiValidationError> {
        try {
            const company = await new CompaniesService().createCompany(requestBody);
            this.setStatus(200);
            return company;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("companies/delete")
@Middlewares(authenticateMiddleware)
export class DeleteCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "La compañia fue modificada con exito")
    @Post()
    public async deleteCompany(
        @Body() requestBody: DeleteCompanyParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().deleteCompany(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("companies/update")
@Middlewares(authenticateMiddleware)
export class UpdateCompanyController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "La compañia fue modificada con exito")
    @Post()
    public async updateCompany(
        @Body() requestBody: UpdateCompanyParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().updateCompany(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("companies/get-by-id")
export class GetCompanyByIdController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async getById(
        @Body() requestBody: OranizationsViewByIdParams
    ): Promise<MyOranizationsView | ApiValidationError> {
        try {
            const companies = await new CompaniesService().getById(requestBody);
            this.setStatus(200);
            return companies;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("companies/get-by-user")
export class GetCompanyByUserController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async getByUserId(
        @Body() requestBody: MyOranizationsViewParams
    ): Promise<MyOranizationsView[] | ApiValidationError> {
        try {
            const companies = await new CompaniesService().getByUserId(requestBody);
            this.setStatus(200);
            return companies;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

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

@Route("companies/upload-header")
@Middlewares([authenticateMiddleware])
export class UploadCompanyHeaderController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El archivo fue cargado con exito")
    @Post()
    public async uploadHeader(
        @FormField() companyId: string,
        @FormField() sessionUser: string,
        @UploadedFile() file: Express.Multer.File
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().setCompanyHeader({
                companyId,
                sessionUser,
                file,
            });
            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("companies/upload-icon")
@Middlewares([authenticateMiddleware])
export class UploadCompanyIconController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El archivo fue cargado con exito")
    @Post()
    public async uploadIcon(
        @FormField() companyId: string,
        @FormField() sessionUser: string,
        @UploadedFile() file: Express.Multer.File
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().setCompanyIcon({
                companyId,
                sessionUser,
                file,
            });
            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);
        }
    }
}

//Create controller for delete Header

@Route("companies/delete-header")
@Middlewares([authenticateMiddleware])
export class DeleteCompanyHeaderController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El archivo fue cargado con exito")
    @Post()
    public async deleteHeader(
        @Body() data: DeleteCompanyFileParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().deleteCompanyHeader(data);
            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("companies/delete-icon")
@Middlewares([authenticateMiddleware])
export class DeleteCompanyIconController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "El archivo fue cargado con exito")
    @Post()
    public async deleteIcon(
        @Body() data: DeleteCompanyFileParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CompaniesService().deleteCompanyIcon(data);
            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("companies/filter-all")
export class filterAllOrganizationsController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async filterAllOrganizations(
        @Body() requestBody: PaginateCompaniesParams
    ): Promise<TextObjectFilterResult[] | ApiValidationError> {
        try {
            const clients = await new CompaniesService().filterAll(requestBody);
            this.setStatus(200);
            return clients;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("companies/check-name")
export class CheckCompanyNameController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async checkName(
        @Body() requestBody: { name: string }
    ): Promise<{ valid: boolean } | ApiValidationError> {
        try {
            const valid = await new CompaniesService().checkNameExists(requestBody.name);
            this.setStatus(200);
            return { valid };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
