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 { HrLeaveTypeService } from '../../../services/hr-leave-type.service';
import { HrLeaveTypesActions } from './leave-types.actions';
import { selectHrLeaveTypesLoaded } from './leave-types.reducer';

@Injectable()
export class HrLeaveTypesEffects {
  private actions$ = inject(Actions);
  private store = inject(Store);
  private service = inject(HrLeaveTypeService);

  loadHrLeaveTypes$ = createEffect(() =>
    this.actions$.pipe(
      ofType(HrLeaveTypesActions.loadHRLeaveTypes),
      withLatestFrom(this.store.select(selectHrLeaveTypesLoaded)),
      filter(([action, loaded]) => !loaded || !!action.forceReload),
      exhaustMap(() =>
        this.service.listAll().pipe(
          map((response) =>
            HrLeaveTypesActions.loadHRLeaveTypesSuccess({
              leaveTypes: response.data,
              meta: response.meta,
            })
          ),
          catchError((error) =>
            of(
              HrLeaveTypesActions.loadHRLeaveTypesFailure({
                error: error.error?.message || 'Failed to load leave types',
              })
            )
          )
        )
      )
    )
  );

  createHrLeaveType$ = createEffect(() =>
    this.actions$.pipe(
      ofType(HrLeaveTypesActions.createHRLeaveType),
      exhaustMap(({ leaveType }) =>
        this.service.create(leaveType).pipe(
          map((response) =>
            HrLeaveTypesActions.createHRLeaveTypeSuccess({ leaveType: response.data })
          ),
          catchError((error) =>
            of(
              HrLeaveTypesActions.createHRLeaveTypeFailure({
                error: error.error?.message || 'Failed to create leave type',
              })
            )
          )
        )
      )
    )
  );

  updateHrLeaveType$ = createEffect(() =>
    this.actions$.pipe(
      ofType(HrLeaveTypesActions.updateHRLeaveType),
      exhaustMap(({ id, leaveType }) =>
        this.service.update(id, leaveType).pipe(
          map((response) =>
            HrLeaveTypesActions.updateHRLeaveTypeSuccess({ leaveType: response.data })
          ),
          catchError((error) =>
            of(
              HrLeaveTypesActions.updateHRLeaveTypeFailure({
                error: error.error?.message || 'Failed to update leave type',
              })
            )
          )
        )
      )
    )
  );

  deleteHrLeaveType$ = createEffect(() =>
    this.actions$.pipe(
      ofType(HrLeaveTypesActions.deleteHRLeaveType),
      exhaustMap(({ id }) =>
        this.service.delete(id).pipe(
          map(() => HrLeaveTypesActions.deleteHRLeaveTypeSuccess({ id })),
          catchError((error) =>
            of(
              HrLeaveTypesActions.deleteHRLeaveTypeFailure({
                error: error.error?.message || 'Failed to delete leave type',
              })
            )
          )
        )
      )
    )
  );
}
