import { useCallback } from 'react';
import {
  createWidgetInteraction,
  getUpdatedWidgetInteraction,
  hasDebugLogger,
  INumberPredictionItem,
  ISliderInteractionItem,
  isWidgetOptionItem,
  ITextAskInteractionItem,
  IWidgetChoiceItem,
  IWidgetOptionItem,
  updateWidgetInteraction,
  WidgetKind,
} from '@livelike/javascript';
import { widgetStoreActions } from '../store';
import { useWidgetInteractions } from './useWidgetInteractions';
import { WidgetUIPhase } from '../types';
import { useWidgetKind } from './useWidgetKind';

export type UseWidgetInteractionActionsArg = {
  widgetId: string;
};

export type WidgetUpdateInteractionActionArg = {
  interactionItem: IWidgetOptionItem;
};

export type WidgetCreateInteractionActionArg = {
  interactionItem:
    | IWidgetChoiceItem
    | IWidgetOptionItem
    | INumberPredictionItem
    | ISliderInteractionItem
    | ITextAskInteractionItem;
};

export function useWidgetInteractionActions({
  widgetId,
}: UseWidgetInteractionActionsArg) {
  const widgetInteractions = useWidgetInteractions({ widgetId });
  const widgetKind = useWidgetKind({ widgetId });

  const updateWidgetInteractionAction = useCallback(
    ({ interactionItem }: WidgetUpdateInteractionActionArg) => {
      if (
        !widgetInteractions?.length ||
        (widgetInteractions[0].widget_kind === WidgetKind.CHEER_METER &&
          isWidgetOptionItem(interactionItem) &&
          !widgetInteractions.find(
            (interaction) => interaction.option_id === interactionItem.id
          )) ||
        !isWidgetOptionItem(interactionItem)
      ) {
        hasDebugLogger() &&
          console.warn(
            'widget interaction not found, may be call createWidgetInteractionAction'
          );
        return;
      }
      widgetStoreActions.updateWidgetStateAction({
        widgetId,
        widgetState: {
          widgetUIPhase: WidgetUIPhase.SUBMITTING,
        },
      });
      return updateWidgetInteraction({
        widgetId,
        widgetKind,
        interactionItem,
      })
        .then((widgetInteraction) => {
          widgetStoreActions.updateWidgetInteractionAction({
            widgetId,
            widgetInteractions: getUpdatedWidgetInteraction(
              widgetInteraction,
              widgetInteractions
            ),
          });
          return widgetInteraction;
        })
        .catch(() => {
          widgetStoreActions.updateWidgetUIPhaseAction({
            widgetId,
            widgetUIPhase: WidgetUIPhase.SUBMITTED,
          });
        });
    },
    [widgetId, widgetKind, widgetInteractions]
  );

  const createWidgetInteractionAction = useCallback(
    ({ interactionItem }: WidgetCreateInteractionActionArg) => {
      if (
        (!!widgetInteractions?.length &&
          widgetInteractions[0].widget_kind !== WidgetKind.CHEER_METER) ||
        (isWidgetOptionItem(interactionItem) &&
          widgetInteractions?.find(
            (interaction) => interaction.option_id === interactionItem.id
          ))
      ) {
        hasDebugLogger() &&
          console.warn(
            'widget interaction already found, may be call "updateWidgetInteractionAction"'
          );
        return;
      }
      widgetStoreActions.updateWidgetUIPhaseAction({
        widgetId,
        widgetUIPhase: WidgetUIPhase.SUBMITTING,
      });
      return createWidgetInteraction({
        widgetId,
        widgetKind,
        interactionItem,
      })
        .then((widgetInteraction) => {
          widgetStoreActions.updateWidgetInteractionAction({
            widgetId,
            widgetInteractions: getUpdatedWidgetInteraction(
              widgetInteraction,
              widgetInteractions
            ),
          });
          return widgetInteraction;
        })
        .catch(() => {
          widgetStoreActions.updateWidgetUIPhaseAction({
            widgetId,
            widgetUIPhase: WidgetUIPhase.INTERACTIVE,
          });
        });
    },
    [widgetId, widgetKind, widgetInteractions]
  );

  return {
    updateWidgetInteractionAction,
    createWidgetInteractionAction,
  };
}
