import { IUserReaction, IUserReactionCountDetail } from '@livelike/javascript';
import { createStore } from './store';

export type UserReactionsForTargetId = {
  [reactionId: string]: IUserReactionCountDetail;
};

export type TargetUserReactions = {
  [targetId: string]: UserReactionsForTargetId;
};

export type UserReactionStoreValue = {
  [reactionSpaceId: string]: TargetUserReactions;
};

const initalUserReaction: UserReactionStoreValue = {};

export const userReactionStore = createStore(initalUserReaction);

export type UpdateUserReactionActionArg = {
  reactionSpaceId: string;
  userReaction: Pick<
    IUserReaction,
    'id' | 'reacted_by_id' | 'reaction_id' | 'target_id'
  >;
  profileId: string;
};

export type loadUserReactionActionArg = {
  reactionSpaceId: string;
  targetUserReactions: TargetUserReactions;
};

export const userReactionStoreActions = {
  addUserReactionAction({
    reactionSpaceId,
    userReaction,
    profileId,
  }: UpdateUserReactionActionArg) {
    const userReactions = userReactionStore.get()?.[reactionSpaceId];
    const { target_id, reaction_id, reacted_by_id, id } = userReaction;
    const isSelfReacted = profileId === reacted_by_id;
    const reactionDetails = userReactions?.[target_id]?.[reaction_id];
    const hasSelfReactionAlreadyAdded =
      isSelfReacted &&
      reactionDetails &&
      !!reactionDetails?.self_reacted_user_reaction_id;
    const updatedUserReactions = {
      ...userReactions,
      [target_id]: {
        ...userReactions?.[target_id],
        [reaction_id]: {
          reaction_id,
          self_reacted_user_reaction_id: isSelfReacted
            ? id
            : reactionDetails?.self_reacted_user_reaction_id,
          count: hasSelfReactionAlreadyAdded
            ? reactionDetails?.count
            : (reactionDetails?.count ?? 0) + 1,
        },
      },
    };
    userReactionStore.set({
      ...userReactionStore.get(),
      [reactionSpaceId]: updatedUserReactions,
    });
  },
  removeUserReactionAction({
    reactionSpaceId,
    userReaction,
    profileId,
  }: UpdateUserReactionActionArg) {
    const userReactions = userReactionStore.get()?.[reactionSpaceId];
    const { target_id, reaction_id, reacted_by_id } = userReaction;
    const isSelfReacted = profileId === reacted_by_id;
    const reactionDetails = userReactions?.[target_id]?.[reaction_id];
    const hasSelfReactionAlreadyRemoved =
      isSelfReacted &&
      reactionDetails &&
      !reactionDetails?.self_reacted_user_reaction_id;
    const updatedUserReactions = {
      ...userReactions,
      [target_id]: {
        ...userReactions?.[target_id],
        [reaction_id]: {
          reaction_id,
          self_reacted_user_reaction_id: isSelfReacted
            ? null
            : reactionDetails?.self_reacted_user_reaction_id,
          count: hasSelfReactionAlreadyRemoved
            ? reactionDetails?.count
            : (reactionDetails?.count ?? 0) - 1,
        },
      },
    };
    userReactionStore.set({
      ...userReactionStore.get(),
      [reactionSpaceId]: updatedUserReactions,
    });
  },
  loadUserReactionAction({
    reactionSpaceId,
    targetUserReactions,
  }: loadUserReactionActionArg) {
    userReactionStore.set({
      ...userReactionStore.get(),
      [reactionSpaceId]: targetUserReactions,
    });
  },
};
