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 { AppstoreOutlined, EditOutlined, MenuOutlined } 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, Drawer, Dropdown, Empty, Form, Input, Menu, message, Modal, Rate, Tag } from "antd";
import { downloadFile } from "../utils/index";
import dayjs from "dayjs";

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>
  );
}

interface AppDrawerProps {
  isMobileScreen: boolean,
  selectedAppId: string,
  type: 'all' | 'collect',
  open: boolean,
  onClose: () => void,
}

const AppDrawer: React.FC<AppDrawerProps> = (props) => {
  const {
    isMobileScreen,
    selectedAppId,
    type,
    open,
    onClose,
  } = props;

  const navigate = useNavigate();

  const [listLoading, setListLoading] = useState(false);

  type List = {
    name: string,
    chatMode: string,
    appId: string,
    desc: string,
    createTime: string,
    typeName: string,
    isCollect: boolean,
  }[];

  const [list, setList] = useState<List>([]);

  const fetchAppList = async () => {
    setListLoading(true);
    try {
      const res = await api.get(`/deepseek/api/project/app`);
      // 确保 res.data 是数组，如果不是则设为空数组
      const data = Array.isArray(res.data) ? res.data : [];
      
      if (type === 'all') {
        setList(data);
      } else {
        setList(data.filter((item: any) => item.isCollect));
      }
    } catch (error) {
      console.error(error);
      // 出错时设置为空数组，避免渲染错误
      setList([]);
    } finally {
      setListLoading(false);
    }
  };

  // 收藏应用
  const collectApp = async (appId: string) => {
    try {
      await api.post('/deepseek/api/app/collect', {
        appId: appId
      });
      message.success('收藏成功');
      await fetchAppList();
    } catch (error: any) {
      message.error(error.msg);
    }
  };

  // 取消收藏应用
  const cancelCollectApp = async (appId: string) => {
    try {
      await api.delete(`/deepseek/api/app/collect/${appId}`);
      message.success('操作成功');
      await fetchAppList();
    } catch (error: any) {
      message.error(error.msg);
    }
  };

  const init = async () => {
    await fetchAppList();
  }

  useEffect(() => {
    init();
  }, [])

  return (
    <Drawer
      width={isMobileScreen ? '100%' : 400}
      title={type === 'all' ? '我的应用' : '我的收藏'}
      open={open}
      loading={listLoading}
      onClose={onClose}
    >
      {
        Array.isArray(list) && list.length > 0 ?
          list.map((item, index) => {
            return <div
              style={{
                padding: 20,
                border: '1px solid #f0f0f0',
                borderRadius: 4,
                marginBottom: 20,
                cursor: 'pointer',
              }}
              key={index}
            >
              <div style={{ display: 'flex', marginBottom: 10 }}>
                <AppstoreOutlined style={{ fontSize: 40, color: '#3875f6', marginRight: 20 }} />
                <div>
                  <div style={{ fontSize: 16, fontWeight: 'bold', marginBottom: 5 }}>
                    {item.name}
                  </div>
                  <div style={{ color: '#d4d7de' }}>
                    ID:{item.appId}
                  </div>
                </div>
              </div>
              <div style={{ color: '#8f949e', marginBottom: 10 }}>
                {item.desc}
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
                <div style={{ color: '#747a86' }}>
                  {dayjs(item.createTime).format('YYYY-MM-DD')} 发布
                </div>
                <div>
                  <Tag style={{ margin: 0 }} color="blue">
                    {item.typeName}
                  </Tag>
                </div>
              </div>
              <div
                style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div onClick={async () => {
                  if (item.isCollect) {
                    await cancelCollectApp(item.appId);
                  } else {
                    await collectApp(item.appId);
                  }
                }}>
                  {
                    item.isCollect ?
                      <Rate count={1} value={1} />
                      :
                      <Rate count={1} />
                  }
                </div>
                <Button type='primary' size="small" onClick={() => {
                  const search = `?showMenu=false&chatMode=${item.chatMode}&appId=${item.appId}`;
                  navigate({
                    pathname: '/knowledgeChat',
                    search: search,
                  })
                  location.reload();
                }}>
                  使用
                </Button>
              </div>
            </div>
          })
          :
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
      }
    </Drawer>
  )
}

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 (chatMode?: 'ONLINE' | 'LOCAL') => {
    try {
      let url = '';
      if (getType() === 'bigModel') {
        const appId = globalStore.selectedAppId;
        if (appId) {
          if (chatMode === 'LOCAL') {
            url = `/deepseek/api/dialog/list/${appId}`;
          } else {
            url = `/bigmodel/api/dialog/list/${appId}`;
          }
        }
      } else {
        const appId = '1881269958412521255';
        url = `/bigmodel/api/dialog/list/${appId}`;
      }
      const res = await api.get(url);
      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 {
                      let blob = null;
                      if (getType() === 'bigModel') {
                        if (chatMode === 'LOCAL') {
                          blob = await api.post(`/deepseek/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
                        } else {
                          blob = await api.post(`/bigmodel/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
                        }
                      } else {
                        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 {
                      if (getType() === 'bigModel') {
                        if (chatMode === 'LOCAL') {
                          await api.delete(`/deepseek/api/dialog/del/${child.key}`);
                          await fetchChatList(chatMode);
                        } else {
                          await api.delete(`/bigmodel/api/dialog/del/${child.key}`);
                          await fetchChatList();
                        }
                      } else {
                        await api.delete(`/bigmodel/api/dialog/del/${child.key}`);
                        await fetchChatList();
                      }
                      chatStore.clearSessions();
                      useChatStore.setState({
                        message: {
                          content: '',
                          role: 'assistant',
                        }
                      });
                    } 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(() => {
    if (getType() === 'bigModel') {
      if (globalStore.selectedAppId) {
        fetchChatList(chatStore.chatMode);
      }
    }
  }, [globalStore.selectedAppId]);

  useEffect(() => {
    chatStore.clearSessions();
    useChatStore.setState({
      message: {
        content: '',
        role: 'assistant',
      }
    });
  }, []);

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

  const isMobileScreen = useMobileScreen();

  const [drawerOpen, setDrawerOpen] = useState(false);

  const [drawerType, setDrawerType] = useState<'all' | 'collect'>('all');

  return (
    <>
      {
        globalStore.showMenu &&
        <SideBarContainer
          onDragStart={onDragStart}
          shouldNarrow={shouldNarrow}
          {...props}
        >
          {
            getType() === 'deepSeek' &&
            <div>
              <img style={{ width: '100%' }} src={deepSeekSrc.src} />
            </div>
          }
          <SideBarHeader
            title={getType() === 'bigModel' ?
              <div style={{ display: 'flex', alignItems: 'center' }}>
                {
                  isMobileScreen && <div>
                    <Button
                      type='text'
                      icon={<MenuOutlined />}
                      onClick={() => {
                        globalStore.setShowMenu(!globalStore.showMenu);
                      }}
                    />
                  </div>
                }
                问答历史
              </div>
              :
              ''
            }
            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%' }}
                onClick={async () => {
                  chatStore.clearSessions();
                  chatStore.updateCurrentSession((value) => {
                    value.appId = globalStore.selectedAppId;
                  });
                  if (isMobileScreen) {
                    globalStore.setShowMenu(false);
                  }
                  if (getType() === 'bigModel') {
                    navigate({ pathname: '/newChat' });
                  } else {
                    navigate({ pathname: '/newDeepseekChat' });
                  }
                  if (getType() === 'bigModel') {
                    if (chatStore.chatMode === 'LOCAL') {
                      await fetchChatList(chatStore.chatMode);
                    } else {
                      await fetchChatList();
                    }
                  } else {
                    await fetchChatList();
                  }
                }}
              >
                新建对话
              </Button>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 10 }}>
              <Button
                style={{ width: '48%' }}
                type="primary"
                onClick={() => {
                  setDrawerType('all');
                  setDrawerOpen(true);
                }}
              >
                我的应用
              </Button>
              <Button
                style={{ width: '48%' }}
                type="primary"
                onClick={() => {
                  setDrawerType('collect');
                  setDrawerOpen(true);
                }}
              >
                我的收藏
              </Button>
            </div>
          </SideBarHeader>
          <Menu
            style={{ border: 'none' }}
            onClick={async (info) => {
              const key = info.key;
              // @ts-ignore
              const props = info.item.props;
              const { showMenu, chatMode, appId } = props;
              if (isMobileScreen) {
                globalStore.setShowMenu(false);
              }
              let url = ``;
              if (getType() === 'bigModel') {
                if (chatStore.chatMode === 'LOCAL') {
                  url = `/deepseek/api/dialog/detail/${key}`;
                } else {
                  url = `/bigmodel/api/dialog/detail/${key}`;
                }
              } else {
                url = `/bigmodel/api/dialog/detail/${key}`;
              }
              const res = await api.get(url);
              const list = res.data.map(((item: any) => {
                return {
                  id: item.did,
                  role: item.type,
                  date: item.create_time,
                  content: item.content,
                  document: item.document ? item.document : undefined,
                  sliceInfo: item.sliceInfo ? item.sliceInfo : undefined,
                  networkInfo: item.networkInfo ? item.networkInfo : undefined,
                }
              }))
              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') {
                const search = `?showMenu=${showMenu}&chatMode=${chatMode}&appId=${appId}`;
                if (appId) {
                  navigate({
                    pathname: '/knowledgeChat',
                    search: search,
                  })
                }
              } 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 {
                  if (getType() === 'bigModel') {
                    if (chatStore.chatMode === 'LOCAL') {
                      await api.put(`/deepseek/api/dialog/update`, {
                        id: values.dialogId,
                        dialogName: values.dialogName
                      });
                      await fetchChatList(chatStore.chatMode);
                    } else {
                      await api.put(`/bigmodel/api/dialog/update`, {
                        id: values.dialogId,
                        dialogName: values.dialogName
                      });
                      await fetchChatList();
                    }
                  } else {
                    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>
      }
      {
        drawerOpen &&
        <AppDrawer
          isMobileScreen={isMobileScreen}
          selectedAppId={globalStore.selectedAppId}
          type={drawerType}
          open={drawerOpen}
          onClose={() => {
            setDrawerOpen(false);
          }}
        />
      }
    </>
  );
}