import { inject, Injectable, signal } from '@angular/core';
import { USER_REPOSITORY_TOKEN } from '@app/infrastructure/users/user-repository.token';
import { GetUserUseCase } from '../../application/users/get-user.usecase';
import { UpdateUserUseCase } from '../../application/users/update-user.usecase';
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 { UserViewModel } from '../users/user.presenter.model';
import { UserPresenter } from '../users/user.presenter';
import { first } from 'rxjs';
import { FeedbackService } from '../shared/services/feedback.service';

@Injectable({ providedIn: 'root' })
export class UserFacade {
  private readonly feedbackService = inject(FeedbackService);
  private readonly userRepository = inject(USER_REPOSITORY_TOKEN);

  private readonly getUseCase = new GetUserUseCase(this.userRepository);
  private readonly updateUseCase = new UpdateUserUseCase(this.userRepository);

  readonly user = signal<UserViewModel>({} as UserViewModel);
  readonly users = signal<UserViewModel[]>([]);
  readonly loading = signal<LoaderAction>({ isLoading: false, action: ActionType.NONE });
  readonly error = signal<ErrorResponse>({
    action: ActionType.NONE,
    hasError: false,
    message: null,
  });

  private readonly userPresenter = new UserPresenter();

  loadOne(userId: string) {
    this.handleError(ActionType.READ, false, null, true);
    this.getUseCase
      .execute(userId)
      .pipe(first())
      .subscribe({
        next: (user) => {
          this.user.set(this.userPresenter.toViewModel(user));
          this.handleError(ActionType.READ, false, null, false);
        },
        error: (err) => {
          this.handleError(ActionType.READ, false, err, false);
        },
      });
  }

  update(userId: string, user: Partial<UserViewModel>) {
    this.handleError(ActionType.UPDATE, false, null, true);
    this.updateUseCase
      .execute(userId, user)
      .pipe(first())
      .subscribe({
        next: (user) => {
          this.user.set(this.userPresenter.toViewModel(user));
          this.handleError(ActionType.UPDATE, false, null, false);

          const message = `Votre profile a bien été modifier !`;
          this.feedbackService.notify(ActionType.UPDATE, message);
        },
        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 });

    if (hasError) {
      this.feedbackService.notify(ActionType.READ, message!, true);
    }
  }
}
