import React, { useMemo, useRef, useState } from "react";
import {
  Modal,
  Typography,
  message,
  Space,
  Spin,
  Dropdown,
  Button,
  Drawer,
  Divider,
  Input,
} from "antd";
import type { DraggableData, DraggableEvent } from "react-draggable";
import Draggable from "react-draggable";
import { Sender, Welcome, Prompts, Bubble, Conversations } from "@ant-design/x";
import { PromptsProps } from "@ant-design/x";
import aiLogo from "@/assets/icon-ai-3.png";
import {
  CoffeeOutlined,
  DeleteOutlined,
  EditOutlined,
  FireOutlined,
  HistoryOutlined,
  PlusOutlined,
  RedoOutlined,
  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";
import { useModel } from "umi";
import InfiniteScroll from "react-infinite-scroll-component";
import type { ConversationsProps } from "@ant-design/x";
import { ChangeSessionName, DeleteSession } from "@/api/ai";
import { Conversation } from "@ant-design/x/lib/conversations";

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 [openHistory, setOpenHistory] = 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 { onCreateByAi } = useModel("erModel");

  // 提示词
  const items: PromptsProps["items"] = [
    {
      key: "6",
      icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
      description: "帮我创建一个用户表",
      disabled: false,
    },
    {
      key: "7",
      icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
      description: "帮我创建一个订单表",
      disabled: false,
    },
    {
      key: "8",
      icon: <FireOutlined style={{ color: "#FAAD14" }} />,
      description: "客户管理系统需要的表",
      disabled: false,
    },
  ];

  // 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}
              codeFooter={(language, code) => {
                const handleAdd = () => {
                  try {
                    const data = JSON.parse(code);
                    onCreateByAi(data);
                    message.success("添加成功");
                  } catch (error) {
                    message.error("解析失败");
                  }
                };
                return (
                  <Button
                    variant="text"
                    size="small"
                    color="primary"
                    icon={<PlusOutlined />}
                    onClick={handleAdd}
                  >
                    加入画布
                  </Button>
                          
                );
              }}
            />
          </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,
    loadingMessages,
    setMessages,
    conversationList,
    changeConversation,
    loadingSession,
    addConversation,
    setConversationList,
    loadMoreConversation,
    hasMoreConversation,
    refreshConversationList,
    activeConversation,
  } = 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";
        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 handleChangeConversationName = (conversation: Conversation) => {
    let new_name: string;
    Modal.info({
      title: "修改对话名称",
      okText: "提交",
      closable: true,
      content: (
        <div>
          <Input
            type="text"
            defaultValue={conversation.label + ""}
            onChange={(e) => {
              new_name = e.target.value;
            }}
          />
        </div>
      ),
      onOk: () => {
        return ChangeSessionName({
          app_name: "data_model",
          session_id: conversation.key,
          new_name,
        }).then(() => {
          message.success("修改成功");
          setConversationList((list) =>
            list?.map((item) =>
              item.key === conversation.key
                ? { ...item, label: new_name }
                : item
            )
          );
        });
      },
    });
  };

  const handleDeleteConversation = (conversation: Conversation) => {
    Modal.confirm({
      title: "删除对话",
      content: "是否删除对话？",
      okText: "删除",
      cancelText: "取消",
      onOk: () => {
        return DeleteSession({
          app_name: "data_model",
          session_id: conversation.key,
        }).then(() => {
          message.success("删除成功");
          refreshConversationList();

          addConversation();
        });
      },
    });
  };

  const menuConfig: ConversationsProps["menu"] = (conversation) => {
    if (conversation.key === "1") return undefined;
    return {
      items: [
        {
          label: "修改对话名称",
          key: "edit",
          icon: <EditOutlined />,
        },
        {
          label: "删除对话",
          key: "del",
          icon: <DeleteOutlined />,
          danger: true,
        },
      ],
      onClick: (menuInfo) => {
        // 修改对话名称
        if (menuInfo.key === "edit") {
          handleChangeConversationName(conversation);
        }
        // 删除对话
        if (menuInfo.key === "del") {
          handleDeleteConversation(conversation);
        }
      },
    };
  };

  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: "",
          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"
              title="为您推荐:"
              items={items}
              vertical
              onItemClick={handlePromptClick}
            />
            <Spin spinning={loadingMessages}>
              <Bubble.List autoScroll roles={roles} items={messages} />
            </Spin>
          </div>
          <div>
            <div className="flex justify-end">
              <Button
                type="text"
                icon={<PlusOutlined />}
                onClick={() => addConversation}
              />
              <Button
                type="text"
                icon={<HistoryOutlined />}
                onClick={() => setOpenHistory(true)}
              />
            </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>
        </div>
        <Drawer
          title="历史记录"
          open={openHistory}
          onClose={() => setOpenHistory(false)}
          placement="right"
          getContainer={false}
          width={280}
          styles={{ body: { padding: '0 12px' } }}
        >
          <div id="scrollableDiv" className="w-full h-full overflow-auto">
            <InfiniteScroll
              dataLength={conversationList?.length || 0}
              next={loadMoreConversation}
              hasMore={hasMoreConversation}
              loader={
                <div style={{ textAlign: "center" }}>
                  <Spin indicator={<RedoOutlined spin />} size="small" />
                </div>
              }
              endMessage={
                <Divider plain>
                  <span className="text-12px text-text-secondary">
                    无更多会话~
                  </span>
                </Divider>
              }
              scrollableTarget="scrollableDiv"
              style={{ overflow: "hidden" }}
            >
              <Spin spinning={loadingSession} className="flex-col">
                <Conversations
                  groupable
                  style={{ width: 200, padding: 0, margin: 0 }}
                  activeKey={activeConversation}
                  onActiveChange={changeConversation}
                  menu={menuConfig}
                  items={conversationList}
                />
              </Spin>
            </InfiniteScroll>
          </div>
        </Drawer>
      </Modal>
    </>
  );
};
