import {
  addWidgetListener,
  createWidgetImpression,
  getWidgetInteractions,
  getWidget,
  removeWidgetListener,
  WidgetKind,
  CHOICE_WIDGET_KIND,
  IWidgetListenerCallbackArgs,
  getRewardTransactions,
  getTargetedWidgetIdAndKind,
} from '@livelike/javascript';
import { useEffect } from 'react';
import {
  getSelectedOptionIndex,
  getWidgetResultState,
  getWidgetRewardsFromRewardTransactions,
  getWidgeUIPhase,
  widgetStoreActions,
} from '../store';
import { useApi } from './useApi';
import { useIsTimelineWidget } from './useIsTimelineWidget';
import { useWidget } from './useWidget';
import { useWidgetInteractions } from './useWidgetInteractions';
import { useWidgetRewards } from './useWidgetRewards';

export type UseLoadWidgetEffectArg = {
  widgetId: string;
  widgetKind: WidgetKind;
  programId: string;
};

export function useLoadWidgetEffect({
  widgetId,
  widgetKind,
  programId,
}: UseLoadWidgetEffectArg) {
  const isTimelineWidget = useIsTimelineWidget({ widgetId });
  const widgetPayload = useWidget({ widgetId });
  const widgetInteractions = useWidgetInteractions({ widgetId });
  const widgetRewards = useWidgetRewards({ widgetId });
  const { onApi, isLoading, error, data } = useApi(() =>
    getWidget({ widgetId, widgetKind }).then((widget) =>
      Promise.all([
        getWidgetInteractions({
          widgetId,
          widgetKind,
          interactionUrl: widget.widget_interactions_url_template,
        }),
        getTargetedWidgetIdAndKind({ widget }).then(
          ({ widgetId: targetedWidgetId }) =>
            getRewardTransactions({ widgetIds: [targetedWidgetId] }).then(
              (res) => res.results
            )
        ),
      ]).then(
        ([widgetInteractions, widgetRewards]) =>
          [widget, widgetInteractions, widgetRewards] as const
      )
    )
  );

  useEffect(() => {
    if (isTimelineWidget) {
      return;
    }
    onApi().then(([widgetPayload, widgetInteractions, rewardTransactions]) => {
      const widgetRewards =
        getWidgetRewardsFromRewardTransactions(rewardTransactions);
      widgetStoreActions.updateWidgetStateAction({
        widgetId,
        widgetState: {
          widgetPayload,
          widgetInteractions,
          widgetRewards,
          widgetResultState: getWidgetResultState({
            widgetPayload,
            widgetInteractions,
          }),
          widgetUIPhase: getWidgeUIPhase({ widgetPayload, widgetInteractions }),
          selectedOptionIndex: getSelectedOptionIndex({
            widgetPayload,
            widgetInteractions,
          }),
        },
      });
    });
  }, [widgetId, widgetKind, isTimelineWidget]);

  useEffect(() => {
    if (!data?.length && !isTimelineWidget) {
      return;
    }
    createWidgetImpression({ widgetId, widgetKind });

    function onWidgetListener({ event, message }: IWidgetListenerCallbackArgs) {
      if (CHOICE_WIDGET_KIND.includes(message.kind) && message.choices.length) {
        widgetStoreActions.updateWidgetChoicesAction({
          widgetId,
          widgetChoices: message.choices,
        });
      } else if (
        message.kind === WidgetKind.EMOJI_SLIDER &&
        message.average_magnitude !== undefined
      ) {
        widgetStoreActions.updateWidgetAverageMagnitude({
          widgetId,
          averageMagnitude: message.average_magnitude,
        });
      } else if (message.options.length) {
        widgetStoreActions.updateWidgetOptionsAction({
          widgetId,
          widgetOptions: message.options,
        });
      }
    }
    addWidgetListener({ widgetId, widgetKind }, onWidgetListener);
    return () => {
      removeWidgetListener({ widgetId, widgetKind }, onWidgetListener);
    };
  }, [data, widgetId, widgetKind, isTimelineWidget]);

  if (isTimelineWidget) {
    return {
      isLoading: false,
      data: [widgetPayload, widgetInteractions, widgetRewards] as const,
    };
  }

  return { onApi, isLoading, error, data };
}
