import {
  addProgramListener,
  removeProgramListener,
  IProgramListenerCallbackArgs,
  FOLLOW_UP_WIDGET_UPDATED_EVENT,
  IWidgetPayload,
  PREDICTION_WIDGET_ID_PROP,
} from '@livelike/javascript';
import { useEffect, useState } from 'react';
import { widgetStore, widgetStoreActions } from '../store';
import { WidgetResultState, WidgetUIPhase } from '../types';
import { useSelectedFieldStore } from './useSelectedFieldStore';
import { useWidgetUIPhase } from './useWidgetUIPhase';

export type UsePredictionWidgetEffectArg = {
  widgetId: string;
  programId: string;
  inlineFollowUp?: boolean;
};

/**
 * @description Listens to prediction follow up updates, and updates widget state and return followup widget details
 * @param UsePredictionWidgetEffectArg
 * @returns object with "followUpWidget" prop
 */
export const usePredictionWidgetEffect = ({
  widgetId,
  programId,
  inlineFollowUp,
}: UsePredictionWidgetEffectArg) => {
  const [followUpWidget, setFollowUpWidget] = useState<IWidgetPayload | null>(
    null
  );
  const currentWidgetUIPhase = useWidgetUIPhase({ widgetId });
  const isFollowUpPublished =
    currentWidgetUIPhase === WidgetUIPhase.FOLLOW_UP_PUBLISHED;
  const followUpWidgetPayload = useSelectedFieldStore(widgetStore, () => {
    const widgetFollowUps =
      widgetStore.get()[widgetId]?.widgetPayload?.follow_ups;
    if (!widgetFollowUps?.length) {
      return undefined;
    }
    return widgetFollowUps[widgetFollowUps.length - 1];
  });

  useEffect(() => {
    if (
      followUpWidgetPayload &&
      inlineFollowUp &&
      followUpWidgetPayload.status === 'published'
    ) {
      setFollowUpWidget(followUpWidgetPayload);
    }
  }, [followUpWidgetPayload, inlineFollowUp]);

  useEffect(() => {
    if (isFollowUpPublished) {
      return;
    }
    function onProgramListener(arg: IProgramListenerCallbackArgs) {
      if (FOLLOW_UP_WIDGET_UPDATED_EVENT.includes(arg.event)) {
        const predictionWidgetId =
          arg.message[PREDICTION_WIDGET_ID_PROP[arg.message.kind]];
        if (predictionWidgetId !== widgetId) {
          return;
        }
        const widget = widgetStore.get()[widgetId]?.widgetPayload;
        if (!widget) {
          return;
        }
        const followUps = [...widget.follow_ups];
        const followUpIndex = followUps.findIndex(
          ({ id }) => id === arg.message.id
        );
        if (followUpIndex < 0) {
          followUps.push(arg.message);
        } else {
          followUps.splice(followUpIndex, 1, arg.message);
        }
        widgetStoreActions.updateWidgetStateAction({
          widgetId,
          widgetState: {
            widgetPayload: {
              ...widget,
              follow_ups: followUps,
            },
            widgetUIPhase: WidgetUIPhase.FOLLOW_UP_PUBLISHED,
            widgetResultState: WidgetResultState.SHOWN,
          },
        });
      }
    }

    addProgramListener({ programId }, onProgramListener);

    return () => {
      removeProgramListener({ programId }, onProgramListener);
    };
  }, [isFollowUpPublished, programId, widgetId]);

  return { followUpWidget };
};
