"use client";

import { useEffect, useState } from "react";

import { cn } from "@/lib/utils";
import { MessageResponse } from "@/shared/ai-elements/message";
import {
  createStreamingMarkdownBufferState,
  resolveStreamingMarkdownDisplayContent,
  takeNextStreamingMarkdownChunk,
} from "./streaming-token-response-state";

type StreamingTokenResponseProps = {
  content: string;
  streaming: boolean;
  streamDone?: boolean;
  className?: string;
  messageId?: string;
};

const STREAMING_MARKDOWN_FRAME_MS = 45;

export function StreamingTokenResponse({
  content,
  streaming,
  streamDone = !streaming,
  className,
  messageId,
}: StreamingTokenResponseProps) {
  const [displayContent, setDisplayContent] = useState(() =>
    streamDone ? content : ""
  );

  useEffect(() => {
    setDisplayContent((currentDisplayContent) =>
      resolveStreamingMarkdownDisplayContent(
        content,
        currentDisplayContent,
        streamDone
      )
    );
  }, [content, messageId, streamDone]);

  useEffect(() => {
    if (streamDone || !streaming) {
      return;
    }

    const showNextChunk = () => {
      setDisplayContent((currentDisplayContent) => {
        const { chunk, state } = takeNextStreamingMarkdownChunk(
          createStreamingMarkdownBufferState(content, currentDisplayContent)
        );

        if (chunk || state.displayContent !== currentDisplayContent) {
          return state.displayContent;
        }

        return currentDisplayContent;
      });
    };

    showNextChunk();
    const timer = window.setInterval(showNextChunk, STREAMING_MARKDOWN_FRAME_MS);

    return () => window.clearInterval(timer);
  }, [content, streamDone, streaming]);

  if (!displayContent) {
    return null;
  }

  return (
    <MessageResponse
      className={cn("agent-streaming-response", className)}
      isAnimating={streaming}
      mode="streaming"
      parseIncompleteMarkdown={true}
    >
      {displayContent}
    </MessageResponse>
  );
}
