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 { BankAccountService } from '../../services/bank-account.service';
import { BankAccountsActions } from './bank-accounts.actions';
import { selectBankAccountsLoaded } from './bank-accounts.reducer';

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

  load$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BankAccountsActions.loadBankAccounts),
      withLatestFrom(this.store.select(selectBankAccountsLoaded)),
      filter(([action, loaded]) => !loaded || !!action.forceReload),
      exhaustMap(() =>
        this.service.listAll().pipe(
          map((res) => BankAccountsActions.loadBankAccountsSuccess({ bankAccounts: res.data, meta: res.meta })),
          catchError((err) => of(BankAccountsActions.loadBankAccountsFailure({ error: err.error?.message || 'Failed to load bank accounts' })))
        )
      )
    )
  );

  create$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BankAccountsActions.createBankAccount),
      exhaustMap(({ bankAccount }) =>
        this.service.create(bankAccount).pipe(
          map((res) => BankAccountsActions.createBankAccountSuccess({ bankAccount: res.data })),
          catchError((err) => of(BankAccountsActions.createBankAccountFailure({ error: err.error?.message || 'Failed to create bank account' })))
        )
      )
    )
  );

  update$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BankAccountsActions.updateBankAccount),
      exhaustMap(({ id, bankAccount }) =>
        this.service.update(id, bankAccount).pipe(
          map((res) => BankAccountsActions.updateBankAccountSuccess({ bankAccount: res.data })),
          catchError((err) => of(BankAccountsActions.updateBankAccountFailure({ error: err.error?.message || 'Failed to update bank account' })))
        )
      )
    )
  );

  delete$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BankAccountsActions.deleteBankAccount),
      exhaustMap(({ id }) =>
        this.service.delete(id).pipe(
          map(() => BankAccountsActions.deleteBankAccountSuccess({ id })),
          catchError((err) => of(BankAccountsActions.deleteBankAccountFailure({ error: err.error?.message || 'Failed to delete bank account' })))
        )
      )
    )
  );
}
