import { useChat, type Message, UseChatHelpers } from 'ai/react';
import { toast } from 'react-hot-toast';
import { useEffect, useState } from 'react';
import { ChatEntity, MessageBase } from '../types';
import { saveKVChatMessage } from '../kv/chat';

const useVisionAgent = (chat: ChatEntity) => {
  const { messages: initialMessages, id, url } = chat;
  const {
    messages,
    append: appendRaw,
    reload,
    stop,
    isLoading,
    input,
    setInput,
    setMessages,
  } = useChat({
    sendExtraMessageFields: true,
    api: '/api/vision-agent',
    onResponse(response) {
      if (response.status !== 200) {
        toast.error(response.statusText);
      }
    },
    onFinish(message) {
      saveKVChatMessage(id, message);
    },
    initialMessages: initialMessages,
    body: {
      url,
      id,
    },
  });

  const [loadingDots, setLoadingDots] = useState('');

  useEffect(() => {
    let loadingInterval: NodeJS.Timeout;

    if (isLoading) {
      loadingInterval = setInterval(() => {
        setLoadingDots(prevMessage => {
          switch (prevMessage) {
            case '':
              return '.';
            case '.':
              return '..';
            case '..':
              return '...';
            case '...':
              return '';
            default:
              return '';
          }
        });
      }, 500);
    }

    return () => {
      clearInterval(loadingInterval);
    };
  }, [isLoading]);

  useEffect(() => {
    if (
      !isLoading &&
      messages.length &&
      messages[messages.length - 1].role === 'user'
    ) {
      reload();
    }
  }, [isLoading, messages, reload]);

  const assistantLoadingMessage = {
    id: 'loading',
    content: loadingDots,
    role: 'assistant',
  };

  const messageWithLoading =
    isLoading &&
    messages.length &&
    messages[messages.length - 1].role !== 'assistant'
      ? [...messages, assistantLoadingMessage]
      : messages;

  const append: UseChatHelpers['append'] = async message => {
    await saveKVChatMessage(id, message as MessageBase);
    return appendRaw(message);
  };

  return {
    messages: messageWithLoading as MessageBase[],
    append,
    reload,
    stop,
    isLoading,
    input,
    setInput,
  };
};

export default useVisionAgent;
