import { ListProfilesUseCase } from '@app/usecase/profiles/list-profiles.usecase'; import { inject, Injectable, signal } from '@angular/core'; import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token'; import { Profile, ProfilePaginated } from '@app/domain/profiles/profile.model'; import { ProfilePresenter } from '@app/ui/profiles/profile.presenter'; import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model'; import { LoaderAction } from '@app/domain/loader-action.util'; import { ActionType } from '@app/domain/action-type.util'; import { ErrorResponse } from '@app/domain/error-response.util'; import { CreateProfileUseCase } from '@app/usecase/profiles/create-profile.usecase'; import { UpdateProfileUseCase } from '@app/usecase/profiles/update-profile.usecase'; import { GetProfileUseCase } from '@app/usecase/profiles/get-profile.usecase'; import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto'; import { SearchFilters } from '@app/domain/search/search-filters'; import { SearchService } from '@app/infrastructure/search/search.service'; @Injectable({ providedIn: 'root', }) export class ProfileFacade { private profileRepository = inject(PROFILE_REPOSITORY_TOKEN); private readonly searchService = inject(SearchService); private listUseCase = new ListProfilesUseCase(this.profileRepository); private createUseCase = new CreateProfileUseCase(this.profileRepository); private updateUseCase = new UpdateProfileUseCase(this.profileRepository); private getUseCase = new GetProfileUseCase(this.profileRepository); readonly searchFilters = this.searchService.getFilters(); readonly profiles = signal([]); readonly profilePaginated = signal({} as ProfilePaginated); readonly profile = signal({} as ProfileViewModel); readonly loading = signal({ isLoading: false, action: ActionType.NONE }); readonly error = signal({ action: ActionType.NONE, hasError: false, message: null, }); load(search?: SearchFilters) { this.handleError(ActionType.READ, false, null, true); if (search === undefined || search === null) { search = this.searchFilters(); } this.listUseCase.execute(search).subscribe({ next: (profilePaginated: ProfilePaginated) => { const filters = { ...this.searchFilters(), page: profilePaginated.page, perPage: profilePaginated.perPage, totalItems: profilePaginated.totalItems, totalPages: profilePaginated.totalPages, }; this.searchService.setFilters(filters); this.searchFilters.set(filters); this.profilePaginated.set(profilePaginated); this.profiles.set(ProfilePresenter.toViewModels(profilePaginated.items as Profile[])); this.handleError(ActionType.READ, false, null, false); }, error: (err) => { this.handleError(ActionType.READ, false, err, false); }, }); } loadOne(userId: string) { this.handleError(ActionType.READ, false, null, true); this.getUseCase.execute(userId).subscribe({ next: (profile: Profile) => { this.profile.set(ProfilePresenter.toViewModel(profile)); this.handleError(ActionType.READ, false, null, false); }, error: (err) => { this.handleError(ActionType.READ, false, err, false); }, }); } create(profileDto: ProfileDTO) { this.handleError(ActionType.CREATE, false, null, true); this.createUseCase.execute(profileDto).subscribe({ next: (profile: Profile) => { this.profile.set(ProfilePresenter.toViewModel(profile)); this.handleError(ActionType.CREATE, false, null, false); }, error: (err) => { this.handleError(ActionType.CREATE, false, err, false); }, }); } update(profileId: string, profile: Partial) { this.handleError(ActionType.UPDATE, false, null, true); this.updateUseCase.execute(profileId, profile).subscribe({ next: (profile: Profile) => { this.profile.set(ProfilePresenter.toViewModel(profile)); this.handleError(ActionType.UPDATE, false, null, false); }, error: (err) => { this.handleError(ActionType.UPDATE, false, err, false); }, }); } private handleError( action: ActionType = ActionType.NONE, hasError: boolean, message: string | null = null, isLoading = false ) { this.error.set({ action, hasError, message }); this.loading.set({ action, isLoading }); } }