import { createFeature, createReducer, on } from '@ngrx/store';
import { createEntityAdapter, EntityState } from '@ngrx/entity';
import { PaginationMeta } from '../../../models/api.model';
import { PurchaseOrder } from '../../../models/purchase-order.model';
import { PurchaseOrdersActions } from './orders.actions';

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

const adapter = createEntityAdapter<PurchaseOrder>();

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

export const purchaseOrdersFeature = createFeature({
  name: 'purchaseOrders',
  reducer: createReducer(
    initialState,

    // ─── Load All ──────────────────────────────────────────────
    on(PurchaseOrdersActions.loadOrders, (state, { force }) => ({
      ...state,
      loading: !state.loaded || force === true,
      error: null,
    })),
    on(PurchaseOrdersActions.loadOrdersSuccess, (state, { orders, meta }) =>
      adapter.setAll(orders, { ...state, meta, loading: false, loaded: true })
    ),
    on(PurchaseOrdersActions.loadOrdersFailure, (state, { error }) => ({
      ...state,
      loading: false,
      error,
    })),

    // ─── Load Single ───────────────────────────────────────────
    on(PurchaseOrdersActions.loadOrder, (state) => ({
      ...state,
      loading: true,
      error: null,
    })),
    on(PurchaseOrdersActions.loadOrderSuccess, (state, { order }) =>
      adapter.upsertOne(order, { ...state, loading: false })
    ),
    on(PurchaseOrdersActions.loadOrderFailure, (state, { error }) => ({
      ...state,
      loading: false,
      error,
    })),

    // ─── Create ────────────────────────────────────────────────
    on(PurchaseOrdersActions.createOrder, (state) => ({
      ...state,
      saving: true,
      error: null,
    })),
    on(PurchaseOrdersActions.createOrderSuccess, (state, { order }) =>
      adapter.addOne(order, { ...state, saving: false })
    ),
    on(PurchaseOrdersActions.createOrderFailure, (state, { error }) => ({
      ...state,
      saving: false,
      error,
    })),

    // ─── Update ────────────────────────────────────────────────
    on(PurchaseOrdersActions.updateOrder, (state) => ({
      ...state,
      saving: true,
      error: null,
    })),
    on(PurchaseOrdersActions.updateOrderSuccess, (state, { order }) =>
      adapter.upsertOne(order, { ...state, saving: false })
    ),
    on(PurchaseOrdersActions.updateOrderFailure, (state, { error }) => ({
      ...state,
      saving: false,
      error,
    })),

    // ─── Delete ────────────────────────────────────────────────
    on(PurchaseOrdersActions.deleteOrder, (state) => ({
      ...state,
      saving: true,
      error: null,
    })),
    on(PurchaseOrdersActions.deleteOrderSuccess, (state, { id }) =>
      adapter.removeOne(id, { ...state, saving: false })
    ),
    on(PurchaseOrdersActions.deleteOrderFailure, (state, { error }) => ({
      ...state,
      saving: false,
      error,
    })),

    // ─── Status Changes ───────────────────────────────────────
    on(
      PurchaseOrdersActions.submitOrderApproval,
      PurchaseOrdersActions.approveOrder,
      PurchaseOrdersActions.rejectOrder,
      PurchaseOrdersActions.confirmOrder,
      PurchaseOrdersActions.createOrderGrn,
      PurchaseOrdersActions.createOrderBill,
      PurchaseOrdersActions.cancelOrder,
      PurchaseOrdersActions.closeOrder,
      PurchaseOrdersActions.duplicateOrder,
      (state) => ({ ...state, saving: true, error: null })
    ),
    on(PurchaseOrdersActions.statusChangeSuccess, (state, { order }) =>
      adapter.upsertOne(order, { ...state, saving: false })
    ),
    on(PurchaseOrdersActions.duplicateOrderSuccess, (state, { order }) =>
      adapter.addOne(order, { ...state, saving: false })
    ),
    on(PurchaseOrdersActions.statusChangeFailure, (state, { error }) => ({
      ...state,
      saving: false,
      error,
    })),

    // ─── Clear Error ───────────────────────────────────────────
    on(PurchaseOrdersActions.clearOrdersError, (state) => ({
      ...state,
      error: null,
    }))
  ),
});

const { selectAll, selectEntities, selectTotal } = adapter.getSelectors(
  purchaseOrdersFeature.selectPurchaseOrdersState
);

export const selectAllPurchaseOrders = selectAll;
export const selectPurchaseOrderEntities = selectEntities;
export const selectPurchaseOrdersTotal = selectTotal;
export const selectPurchaseOrdersMeta = purchaseOrdersFeature.selectMeta;
export const selectPurchaseOrdersLoading = purchaseOrdersFeature.selectLoading;
export const selectPurchaseOrdersSaving = purchaseOrdersFeature.selectSaving;
export const selectPurchaseOrdersError = purchaseOrdersFeature.selectError;
export const selectPurchaseOrdersLoaded = purchaseOrdersFeature.selectLoaded;
