import React, { useCallback, useMemo } from 'react';
import {
  useInteractedWidgetOption,
  useWidgetResultState,
  useWidgetChoices,
  useIsWidgetOptionDisabled,
} from '../../hooks';
import { WidgetResultState } from '../../types';
import { LLWidgetOption, LLWidgetOptionProps } from './LLWidgetOption';

export type LLWidgetChoiceOptionProps = {
  widgetId: string;
  optionIndex: number;
  selectedOptionIndex: number;
  onOptionChange: (optionIndex: number) => void;
  OptionComponent?: typeof LLWidgetOption;
  OptionComponentStyles?: LLWidgetOptionProps['styles'];
};

export function LLWidgetChoiceOption({
  widgetId,
  optionIndex,
  selectedOptionIndex: selectedOptionIndexProp,
  onOptionChange,
  OptionComponent = LLWidgetOption,
  OptionComponentStyles,
}: LLWidgetChoiceOptionProps) {
  const widgetResultState = useWidgetResultState({ widgetId });
  const widgetChoices = useWidgetChoices({ widgetId });
  const interactedOption = useInteractedWidgetOption({ widgetId });
  const optionDisabled = useIsWidgetOptionDisabled({ widgetId, optionIndex });
  const interactedOptionId = interactedOption?.id;
  const widgetChoice = widgetChoices?.[optionIndex];
  const widgetChoiceId = widgetChoice?.id;

  const selectedOptionIndex = useMemo(() => {
    // show interactedOption as selected when user has not interacted with any of the option
    // useful for inital mount of widget where selectedIndex is -1 but user has already interacted
    // with the widget before.
    if (
      interactedOptionId &&
      widgetChoiceId &&
      interactedOptionId === widgetChoiceId &&
      selectedOptionIndexProp < 0
    ) {
      return optionIndex;
    }
    return selectedOptionIndexProp;
  }, [
    selectedOptionIndexProp,
    widgetChoiceId,
    interactedOptionId,
    optionIndex,
  ]);

  const answerPercentage = useMemo(() => {
    if (!widgetChoices || !widgetChoices.length) {
      return 0;
    }
    const totalVotes = widgetChoices.reduce(
      (total, option) => option.answer_count + total,
      0
    );
    if (!totalVotes) {
      return 0;
    }
    return Math.round(
      (widgetChoices[optionIndex].answer_count / totalVotes) * 100
    );
  }, [widgetChoices, optionIndex]);

  const onOptionPressHandler = useCallback(() => {
    onOptionChange(optionIndex);
  }, [optionIndex]);

  const showWidgetResult = widgetResultState === WidgetResultState.SHOWN;

  if (!widgetChoices || !widgetChoice) {
    return undefined;
  }

  return (
    <OptionComponent
      optionIndex={optionIndex}
      percentage={answerPercentage}
      optionImage={widgetChoice?.image_url}
      optionText={widgetChoice?.description}
      optionDisabled={optionDisabled}
      showWidgetResult={showWidgetResult}
      selectedOptionIndex={selectedOptionIndex}
      onOptionChange={onOptionPressHandler}
      styles={OptionComponentStyles}
      correctOption={interactedOption ? !!widgetChoice?.is_correct : undefined}
    />
  );
}
