import { createFeature, createReducer, on } from '@ngrx/store';
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
import { FiscalYear } from '../../models/fiscal-year.model';
import { PaginationMeta } from '../../models/api.model';
import { FiscalYearsActions } from './fiscal-years.actions';

export interface FiscalYearsState extends EntityState<FiscalYear> {
  meta: PaginationMeta | null;
  loading: boolean;
  saving: boolean;
  error: string | null;
  loaded: boolean;
}

export const fiscalYearsAdapter: EntityAdapter<FiscalYear> = createEntityAdapter<FiscalYear>();

const initialState: FiscalYearsState = fiscalYearsAdapter.getInitialState({
  meta: null,
  loading: false,
  saving: false,
  error: null,
  loaded: false,
});

export const fiscalYearsFeature = createFeature({
  name: 'fiscalYears',
  reducer: createReducer(
    initialState,
    on(FiscalYearsActions.loadFiscalYears, (state, action) =>
      state.loaded && !action.forceReload ? state : { ...state, loading: true, error: null }
    ),
    on(FiscalYearsActions.loadFiscalYearsSuccess, (state, { fiscalYears, meta }) =>
      fiscalYearsAdapter.setAll(fiscalYears, { ...state, meta, loading: false, loaded: true })
    ),
    on(FiscalYearsActions.loadFiscalYearsFailure, (state, { error }) => ({ ...state, loading: false, error })),
    on(FiscalYearsActions.createFiscalYear, (state) => ({ ...state, saving: true, error: null })),
    on(FiscalYearsActions.createFiscalYearSuccess, (state, { fiscalYear }) =>
      fiscalYearsAdapter.addOne(fiscalYear, { ...state, saving: false })
    ),
    on(FiscalYearsActions.createFiscalYearFailure, (state, { error }) => ({ ...state, saving: false, error })),
    on(FiscalYearsActions.updateFiscalYear, (state) => ({ ...state, saving: true, error: null })),
    on(FiscalYearsActions.updateFiscalYearSuccess, (state, { fiscalYear }) =>
      fiscalYearsAdapter.upsertOne(fiscalYear, { ...state, saving: false })
    ),
    on(FiscalYearsActions.updateFiscalYearFailure, (state, { error }) => ({ ...state, saving: false, error })),
    on(FiscalYearsActions.deleteFiscalYear, (state) => ({ ...state, saving: true, error: null })),
    on(FiscalYearsActions.deleteFiscalYearSuccess, (state, { id }) =>
      fiscalYearsAdapter.removeOne(id, { ...state, saving: false })
    ),
    on(FiscalYearsActions.deleteFiscalYearFailure, (state, { error }) => ({ ...state, saving: false, error })),
    on(FiscalYearsActions.clearFiscalYearsError, (state) => ({ ...state, error: null }))
  ),
});

const { selectAll, selectEntities, selectTotal } = fiscalYearsAdapter.getSelectors(fiscalYearsFeature.selectFiscalYearsState);

export const selectAllFiscalYears = selectAll;
export const selectFiscalYearEntities = selectEntities;
export const selectFiscalYearsTotal = selectTotal;
export const selectFiscalYearsMeta = fiscalYearsFeature.selectMeta;
export const selectFiscalYearsLoading = fiscalYearsFeature.selectLoading;
export const selectFiscalYearsSaving = fiscalYearsFeature.selectSaving;
export const selectFiscalYearsError = fiscalYearsFeature.selectError;
export const selectFiscalYearsLoaded = fiscalYearsFeature.selectLoaded;
