import { Alert, ScrollShadow, Spinner } from '@heroui/react';
import { useChat, useMujian } from '@mujian/js-sdk/react';
import { useEffect, useMemo, useState } from 'react';
import { useGlobalStore } from '@/store/global';
import { MessageList } from './MessageList';
import { MsgSend } from './MsgSend';

// 扩展Window接口以包含chat对象
declare global {
  interface Window {
    $mj_engine: {
      chat: {
        complete?: (message: string) => Promise<void>;
      };
    };
  }
}

window.$mj_engine = {
  chat: {},
};

export const Chat = () => {
  const { init, projectInfo } = useGlobalStore();
  const mujian = useMujian();
  const [inputValue, setInputValue] = useState('');
  const {
    messages,
    status,
    error,
    append,
    continueGenerate,
    regenerate,
    stop,
    deleteMessage,
    editMessage,
    setSwipe,
  } = useChat({
    onError: (e) => {
      console.error(e);
    },
  });

  // 自定义删除消息函数
  const handleDeleteMessage = async (messageId: string) => {
    // 找到要删除的消息
    const messageIndex = messages.findIndex((msg) => msg.id === messageId);
    if (messageIndex === -1) return;

    let deletedUserMessageContent = '';

    // 检查前一条消息是否是用户消息且被删除的消息是AI消息
    if (messageIndex > 0 && messages[messageIndex].role === 'assistant') {
      const prevMessage = messages[messageIndex - 1];
      if (prevMessage.role === 'user') {
        // 保存用户消息内容
        deletedUserMessageContent = prevMessage.content;
        // 同时删除前一条用户消息
        deleteMessage(prevMessage.id);
      }
    }

    // 删除当前消息
    await deleteMessage(messageId);

    // 如果有删除的用户消息，将其内容填入发送框
    if (deletedUserMessageContent) {
      setInputValue(deletedUserMessageContent);
    }
  };

  const paddingTop = useMemo(() => {
    const params = new URLSearchParams(window.location.search);
    return parseInt(params.get('insetTop') || '0', 10);
  }, []);

  // biome-ignore lint/correctness/useExhaustiveDependencies: onMount ONLY
  useEffect(() => {
    init(mujian);
  }, []);

  const onSend = append;

  // 将chat对象挂载到window上
  useEffect(() => {
    window.$mj_engine.chat.complete = async (message: string) => {
      await onSend(message);
    };

    return () => {
      delete window.$mj_engine.chat.complete;
    };
  }, [onSend]);

  const handleInputChange = (value: string) => {
    setInputValue(value);
  };

  if (status === 'uninitialized') {
    return (
      <div className="w-full h-full flex justify-center items-center">
        <Spinner />
      </div>
    );
  }

  const errorMessage =
    Boolean(error) &&
    (typeof error === 'object' &&
    error &&
    'message' in error &&
    typeof error.message === 'string'
      ? error.message
      : '哎呀，发生了未知错误，刷新页面再试试吧~');

  return (
    <div className="size-full relative">
      <div
        className="h-full opacity-30 blur-xs object-cover absolute top-0 left-1/2 w-[min(640px,100%)] -translate-x-1/2 bg-cover bg-top bg-no-repeat [mask-image:linear-gradient(to_right,transparent,black_100px,black_calc(100%-100px),transparent)]"
        style={{
          backgroundImage: projectInfo
            ? `url(${projectInfo.coverImageUrl})`
            : undefined,
        }}
      />
      <div
        className="size-full z-10 p-3 flex flex-col"
        style={{
          paddingTop,
        }}
      >
        <ScrollShadow hideScrollBar className="h-full" size={20}>
          <MessageList
            data={messages}
            sendMessage={async (q) => {
              await onSend(q);
            }}
            onContinue={continueGenerate}
            onDelete={handleDeleteMessage}
            onEdit={editMessage}
            onSwipe={setSwipe}
            onRegenerate={regenerate}
          />
          {errorMessage && (
            <Alert
              hideIcon
              className="mt-2 mb-6"
              classNames={{
                mainWrapper: 'min-h-4 ml-0',
              }}
              color="danger"
              title={errorMessage}
              variant="bordered"
            />
          )}
        </ScrollShadow>
        <div className="flex flex-col gap-2 mt-2">
          <MsgSend
            running={status === 'streaming'}
            onSend={onSend}
            onStop={stop}
            value={inputValue}
            onChange={handleInputChange}
          />
        </div>
      </div>
    </div>
  );
};
