import { inject, Injectable, signal } from '@angular/core';
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
import { ListSectorUsecase } from '../../application/sectors/list-sector.usecase';
import { GetSectorUseCase } from '../../application/sectors/get-sector.usecase';
import { ActionType } from '@app/domain/action-type.util';
import { LoaderAction } from '@app/domain/loader-action.util';
import { ErrorResponse } from '@app/domain/error-response.util';
import { SectorPresenterModel } from '../sectors/sector.presenter.model';
import { Sector } from '@app/domain/sectors/sector.model';
import { SectorPresenter } from '../sectors/sector.presenter';
import { first, Subscription } from 'rxjs';
import { FeedbackService } from '../shared/services/feedback.service';

@Injectable()
export class SectorFacade {
  private readonly feedbackService = inject(FeedbackService);
  private readonly sectorRepo = inject(SECTOR_REPOSITORY_TOKEN);

  private readonly listSectorUseCase = new ListSectorUsecase(this.sectorRepo);
  private readonly getSectorUseCase = new GetSectorUseCase(this.sectorRepo);

  readonly sectors = signal<SectorPresenterModel[]>([]);
  readonly sector = signal<SectorPresenterModel>({} as SectorPresenterModel);

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

  private readonly sectorPresenter = new SectorPresenter();
  private sectorSubscription: Subscription | null = null;

  load() {
    if (this.sectorSubscription) {
      this.sectorSubscription.unsubscribe();
      this.sectorSubscription = null;
    }

    this.handleError(ActionType.READ, false, null, true);
    this.sectorSubscription = this.listSectorUseCase.execute().subscribe({
      next: (sectors: Sector[]) => {
        this.sectors.set(this.sectorPresenter.toViewModels(sectors));
        this.handleError(ActionType.READ, false, null, false);
        this.sectorSubscription = null;
      },
      error: (err) => {
        this.handleError(ActionType.READ, false, err, false);
        this.sectorSubscription = null;
      },
    });
  }

  loadOne(sectorId: string) {
    this.handleError(ActionType.READ, false, null, true);
    this.getSectorUseCase
      .execute(sectorId)
      .pipe(first())
      .subscribe({
        next: (sector: Sector) => {
          this.sector.set(this.sectorPresenter.toViewModel(sector));
          this.handleError(ActionType.READ, false, null, false);
        },
        error: (err) => {
          this.handleError(ActionType.READ, 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);
    }
  }
}
