// This component will interact with the backend API to get the responses from the sales agent.
import { PageVisitCategory, UserEventCategory } from '@spiffy-ai/commerce-api-client';
import { useAtomValue, useSetAtom } from 'jotai';
import { useCallback } from 'react';
import Logger from 'src/application/logging/logger';
import {
  ChatElementDisplayLocationV3,
  FormSubmittedAttributes,
  MessageRole,
  MessageType,
  Suggestion,
  UserEvent,
} from 'src/application/models';
import { hasParsedVariantInfoAtom } from 'src/atoms/app';
import { analyticsContextAtom } from 'src/atoms/app/variant';
import { formSubmitAtom, replyEventCategoryAtom } from 'src/atoms/chat';
import { suggestionsAtom } from 'src/atoms/chat/chatState';
import { queueUserEventAtom } from 'src/atoms/chat/messageQueue';
import { useWidgetInteraction } from 'src/hooks/WidgetInteraction';
import {
  WidgetInteractionComponent,
  WidgetInteractionType,
} from 'src/hooks/WidgetInteraction/types';
import { EnviveMetricsEventName } from 'src/services/amplitudeService/amplitudeService';
import { v4 as uuid } from 'uuid';
import { SpiffyMetricsEventName, useAmplitude } from '../amplitudeContext';

const TRACKED_USER_EVENTS = [
  UserEventCategory.PageVisit,
  UserEventCategory.PdpVisit,
  UserEventCategory.PlpVisit,
];

const logger = new Logger('chatAPI');
export interface SalesAgentChatAPI {
  logPageVisit: ({ pageVisitCategory }: { pageVisitCategory: PageVisitCategory }) => void;
  logUserEvent: (event: UserEvent) => void;
  onSuggestionClicked: (
    suggestion: Suggestion,
    displayLocation: ChatElementDisplayLocationV3,
  ) => void;
  onTypedMessageSubmitted: ({
    query,
    userTyped,
    displayLocation,
  }: {
    query: string;
    userTyped: boolean;
    displayLocation: ChatElementDisplayLocationV3;
  }) => void;
  onFormResponseSubmitted: (form: FormSubmittedAttributes) => void;
}

export const useSalesAgentChatAPI = (widget?: WidgetInteractionComponent) => {
  // TODO: Each of these functions will trigger both the necessary amplitude events and initiate the
  // necessary actions to trigger the backend API
  const context = useAtomValue(analyticsContextAtom);
  const hasParsedVariantInfo = useAtomValue(hasParsedVariantInfoAtom);
  const queueUserEvent = useSetAtom(queueUserEventAtom);
  const setSuggestions = useSetAtom(suggestionsAtom);
  const setReplyEventCategory = useSetAtom(replyEventCategoryAtom);
  const setFormSubmit = useSetAtom(formSubmitAtom);
  const { trackEvent } = useAmplitude();
  const { trackWidgetInteraction } = useWidgetInteraction();
  const contextWidget = widget || WidgetInteractionComponent.FLOATING_CHAT;

  const logPageVisit = useCallback(
    ({ pageVisitCategory }: { pageVisitCategory: PageVisitCategory }) => {
      const eventId = uuid();
      trackEvent({
        eventName: EnviveMetricsEventName.ChatRequest,
        eventProps: {
          ...context,
          'chat.request_id': eventId,
          'chat.request_type': 'page_visit',
        },
      });
      const event: UserEvent = {
        eventId,
        category: UserEventCategory.PageVisit,
        createdAt: new Date().toISOString(),
        attributes: {
          url: window.location.href,
          pageVisitCategory,
        },
      };
      queueUserEvent(event);
    },
    [queueUserEvent, context, trackEvent],
  );

  const logUserEvent = useCallback(
    (event: UserEvent) => {
      if (!hasParsedVariantInfo) {
        logger.logWarn('hasParsedVariantInfo is false, not logging user event', undefined, {
          event,
        });
        return;
      }
      if (TRACKED_USER_EVENTS.includes(event.category)) {
        trackEvent({
          eventName: EnviveMetricsEventName.ChatRequest,
          eventProps: {
            ...context,
            'chat.request_id': event.eventId,
            'chat.request_type': 'page_visit',
          },
        });
      }
      queueUserEvent(event);
    },
    [context, hasParsedVariantInfo, queueUserEvent, trackEvent],
  );
  const onSuggestionClicked = useCallback(
    (suggestion: Suggestion, displayLocation: ChatElementDisplayLocationV3) => {
      trackWidgetInteraction({
        eventName: EnviveMetricsEventName.WidgetInteraction,
        trigger: {
          widget: contextWidget,
          widget_interaction: WidgetInteractionType.SUGGESTION_CLICKED,
          widget_interaction_data: {
            suggestion_clicked: {
              suggestion_id: suggestion.id,
            },
          },
        },
      });

      trackEvent({
        eventName: SpiffyMetricsEventName.ChatSuggestionClicked,
        eventProps: {
          message_id: suggestion.id,
          message_role: MessageRole.User,
          message_type: MessageType.SuggestionClicked,
          message_metadata: {
            content: suggestion.content,
            created_at: suggestion.createdAt,
            category: suggestion.category,
            is_answer: suggestion.isAnswer,
            display_location: displayLocation,
          },
        },
      });
      const eventId = uuid();
      trackEvent({
        eventName: EnviveMetricsEventName.ChatRequest,
        eventProps: {
          ...context,
          'trigger.widget': displayLocation, // This is fairly finegrained, but that may be ok
          'chat.request_id': eventId,
          'chat.request_type': 'suggestion',
          'chat.request_text': suggestion.content,
          'chat.suggestion_id': suggestion.id,
          'chat.suggestion_category': suggestion.category,
          'chat.suggestion_created_at': suggestion.createdAt,
          'chat.suggestion_is_answer': suggestion.isAnswer,
          'chat.user_typed': false,
        },
      });
      const event: UserEvent = {
        eventId,
        category: UserEventCategory.SuggestionClicked,
        createdAt: new Date().toISOString(),
        attributes: {
          suggestionId: suggestion.id,
          content: suggestion.content,
        },
      };
      setSuggestions([]);
      queueUserEvent(event);
    },
    [queueUserEvent, setSuggestions, trackEvent, context],
  );
  const onTypedMessageSubmitted = useCallback(
    ({
      query,
      userTyped,
      displayLocation,
    }: {
      query: string;
      userTyped: boolean;
      displayLocation: ChatElementDisplayLocationV3;
    }) => {
      const eventId = uuid();

      trackWidgetInteraction({
        eventName: EnviveMetricsEventName.WidgetInteraction,
        trigger: {
          widget: contextWidget,
          widget_interaction: WidgetInteractionType.MESSAGE_SUBMITTED,
          widget_interaction_data: {
            message_submitted: {
              request_text: query,
            },
          },
        },
      });

      trackEvent({
        eventName: SpiffyMetricsEventName.ChatUserMessageInput,
        eventProps: {
          query,
          user_typed: userTyped,
          message_id: eventId,
          message_role: MessageRole.User,
          message_type: MessageType.QueryTyped,
          message_metadata: {
            content: query,
            created_at: new Date().toISOString(),
            user_typed: userTyped,
          },
        },
      });
      trackEvent({
        eventName: EnviveMetricsEventName.ChatRequest,
        eventProps: {
          ...context,
          'trigger.widget': displayLocation,
          'chat.request_type': 'text',
          'chat.request_text': query,
          'chat.request_id': eventId,
          'chat.request_created_at': new Date().toISOString(),
          'chat.user_typed': userTyped,
        },
      });
      const event: UserEvent = {
        eventId,
        category: UserEventCategory.QueryTyped,
        createdAt: new Date().toISOString(),
        attributes: {
          query,
          userTyped,
        },
      };
      setSuggestions([]);
      queueUserEvent(event);
    },
    [queueUserEvent, setSuggestions, trackEvent, context],
  );
  const onFormResponseSubmitted = useCallback(
    (form: FormSubmittedAttributes) => {
      setReplyEventCategory(UserEventCategory.FormSubmitted);
      setFormSubmit(form);
      const eventId = uuid();
      trackEvent({
        eventName: EnviveMetricsEventName.ChatRequest,
        eventProps: {
          ...context,
          'chat.request_id': eventId,
          'chat.request_type': 'form',
          'chat.form_response_id': form.formResponseId,
          'chat.form_type': form.formType,
        },
      });
      const event: UserEvent = {
        eventId,
        category: UserEventCategory.FormSubmitted,
        createdAt: new Date().toISOString(),
        attributes: form,
      };
      queueUserEvent(event);
    },
    [setReplyEventCategory, setFormSubmit, trackEvent, context, queueUserEvent],
  );

  return {
    logPageVisit,
    logUserEvent,
    onSuggestionClicked,
    onTypedMessageSubmitted,
    onFormResponseSubmitted,
  };
};
