import React, { useEffect, useRef, useMemo, useState, Fragment } from "react";
import styles from "./home.module.scss";
import DragIcon from "../icons/drag.svg";
import faviconSrc from "../icons/favicon.png";
import deepSeekSrc from "../icons/deepSeek.png";
import { EditOutlined } from '@ant-design/icons';
import { useAppConfig, useChatStore, useGlobalStore } from "../store";
import {
  DEFAULT_SIDEBAR_WIDTH,
  MAX_SIDEBAR_WIDTH,
  MIN_SIDEBAR_WIDTH,
  NARROW_SIDEBAR_WIDTH,
} from "../constant";
import { useLocation, useNavigate } from "react-router-dom";
import { isIOS, useMobileScreen } from "../utils";
import api from "@/app/api/api";
import { Button, Dropdown, Form, Input, Menu, Modal } from "antd";
import { downloadFile } from "../utils/index";

const FormItem = Form.Item;

export function useHotKey() {
  const chatStore = useChatStore();

  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.altKey || e.ctrlKey) {
        if (e.key === "ArrowUp") {
          chatStore.nextSession(-1);
        } else if (e.key === "ArrowDown") {
          chatStore.nextSession(1);
        }
      }
    };

    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  });
}

export function useDragSideBar() {
  const limit = (x: number) => Math.min(MAX_SIDEBAR_WIDTH, x);

  const config = useAppConfig();
  const startX = useRef(0);
  const startDragWidth = useRef(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
  const lastUpdateTime = useRef(Date.now());

  const toggleSideBar = () => {
    config.update((config) => {
      if (config.sidebarWidth < MIN_SIDEBAR_WIDTH) {
        config.sidebarWidth = DEFAULT_SIDEBAR_WIDTH;
      } else {
        config.sidebarWidth = NARROW_SIDEBAR_WIDTH;
      }
    });
  };

  const onDragStart = (e: MouseEvent) => {
    // Remembers the initial width each time the mouse is pressed
    startX.current = e.clientX;
    startDragWidth.current = config.sidebarWidth;
    const dragStartTime = Date.now();

    const handleDragMove = (e: MouseEvent) => {
      if (Date.now() < lastUpdateTime.current + 20) {
        return;
      }
      lastUpdateTime.current = Date.now();
      const d = e.clientX - startX.current;
      const nextWidth = limit(startDragWidth.current + d);
      config.update((config) => {
        if (nextWidth < MIN_SIDEBAR_WIDTH) {
          config.sidebarWidth = NARROW_SIDEBAR_WIDTH;
        } else {
          config.sidebarWidth = nextWidth;
        }
      });
    };

    const handleDragEnd = () => {
      // In useRef the data is non-responsive, so `config.sidebarWidth` can't get the dynamic sidebarWidth
      window.removeEventListener("pointermove", handleDragMove);
      window.removeEventListener("pointerup", handleDragEnd);

      // if user click the drag icon, should toggle the sidebar
      const shouldFireClick = Date.now() - dragStartTime < 300;
      if (shouldFireClick) {
        toggleSideBar();
      }
    };

    window.addEventListener("pointermove", handleDragMove);
    window.addEventListener("pointerup", handleDragEnd);
  };

  const isMobileScreen = useMobileScreen();
  const shouldNarrow =
    !isMobileScreen && config.sidebarWidth < MIN_SIDEBAR_WIDTH;

  useEffect(() => {
    const barWidth = shouldNarrow
      ? NARROW_SIDEBAR_WIDTH
      : limit(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
    const sideBarWidth = isMobileScreen ? "100vw" : `${barWidth}px`;
    document.documentElement.style.setProperty("--sidebar-width", sideBarWidth);
  }, [config.sidebarWidth, isMobileScreen, shouldNarrow]);

  return {
    onDragStart,
    shouldNarrow,
  };
}
export function SideBarContainer(props: {
  children: React.ReactNode;
  onDragStart: (e: MouseEvent) => void;
  shouldNarrow: boolean;
  className?: string;
}) {
  const isMobileScreen = useMobileScreen();
  const isIOSMobile = useMemo(
    () => isIOS() && isMobileScreen,
    [isMobileScreen],
  );
  const { children, className, onDragStart, shouldNarrow } = props;
  return (
    <div
      className={`${styles.sidebar} ${className} ${shouldNarrow && styles["narrow-sidebar"]
        }`}
      style={{
        transition: isMobileScreen && isIOSMobile ? "none" : undefined,
        background: '#FFFFFF',
        overflowY: "auto",
      }}
    >
      {children}
      <div
        className={styles["sidebar-drag"]}
        onPointerDown={(e) => onDragStart(e as any)}
      >
        <DragIcon />
      </div>
    </div>
  );
}

export function SideBarHeader(props: {
  title?: string | React.ReactNode;
  subTitle?: string | React.ReactNode;
  logo?: React.ReactNode;
  children?: React.ReactNode;
}) {
  const { title, subTitle, logo, children } = props;
  return (
    <Fragment>
      <div className={styles["sidebar-header"]} data-tauri-drag-region>
        <div className={styles["sidebar-title-container"]}>
          <div className={styles["sidebar-title"]} data-tauri-drag-region>
            {title}
          </div>
          <div className={styles["sidebar-sub-title"]}>{subTitle}</div>
        </div>
        <div className={styles["sidebar-logo"] + " no-dark"}>{logo}</div>
      </div>
      {children}
    </Fragment>
  );
}

export function SideBarBody(props: {
  children: React.ReactNode;
  onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
}) {
  const { onClick, children } = props;
  return (
    <div className={styles["sidebar-body"]} onClick={onClick}>
      {children}
    </div>
  );
}

export function SideBarTail(props: {
  primaryAction?: React.ReactNode;
  secondaryAction?: React.ReactNode;
}) {
  const { primaryAction, secondaryAction } = props;

  return (
    <div className={styles["sidebar-tail"]}>
      <div className={styles["sidebar-actions"]}>{primaryAction}</div>
      <div className={styles["sidebar-actions"]}>{secondaryAction}</div>
    </div>
  );
}

export const SideBar = (props: { className?: string }) => {
  // useHotKey();
  const { onDragStart, shouldNarrow } = useDragSideBar();
  const [showPluginSelector, setShowPluginSelector] = useState(false);
  const navigate = useNavigate();
  const location = useLocation();
  const chatStore = useChatStore();
  const globalStore = useGlobalStore();

  const [menuList, setMenuList] = useState([])
  const [modalOpen, setModalOpen] = useState(false)
  const [form] = Form.useForm();

  const getType = (): 'bigModel' | 'deepSeek' => {
    if (['/knowledgeChat', '/newChat'].includes(location.pathname)) {
      return 'bigModel';
    } else if (['/deepseekChat', '/newDeepseekChat'].includes(location.pathname)) {
      return 'deepSeek';
    } else {
      return 'bigModel';
    }
  }

  // 获取聊天列表
  const fetchChatList = async () => {
    try {
      let appId = '';
      if (getType() === 'bigModel') {
        appId = globalStore.selectedAppId;
      } else {
        appId = '1881269958412521255';
      }
      const res = await api.get(`/bigmodel/api/dialog/list/${appId}`);
      const list = res.data.map((item: any) => {
        return {
          ...item,
          children: item.children.map((child: any) => {
            const items = [
              {
                key: '1',
                label: (
                  <a onClick={() => {
                    setModalOpen(true);
                    form.setFieldsValue({
                      dialogId: child.key,
                      dialogName: child.label
                    });
                  }}>
                    重命名
                  </a>
                ),
              },
              {
                key: '2',
                label: (
                  <a onClick={async () => {
                    try {
                      const blob = await api.post(`/bigmodel/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
                      const fileName = `${child.label}.xlsx`;
                      downloadFile(blob, fileName);
                    } catch (error) {
                      console.error(error);
                    }
                  }}>
                    导出
                  </a>
                ),
              },
              {
                key: '3',
                label: (
                  <a onClick={async () => {
                    try {
                      await api.delete(`/bigmodel/api/dialog/del/${child.key}`);
                      await fetchChatList()
                      // 删除不需要清理消息
                      // chatStore.clearSessions();
                      // chatStore.updateCurrentSession((value) => {
                      //   value.appId = globalStore.selectedAppId;
                      // });
                    } catch (error) {
                      console.error(error);
                    }
                  }}>
                    删除
                  </a>
                ),
              },
            ];
            return {
              ...child,
              label: <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', marginRight: 10 }}>
                  {child.label}
                </div>
                <div style={{ width: 20 }}>
                  <Dropdown menu={{ items }} trigger={['click']} placement="bottomRight">
                    <EditOutlined onClick={(e) => e.stopPropagation()} />
                  </Dropdown>
                </div>
              </div>
            }
          })
        }
      })
      setMenuList(list);
    } catch (error) {
      console.error(error)
    }
  }

  useEffect(() => {
    fetchChatList();
  }, [globalStore.selectedAppId]);

  useEffect(() => {
    chatStore.clearSessions();
  }, []);

  return (
    <SideBarContainer
      onDragStart={onDragStart}
      shouldNarrow={shouldNarrow}
      {...props}
    >
      {
        getType() === 'deepSeek' &&
        <div>
          <img style={{ width: '100%' }} src={deepSeekSrc.src} />
        </div>
      }
      <SideBarHeader
        title={getType() === 'bigModel' ? '问答历史' : ''}
        logo={getType() === 'bigModel' ? <img style={{ height: 40 }} src={faviconSrc.src} /> : ''}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 10 }}>
          <Button
            style={{ width: '48%' }}
            onClick={() => {
              navigate({ pathname: '/' });
            }}
          >
            回到首页
          </Button>
          <Button
            style={{ width: '48%' }}
            type="primary"
            onClick={async () => {
              chatStore.clearSessions();
              chatStore.updateCurrentSession((value) => {
                value.appId = globalStore.selectedAppId;
              });
              if (getType() === 'bigModel') {
                navigate({ pathname: '/newChat' });
              } else {
                navigate({ pathname: '/newDeepseekChat' });
              }
              await fetchChatList()
            }}
          >
            新建对话
          </Button>
        </div>
      </SideBarHeader>
      <Menu
        style={{ border: 'none' }}
        onClick={async ({ key }) => {
          const res = await api.get(`/bigmodel/api/dialog/detail/${key}`);
          const list = res.data.map(((item: any) => {
            return {
              content: item.content,
              date: item.create_time,
              id: item.did,
              role: item.type,
            }
          }))
          const session = {
            appId: res.data.length ? res.data[0].appId : '',
            dialogName: res.data.length ? res.data[0].dialog_name : '',
            id: res.data.length ? res.data[0].id : '',
            messages: list,
          }
          globalStore.setCurrentSession(session);
          chatStore.clearSessions();
          chatStore.updateCurrentSession((value) => {
            value.appId = session.appId;
            value.topic = session.dialogName;
            value.id = session.id;
            value.messages = list;
          });
          if (getType() === 'bigModel') {
            navigate({ pathname: '/newChat' });
          } else {
            navigate({ pathname: '/newDeepseekChat' });
          }
        }}
        mode="inline"
        items={menuList}
      />
      <Modal
        title="重命名"
        open={modalOpen}
        width={300}
        maskClosable={false}
        onOk={() => {
          form.validateFields().then(async (values) => {
            setModalOpen(false);
            try {
              await api.put('/bigmodel/api/dialog/update', {
                id: values.dialogId,
                dialogName: values.dialogName
              });
              await fetchChatList()
              chatStore.updateCurrentSession((value) => {
                value.topic = values.dialogName;
              });
            } catch (error) {
              console.error(error);
            }
          }).catch((error) => {
            console.error(error);
          });
        }}
        onCancel={() => {
          setModalOpen(false);
        }}
      >
        <Form form={form} layout='inline'>
          <FormItem name='dialogId' noStyle />
          <FormItem
            label='名称'
            name='dialogName'
            rules={[{ required: true, message: '名称不能为空', whitespace: true }]}
          >
            <Input
              style={{ width: 300 }}
              placeholder='请输入'
              maxLength={20}
            />
          </FormItem>
        </Form>
      </Modal>
    </SideBarContainer>
  );
}