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 { ProductCategoryService } from '../../services/product-category.service';
import { ProductCategoriesActions } from './product-categories.actions';
import { selectProductCategoriesLoaded } from './product-categories.reducer';

@Injectable()
export class ProductCategoriesEffects {
  private actions$ = inject(Actions);
  private store = inject(Store);
  private productCategoryService = inject(ProductCategoryService);

  loadProductCategories$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ProductCategoriesActions.loadProductCategories),
      withLatestFrom(this.store.select(selectProductCategoriesLoaded)),
      filter(([action, loaded]) => !loaded || !!action.forceReload),
      exhaustMap(() =>
        this.productCategoryService.listAll().pipe(
          map((response) =>
            ProductCategoriesActions.loadProductCategoriesSuccess({
              categories: response.data,
              meta: response.meta,
            })
          ),
          catchError((error) =>
            of(ProductCategoriesActions.loadProductCategoriesFailure({
              error: error.error?.message || 'Failed to load product categories',
            }))
          )
        )
      )
    )
  );

  createProductCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ProductCategoriesActions.createProductCategory),
      exhaustMap(({ category }) =>
        this.productCategoryService.create(category).pipe(
          map((response) =>
            ProductCategoriesActions.createProductCategorySuccess({ category: response.data })
          ),
          catchError((error) =>
            of(ProductCategoriesActions.createProductCategoryFailure({
              error: error.error?.message || 'Failed to create product category',
            }))
          )
        )
      )
    )
  );

  updateProductCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ProductCategoriesActions.updateProductCategory),
      exhaustMap(({ id, category }) =>
        this.productCategoryService.update(id, category).pipe(
          map((response) =>
            ProductCategoriesActions.updateProductCategorySuccess({ category: response.data })
          ),
          catchError((error) =>
            of(ProductCategoriesActions.updateProductCategoryFailure({
              error: error.error?.message || 'Failed to update product category',
            }))
          )
        )
      )
    )
  );

  deleteProductCategory$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ProductCategoriesActions.deleteProductCategory),
      exhaustMap(({ id }) =>
        this.productCategoryService.delete(id).pipe(
          map(() => ProductCategoriesActions.deleteProductCategorySuccess({ id })),
          catchError((error) =>
            of(ProductCategoriesActions.deleteProductCategoryFailure({
              error: error.error?.message || 'Failed to delete product category',
            }))
          )
        )
      )
    )
  );
}
