import {
  patchState,
  signalStore,
  withComputed,
  withMethods,
  withState,
} from '@ngrx/signals';
import {
  RewardSelectionItem,
  calculatePriceValue,
  calculateLoyaltyPointsValue,
} from '@isa/checkout/data-access';
import { computed } from '@angular/core';

interface RewardSelectionState {
  // Single source of truth for all items with their allocations
  rewardSelectionItems: Record<number, RewardSelectionItem>;
  customerRewardPoints: number;
}

const initialState: RewardSelectionState = {
  rewardSelectionItems: {},
  customerRewardPoints: 0,
};

export const RewardSelectionStore = signalStore(
  withState(initialState),
  withComputed((store) => ({
    // Calculate total loyalty points needed for all selected reward items
    totalLoyaltyPointsNeeded: computed(() =>
      Object.values(store.rewardSelectionItems()).reduce(
        (sum, item) =>
          sum +
          calculateLoyaltyPointsValue(item) * (item?.rewardCartQuantity ?? 0),
        0,
      ),
    ),

    // Calculate total price for all selected items
    totalPrice: computed(() =>
      Object.values(store.rewardSelectionItems()).reduce(
        (sum, item) =>
          sum + calculatePriceValue(item) * (item?.cartQuantity ?? 0),
        0,
      ),
    ),
  })),
  withMethods((store) => ({
    /**
     * Initialize store with cart and reward items
     */
    initState({
      rewardSelectionItems,
      customerRewardPoints,
    }: {
      rewardSelectionItems: RewardSelectionItem[];
      customerRewardPoints: number;
    }) {
      const rewardSelectionItemsMapped = rewardSelectionItems.reduce(
        (acc, item) => {
          const itemId = item.item.id;
          if (itemId !== undefined) {
            acc[itemId] = item;
          }
          return acc;
        },
        {} as Record<number, RewardSelectionItem>,
      );

      patchState(store, {
        rewardSelectionItems: rewardSelectionItemsMapped,
        customerRewardPoints,
      });
    },

    /**
     * Update the quantity of an item in the regular cart
     */
    updateItemCartQuantity(itemId: number, quantity: number) {
      const currentItem = store.rewardSelectionItems()[itemId];
      patchState(store, {
        rewardSelectionItems: {
          ...store.rewardSelectionItems(),
          [itemId]: {
            ...currentItem,
            cartQuantity: quantity,
          },
        },
      });
    },

    /**
     * Update the quantity of an item in the reward cart
     */
    updateItemRewardCartQuantity(itemId: number, quantity: number) {
      const currentItem = store.rewardSelectionItems()[itemId];
      patchState(store, {
        rewardSelectionItems: {
          ...store.rewardSelectionItems(),
          [itemId]: {
            ...currentItem,
            rewardCartQuantity: quantity,
          },
        },
      });
    },
  })),
);
