import { Injectable, inject } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { of } from 'rxjs';
import { map, exhaustMap, catchError, withLatestFrom, filter } from 'rxjs/operators';
import { UnitGroupService } from '../../services/unit-group.service';
import { UnitGroupsActions } from './unit-groups.actions';
import { selectUnitGroupsLoaded } from './unit-groups.reducer';

@Injectable()
export class UnitGroupsEffects {
  private actions$ = inject(Actions);
  private store = inject(Store);
  private unitGroupService = inject(UnitGroupService);

  loadUnitGroups$ = createEffect(() =>
    this.actions$.pipe(
      ofType(UnitGroupsActions.loadUnitGroups),
      withLatestFrom(this.store.select(selectUnitGroupsLoaded)),
      filter(([action, loaded]) => !loaded || !!action.forceReload),
      exhaustMap(() =>
        this.unitGroupService.listAll().pipe(
          map((response) =>
            UnitGroupsActions.loadUnitGroupsSuccess({
              unitGroups: response.data,
              meta: response.meta,
            })
          ),
          catchError((error) =>
            of(UnitGroupsActions.loadUnitGroupsFailure({
              error: error.error?.message || 'Failed to load unit groups',
            }))
          )
        )
      )
    )
  );

  createUnitGroup$ = createEffect(() =>
    this.actions$.pipe(
      ofType(UnitGroupsActions.createUnitGroup),
      exhaustMap(({ unitGroup }) =>
        this.unitGroupService.create(unitGroup).pipe(
          map((response) =>
            UnitGroupsActions.createUnitGroupSuccess({ unitGroup: response.data })
          ),
          catchError((error) =>
            of(UnitGroupsActions.createUnitGroupFailure({
              error: error.error?.message || 'Failed to create unit group',
            }))
          )
        )
      )
    )
  );

  updateUnitGroup$ = createEffect(() =>
    this.actions$.pipe(
      ofType(UnitGroupsActions.updateUnitGroup),
      exhaustMap(({ id, unitGroup }) =>
        this.unitGroupService.update(id, unitGroup).pipe(
          map((response) =>
            UnitGroupsActions.updateUnitGroupSuccess({ unitGroup: response.data })
          ),
          catchError((error) =>
            of(UnitGroupsActions.updateUnitGroupFailure({
              error: error.error?.message || 'Failed to update unit group',
            }))
          )
        )
      )
    )
  );

  deleteUnitGroup$ = createEffect(() =>
    this.actions$.pipe(
      ofType(UnitGroupsActions.deleteUnitGroup),
      exhaustMap(({ id }) =>
        this.unitGroupService.delete(id).pipe(
          map(() => UnitGroupsActions.deleteUnitGroupSuccess({ id })),
          catchError((error) =>
            of(UnitGroupsActions.deleteUnitGroupFailure({
              error: error.error?.message || 'Failed to delete unit group',
            }))
          )
        )
      )
    )
  );
}
