import React, { useMemo, useRef, useState } from "react";
import {
  Modal,
  Typography,
  message,
  Space,
  Spin,
  Dropdown,
  Button,
} from "antd";
import type { DraggableData, DraggableEvent } from "react-draggable";
import Draggable from "react-draggable";
import { Sender, Welcome, Prompts, Bubble } from "@ant-design/x";
import { PromptsProps } from "@ant-design/x";
import aiLogo from "@/assets/icon-ai-3.png";
import { CoffeeOutlined, SmileOutlined, UserOutlined } from "@ant-design/icons";
import { useChat } from "@/hooks/useChat";
import type { GetProp } from "antd/lib";
import MarkdownViewer from "@/components/ai/MarkdownViewer";
import AITable from "./AITable";

type AICteatorProps = {
  trigger: JSX.Element;
  onChange?: (data: any) => void;
  onError?: (err: Error) => void;
  position?: {
    top?: number | string;
    left?: number | string;
    bottom?: number | string;
    right?: number | string;
  };
};

export default (props: AICteatorProps) => {
  const [open, setOpen] = useState(false);
  const [disabled, setDisabled] = useState(true);
  const [bounds, setBounds] = useState({
    left: 0,
    top: 0,
    bottom: 0,
    right: 0,
  });
  const [input, setInput] = useState("");
  const draggleRef = useRef<HTMLDivElement>(null!);
  const [assistantType, setAssistantType] = useState<"chat" | "generate">(
    "generate"
  );
  const scrollRef = useRef<HTMLDivElement>(null);

  const items: PromptsProps["items"] = [
    {
      key: "6",
      icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
      description: "帮我创建一个用户表",
      disabled: false,
    },
    {
      key: "7",
      icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
      description: "创建一个订单表",
      disabled: false,
    },
  ];

  const handleTry = () => {
    onSubmit(messages[messages.length - 2].content as string);
  };

  // bubbles角色配置
  const roles: GetProp<typeof Bubble.List, "roles"> = {
    assistant: {
      placement: "start",
      avatar: undefined,
      loadingRender: () => (
        <Space>
          <Spin size="small" />
          思考中...
        </Space>
      ),
      messageRender: (content) => {
        return typeof content === "string" ? (
          <Typography className={content?.includes("```") ? "w-full" : ""}>
            {/* <MarkdownViewer content={content} /> */}
            {content?.includes("<generate>") ? (
              <AITable
                content={content}
                onChange={props.onChange}
                onTry={handleTry}
              ></AITable>
            ) : (
              <MarkdownViewer
                content={content.replace("<chat>", "").replace("</chat>", "")}
              />
            )}
          </Typography>
        ) : (
          content
        );
      },
    },
    user: {
      placement: "end",
      avatar: undefined,
      messageRender: (content) => {
        return <div style={{ whiteSpace: "pre-wrap" }}>{content}</div>;
      },
      styles: {
        content: {
          backgroundColor: "#d2e1fb",
        },
      },
    },
  };

  const { loading, onRequest, cancel, messages, setMessages, addConversation } =
    useChat({
      app_name: "data_model",
      onSuccess: (msg) => {
        setMessages((messages) => {
          const arr = [...messages];
          const query = arr[messages.length - 2].content as string;
          arr[messages.length - 1].status = "done";
          arr[messages.length - 1].content += `</${assistantType}>`;
          return arr;
        });
      },
      onUpdate: (msg) => {
        setMessages((messages) => {
          const arr = [...messages];
          arr[messages.length - 1].content += msg.answer;
          arr[messages.length - 1].id = msg.message_id;
          arr[messages.length - 1].loading = false;
          arr[messages.length - 1].status = "loading";
          return arr;
        });
        setTimeout(() => {
          const scrollHeight = scrollRef.current?.scrollHeight;
          scrollRef.current?.scrollTo(0, scrollHeight || 0);
        }, 200);
      },
      onError: (error) => {
        message.error(error.message);
        setMessages((messages) => {
          const arr = [...messages];
          arr[messages.length - 1].content = (
            <Typography.Text type="danger">{error.message}</Typography.Text>
          );
          arr[messages.length - 1].status = "error";
          arr[messages.length - 1].loading = false;
          return arr;
        });
      },
    });

  const triggerDom = React.cloneElement(props.trigger, {
    ...props.trigger.props,
    onClick: () => {
      setOpen(!open);
    },
  });

  const onStart = (_event: DraggableEvent, uiData: DraggableData) => {
    const { clientWidth, clientHeight } = window.document.documentElement;
    const targetRect = draggleRef.current?.getBoundingClientRect();
    if (!targetRect) {
      return;
    }
    setBounds({
      left: -targetRect.left + uiData.x,
      right: clientWidth - (targetRect.right - uiData.x),
      top: -targetRect.top + uiData.y,
      bottom: clientHeight - (targetRect.bottom - uiData.y),
    });
  };

  const onSubmit = (value: string) => {
    setInput("");
    if (value.trim()) {
      setMessages((prev) => [
        ...(prev || []),
        {
          id: Date.now() + "",
          role: "user",
          content: value.trim(),
          status: "done",
        },
        {
          id: Date.now() + "1",
          content: `<${assistantType}>`,
          status: "loading",
          role: "assistant",
          loading: true,
        },
      ]);

      const query =
        assistantType === "generate"
          ? `#角色：你是一个数据模型助手，根据需求部分的描述用生成数据模型工具为用户生成数据模型的json数据，不需要返回其他内容。
#需求：${value.trim()}`
          : value.trim();
      onRequest(query, value.trim());
      setTimeout(() => {
        const scrollHeight = scrollRef.current?.scrollHeight;
        scrollRef.current?.scrollTo(0, scrollHeight || 0);
      }, 200);
    }
  };

  const onStop = () => {
    cancel();
  };

  const handlePromptClick = (item: any) => {
    const msg = item.data.description || item.data.label;
    onSubmit(msg);
  };

  const getStyle: React.CSSProperties = useMemo(
    () =>
      props.position
        ? { position: "absolute", ...props.position }
        : {
            position: "absolute",
            top: 20,
            right: 18,
          },
    [props.position]
  );

  return (
    <>
      {triggerDom}
      <Modal
        title={
          <div
            style={{ width: "100%", cursor: "move" }}
            onMouseOver={() => disabled && setDisabled(false)}
            onMouseOut={() => setDisabled(true)}
          >
            <svg className="icon h-16px w-16px color-#666" aria-hidden="true">
              <use xlinkHref="#icon-AI1"></use>
            </svg>
            <span className="ml-4px">AI助手</span>
          </div>
        }
        mask={false}
        maskClosable={false}
        open={open}
        width={500}
        style={getStyle}
        styles={{
          content: {
            backgroundImage:
              "linear-gradient(137deg, #e5f4ff 0%, #efe7ff 100%)",
            height: "88vh",
          },
          header: { background: "transparent" },
          body: {
            height: "calc(100% - 32px)",
          },
        }}
        footer={null}
        destroyOnClose
        wrapClassName="ai-modal-wrapper"
        onCancel={() => setOpen(false)}
        modalRender={(modal) => (
          <Draggable
            disabled={disabled}
            bounds={bounds}
            nodeRef={draggleRef}
            onStart={(event, uiData) => onStart(event, uiData)}
          >
            <div ref={draggleRef}>{modal}</div>
          </Draggable>
        )}
      >
        <div className="h-full flex flex-col overflow-hidden">
          <div ref={scrollRef} className="flex-1 overflow-auto p-b-12px">
            <div className="my-10">
              <Welcome
                variant="borderless"
                icon={<img src={aiLogo} className="rounded-lg" alt="AI Logo" />}
                title="你好，我是数据模型AI助手"
                description="你需要创建什么的内容，我可以帮你快速生成~"
              />
            </div>

            <Prompts
              className="mb-10"
              items={items}
              vertical
              onItemClick={handlePromptClick}
            />

            <Bubble.List autoScroll roles={roles} items={messages} />
          </div>
          <Sender
            placeholder={
              assistantType === "generate"
                ? "如：创建一个用户表"
                : "请输入咨询问题"
            }
            prefix={
              <Dropdown
                menu={{
                  items: [
                    {
                      key: "1",
                      label: "生成实体表",
                      onClick: () => {
                        setAssistantType("generate");
                        addConversation();
                      },
                    },
                    {
                      key: "2",
                      label: "咨询聊天",
                      onClick: () => {
                        setAssistantType("chat");
                        addConversation();
                      },
                    },
                  ],
                }}
              >
                <Button type="text" className="w-80px">
                  {assistantType === "generate" ? "生成实体表" : "咨询聊天"}
                </Button>
              </Dropdown>
            }
            loading={loading}
            value={input}
            onChange={setInput}
            onSubmit={onSubmit}
            onCancel={onStop}
          />
        </div>
      </Modal>
    </>
  );
};
