import {GetAllDip, SearchDip, SearchDipFail, SearchDipSuccess} from "@app/access/access.action";
import {BaseStateModel} from "@app/base.state";
import {StateEnum} from "@app/shared/enums/state.enum";
import {DipModel} from "@app/generated-api";
import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
import {Action, State, StateContext} from "@ngxs/store";
import {tap} from "rxjs/internal/operators/tap";
import {catchError} from "rxjs/operators";
import {ApiService} from "@app/shared/services/api.service";
import {AccessResourceApiEnum} from "@app/shared/enums/api.enum";

export interface AccessStateModel extends BaseStateModel {
  totalDip: number;
  dips: DipModel[];
}

@State<AccessStateModel>({
  name: StateEnum.access,
  defaults: {
    totalDip: 0,
    isLoading: false,
    dips: [],
  },
})
export class AccessState {
  constructor(private apiService: ApiService) {
  }

  @Action(GetAllDip)
  getAllDip(ctx: StateContext<AccessStateModel>, action: GetAllDip) {
    ctx.patchState({
      isLoading: true,
    });

    return this.apiService.get<DipModel>(AccessResourceApiEnum.dip)
      .pipe(
        tap((collectionDips: CollectionTypedModel<DipModel>) => {
          ctx.patchState({
            dips: collectionDips._data,
            totalDip: collectionDips._page.totalItems,
            isLoading: false,
          });

          // Equals to :

          // const state = ctx.getState();
          // ctx.setState({
          //   ...state,
          //   dips: collectionDips.data as Dip[],
          //   isLoading: false,
          // });
        }),
      );
  }

  @Action(SearchDip, {cancelUncompleted: true})
  searchDip(ctx: StateContext<AccessStateModel>, action: SearchDip) {
    ctx.patchState({
      isLoading: true,
    });

    const filters = {
      "info.name": action.search,
    };

    // return this.dlcmService.accessDipGetFilter(null, null, null, filters)
    return this.apiService.get<DipModel>(AccessResourceApiEnum.dip, null, null, null, filters)
      .pipe(
        tap((collectionDips: CollectionTypedModel<DipModel>) => {
          ctx.dispatch(new SearchDipSuccess(collectionDips));
        }),
        catchError(error => {
          ctx.dispatch(new SearchDipFail());
          throw error;
        }),
      );
  }

  @Action(SearchDipSuccess)
  searchDipSuccess(ctx: StateContext<AccessStateModel>, action: SearchDipSuccess) {
    ctx.patchState({
      dips: action.aips._data,
      totalDip: action.aips._page.totalItems,
      isLoading: false,
    });
  }

  @Action(SearchDipFail)
  searchDipFail(ctx: StateContext<AccessStateModel>) {
    ctx.patchState({
      isLoading: false,
    });
  }
}