import React, { useMemo } from 'react';
import { Text, View } from 'react-native';

import { MessageBubble } from './conversationParts';
import { conversationStyles } from './conversationStyles';
import { formatDateLabel, getMessageFiles, getMessageToolCalls, shouldShowDateSeparator } from './messageUtils';
import type {
  SuperagentAgent,
  SuperagentConnector,
  SuperagentConnectorActionInput,
  SuperagentConversation,
  SuperagentMarkdownRenderer,
  SuperagentMessage,
  SuperagentToolRenderers,
} from '../../types';

export function ConversationMessageList({
  agent,
  availableConnectors,
  conversationId,
  currentUserAvatarUrl,
  messages,
  onConnectConnector,
  onReplyMessage,
  renderMarkdown,
  showDebugPayloads,
  submitToolCallInput,
  toolRenderers,
}: {
  agent: SuperagentAgent;
  availableConnectors?: SuperagentConnector[];
  conversationId: string | null;
  currentUserAvatarUrl?: string | null;
  messages: SuperagentMessage[];
  onConnectConnector?: (input: SuperagentConnectorActionInput) => Promise<boolean | string | void> | boolean | string | void;
  onReplyMessage?: (message: SuperagentMessage) => void;
  renderMarkdown?: SuperagentMarkdownRenderer;
  showDebugPayloads?: boolean;
  submitToolCallInput?: (
    toolCallId: string,
    approve: boolean,
    extraUserInput?: unknown,
    originRequestId?: string,
  ) => Promise<SuperagentConversation | null>;
  toolRenderers?: SuperagentToolRenderers;
}) {
  const displayMessages = useMemo(() => mergeConsecutiveToolOnlyMessages(messages), [messages]);
  const lastAssistantMessageIndex = useMemo(() => {
    for (let index = displayMessages.length - 1; index >= 0; index -= 1) {
      if (displayMessages[index].role === 'assistant') return index;
    }

    return -1;
  }, [displayMessages]);

  return (
    <>
      {displayMessages.map((message, index) => {
        const previousMessage = displayMessages[index - 1];
        const nextMessage = displayMessages[index + 1];
        const showAvatar = !previousMessage || previousMessage.role !== message.role;
        const showTimestamp = !nextMessage || nextMessage.role !== message.role;
        return (
          <View key={message.id ?? `${message.role}-${index}`}>
            {shouldShowDateSeparator(message, previousMessage) ? (
              <DateSeparator label={formatDateLabel(message.createdAt)} />
            ) : null}
            <MessageBubble
              agent={agent}
              availableConnectors={availableConnectors}
              conversationId={conversationId}
              currentUserAvatarUrl={currentUserAvatarUrl}
              isLastAssistantMessage={index === lastAssistantMessageIndex}
              message={message}
              onConnectConnector={onConnectConnector}
              onReplyMessage={onReplyMessage}
              renderMarkdown={renderMarkdown}
              showAvatar={showAvatar}
              showDebugPayloads={showDebugPayloads}
              showTimestamp={showTimestamp}
              submitToolCallInput={submitToolCallInput}
              toolRenderers={toolRenderers}
            />
          </View>
        );
      })}
    </>
  );
}

function mergeConsecutiveToolOnlyMessages(messages: SuperagentMessage[]) {
  const merged: SuperagentMessage[] = [];

  messages.forEach((message) => {
    const toolCalls = getMessageToolCalls(message);
    const isToolOnly = message.role === 'assistant' &&
      !message.content?.trim() &&
      toolCalls.length > 0 &&
      getMessageFiles(message).length === 0;
    const previous = merged[merged.length - 1];

    if (isToolOnly && previous && isMergeableToolOnlyMessage(previous)) {
      const previousToolCalls = getMessageToolCalls(previous);
      merged[merged.length - 1] = {
        ...previous,
        id: previous.id ? `${previous.id}:${message.id ?? toolCalls.length}` : message.id,
        toolCalls: [...previousToolCalls, ...toolCalls],
        tool_calls: [...previousToolCalls, ...toolCalls],
        createdAt: message.createdAt ?? previous.createdAt,
        created_at: message.created_at ?? previous.created_at,
      };
      return;
    }

    merged.push(message);
  });

  return merged;
}

function isMergeableToolOnlyMessage(message: SuperagentMessage) {
  return message.role === 'assistant' &&
    !message.content?.trim() &&
    getMessageToolCalls(message).length > 0 &&
    getMessageFiles(message).length === 0;
}

function DateSeparator({ label }: { label: string }) {
  return (
    <View style={conversationStyles.dateSeparator}>
      <View style={conversationStyles.dateSeparatorLine} />
      <Text style={conversationStyles.dateSeparatorText}>{label}</Text>
      <View style={conversationStyles.dateSeparatorLine} />
    </View>
  );
}
