import { useCallback } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import {
  useContextSelector,
  useContextSelectorRef,
} from '@/hooks/useContextSelector';
import { TransactionLogger } from '@/logging/logWebUserEvent';
import { CREATE_VERSION } from '@/utils/constants';
import { hasChangedControlSliders } from '@/utils/utils';

import CreateFormContext from './CreateFormContext';
import {
  getAllConditions,
  getCurrentAudioInfluence,
  getCurrentExcludeStyles,
  getCurrentLyrics,
  getCurrentStyleInfluence,
  getCurrentStyles,
  getCurrentWeirdness,
} from './actions/currentModeSetters';
import {
  ConditionTypes,
  CreateFormState,
  CreateModes,
  LyricsInputModes,
} from './types';

export const getEffectiveLyricsMode = (state: CreateFormState) => {
  if (state.global.mode === CreateModes.SIMPLE) {
    return state[CreateModes.SIMPLE].instrumental ? 'instrumental' : 'auto';
  }
  if (state.global.mode === CreateModes.CUSTOM) {
    if (state[CreateModes.CUSTOM].lyricsMode === LyricsInputModes.AUTO) {
      return 'auto';
    } else if (
      state[CreateModes.CUSTOM].lyricsMode === LyricsInputModes.MANUAL
    ) {
      return 'custom';
    } else if (
      state[CreateModes.CUSTOM].lyricsMode === LyricsInputModes.INSTRUMENTAL
    ) {
      return 'instrumental';
    } else if (
      state[CreateModes.CUSTOM].lyricsMode === LyricsInputModes.MUMBLE_MODE
    ) {
      return 'mumble_mode';
    }
    return 'INVALID_LYRICS_INPUT_MODE';
  }
  if (state.global.mode === CreateModes.ADJUST_SPEED) {
    return 'not_applicable';
  }
  return 'INVALID_CREATE_FORM_MODE';
};

export default function useCreateFormLogging() {
  const { session, genForm, createV2 } = useStores();

  const stateRef = useContextSelectorRef(CreateFormContext, (ctx) => ctx.state);
  const isRemix = useContextSelector(CreateFormContext, (ctx) => ctx.isRemix);

  const logGenerateButtonClicked = useCallback(
    (transactionLogger: TransactionLogger) => {
      const state = stateRef.current;
      const currentConditioning = getAllConditions(state);
      transactionLogger.logWebUserEvent({
        actionName: 'GenerateButtonClicked',
        context: {
          onebox: state.global.mode === CreateModes.SIMPLE,
          createVersion: CREATE_VERSION,
          createMode: state.global.mode,
          lyricsMode: getEffectiveLyricsMode(state),
          hasSimplePrompt:
            state.global.mode === CreateModes.SIMPLE
              ? state[CreateModes.SIMPLE].prompt !== ''
              : state[CreateModes.CUSTOM].lyricsMode ===
                  LyricsInputModes.AUTO &&
                state[CreateModes.CUSTOM].lyricsPrompt !== '',
          hasStyleTags: !!getCurrentStyles(state),
          hasExcludeStyleTags: !!getCurrentExcludeStyles(state),
          hasLyrics: !!getCurrentLyrics(state),
          hasPersona:
            (state.global.untimedConditions[ConditionTypes.PERSONA]?.length ??
              0) > 0,
          hasAudio:
            Object.values(currentConditioning ?? {}).filter(Boolean).length > 0,
          hasTitle:
            state.global.mode === CreateModes.CUSTOM
              ? state[CreateModes.CUSTOM].title !== ''
              : false,
          audioMode: currentConditioning?.[ConditionTypes.COVER]
            ? 'cover'
            : currentConditioning?.[ConditionTypes.EXTEND]
              ? 'extend'
              : undefined,
          isRemix,
          controlParamsChanged: hasChangedControlSliders({
            weirdness_constraint: getCurrentWeirdness(state),
            style_weight: getCurrentStyleInfluence(state),
            audio_weight: getCurrentAudioInfluence(state),
          }),
        },
      });
    },
    [stateRef, isRemix, session, genForm, createV2]
  );

  const logInsufficientCredits = useCallback(
    (transactionLogger: TransactionLogger) => {
      transactionLogger.logWebUserEvent({
        actionName: 'GenerationStartError',
        principalObjectType: 'error_type',
        principalObjectValue: 'Insufficient Credits',
        context: {
          createVersion: CREATE_VERSION,
        },
      });
    },
    []
  );

  return {
    logGenerateButtonClicked,
    logInsufficientCredits,
  };
}
