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 { PartnerCategoryService } from '../../services/partner-category.service';
import { PartnerCategoriesActions } from './partner-categories.actions';
import { selectPartnerCategoriesLoaded } from './partner-categories.reducer';

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

  loadPartnerCategories$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PartnerCategoriesActions.loadPartnerCategories),
      withLatestFrom(this.store.select(selectPartnerCategoriesLoaded)),
      filter(([action, loaded]) => !loaded || !!action.forceReload),
      exhaustMap(() =>
        this.service.listAll().pipe(
          map((response) =>
            PartnerCategoriesActions.loadPartnerCategoriesSuccess({
              categories: response.data,
              meta: response.meta,
            })
          ),
          catchError((error) =>
            of(PartnerCategoriesActions.loadPartnerCategoriesFailure({
              error: error.error?.message || 'Failed to load partner categories',
            }))
          )
        )
      )
    )
  );

  createPartnerCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PartnerCategoriesActions.createPartnerCategory),
      exhaustMap(({ category }) =>
        this.service.create(category).pipe(
          map((response) =>
            PartnerCategoriesActions.createPartnerCategorySuccess({ category: response.data })
          ),
          catchError((error) =>
            of(PartnerCategoriesActions.createPartnerCategoryFailure({
              error: error.error?.message || 'Failed to create partner category',
            }))
          )
        )
      )
    )
  );

  updatePartnerCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PartnerCategoriesActions.updatePartnerCategory),
      exhaustMap(({ id, category }) =>
        this.service.update(id, category).pipe(
          map((response) =>
            PartnerCategoriesActions.updatePartnerCategorySuccess({ category: response.data })
          ),
          catchError((error) =>
            of(PartnerCategoriesActions.updatePartnerCategoryFailure({
              error: error.error?.message || 'Failed to update partner category',
            }))
          )
        )
      )
    )
  );

  deletePartnerCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PartnerCategoriesActions.deletePartnerCategory),
      exhaustMap(({ id }) =>
        this.service.delete(id).pipe(
          map(() => PartnerCategoriesActions.deletePartnerCategorySuccess({ id })),
          catchError((error) =>
            of(PartnerCategoriesActions.deletePartnerCategoryFailure({
              error: error.error?.message || 'Failed to delete partner category',
            }))
          )
        )
      )
    )
  );
}
