import React, { useCallback, useRef, useState } from 'react';
import type { MouseEvent } from 'react';
import { AddIcon } from '@chakra-ui/icons';
import {
  Box,
  Button,
  Flex,
  useTheme,
  Menu,
  MenuList,
  MenuItem,
  useOutsideClick
} from '@chakra-ui/react';
import { ChatIcon } from '@chakra-ui/icons';
import { useRouter } from 'next/router';
import { formatTimeToChatTime } from '@/utils/tools';
import MyIcon from '@/components/Icon';
import type { ShareChatHistoryItemType, ExportChatType } from '@/types/chat';
import { useChatStore } from '@/store/chat';
import { useGlobalStore } from '@/store/global';

import styles from '../index.module.scss';

const PcSliderBar = ({
  onclickDelHistory,
  onclickExportChat,
  onCloseSlider
}: {
  onclickDelHistory: (historyId: string) => void;
  onclickExportChat: (type: ExportChatType) => void;
  onCloseSlider: () => void;
}) => {
  const router = useRouter();
  const { shareId = '', historyId = '' } = router.query as {
    shareId: string;
    historyId: string;
  };
  const theme = useTheme();
  const { isPc } = useGlobalStore();

  const ContextMenuRef = useRef(null);
  const onclickContext = useRef(false);

  const [contextMenuData, setContextMenuData] = useState<{
    left: number;
    top: number;
    history: ShareChatHistoryItemType;
  }>();

  const { shareChatHistory } = useChatStore();

  // close contextMenu
  useOutsideClick({
    ref: ContextMenuRef,
    handler: () => {
      setTimeout(() => {
        if (contextMenuData && !onclickContext.current) {
          setContextMenuData(undefined);
        }
      }, 10);
      setTimeout(() => {
        onclickContext.current = false;
      }, 10);
    }
  });

  const onclickContextMenu = useCallback(
    (e: MouseEvent<HTMLDivElement>, history: ShareChatHistoryItemType) => {
      e.preventDefault(); // 阻止默认右键菜单

      if (!isPc) return;
      onclickContext.current = true;

      setContextMenuData({
        left: e.clientX,
        top: e.clientY,
        history
      });
    },
    [isPc]
  );

  const replaceChatPage = useCallback(
    ({ hId = '', shareId }: { hId?: string; shareId: string }) => {
      if (hId === historyId) return;

      router.replace(`/chat/share?shareId=${shareId}&historyId=${hId}`);
      !isPc && onCloseSlider();
    },
    [historyId, isPc, onCloseSlider, router]
  );

  return (
    <Flex
      position={'relative'}
      flexDirection={'column'}
      w={'100%'}
      h={'100%'}
      bg={'white'}
      borderRight={['', theme.borders.base]}
    >
      {/* 新对话 */}
      <Box
        className={styles.newChat}
        zIndex={1000}
        w={'90%'}
        h={'40px'}
        my={5}
        mx={'auto'}
        position={'relative'}
      >
        <Button
          variant={'base'}
          w={'100%'}
          h={'100%'}
          leftIcon={<AddIcon />}
          onClick={() => replaceChatPage({ shareId })}
        >
          新对话
        </Button>
      </Box>

      {/* chat history */}
      <Box flex={'1 0 0'} h={0} overflow={'overlay'}>
        {shareChatHistory.map((item) => (
          <Flex
            position={'relative'}
            key={item._id}
            alignItems={'center'}
            py={3}
            pr={[0, 3]}
            pl={[6, 3]}
            cursor={'pointer'}
            transition={'background-color .2s ease-in'}
            borderLeft={['none', '5px solid transparent']}
            userSelect={'none'}
            _hover={{
              backgroundColor: ['', '#dee0e3']
            }}
            {...(item._id === historyId
              ? {
                  backgroundColor: '#eff0f1',
                  borderLeftColor: 'myBlue.600 !important'
                }
              : {})}
            onClick={() => replaceChatPage({ hId: item._id, shareId: item.shareId })}
            onContextMenu={(e) => onclickContextMenu(e, item)}
          >
            <ChatIcon fontSize={'16px'} color={'myGray.500'} />
            <Box flex={'1 0 0'} w={0} ml={3}>
              <Flex alignItems={'center'}>
                <Box flex={'1 0 0'} w={0} className="textEllipsis" color={'myGray.1000'}>
                  {item.title}
                </Box>
                <Box color={'myGray.400'} fontSize={'sm'}>
                  {formatTimeToChatTime(item.updateTime)}
                </Box>
              </Flex>
              <Box className="textEllipsis" mt={1} fontSize={'sm'} color={'myGray.500'}>
                {item.latestChat || '……'}
              </Box>
            </Box>
            {/* phone quick delete */}
            {!isPc && (
              <MyIcon
                px={3}
                name={'delete'}
                w={'16px'}
                onClickCapture={(e) => {
                  e.stopPropagation();
                  onclickDelHistory(item._id);
                  item._id === historyId && replaceChatPage({ shareId: item.shareId });
                }}
              />
            )}
          </Flex>
        ))}
        {shareChatHistory.length === 0 && (
          <Flex h={'100%'} flexDirection={'column'} alignItems={'center'} pt={'30vh'}>
            <MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
            <Box mt={2} color={'myGray.500'}>
              还没有聊天记录
            </Box>
          </Flex>
        )}
      </Box>
      {/* context menu */}
      {contextMenuData && (
        <Box zIndex={10} position={'fixed'} top={contextMenuData.top} left={contextMenuData.left}>
          <Box ref={ContextMenuRef}></Box>
          <Menu isOpen>
            <MenuList>
              <MenuItem
                onClick={() => {
                  onclickDelHistory(contextMenuData.history._id);
                  contextMenuData.history._id === historyId && replaceChatPage({ shareId });
                }}
              >
                删除记录
              </MenuItem>
              <MenuItem onClick={() => onclickExportChat('html')}>导出HTML格式</MenuItem>
              <MenuItem onClick={() => onclickExportChat('pdf')}>导出PDF格式</MenuItem>
              <MenuItem onClick={() => onclickExportChat('md')}>导出Markdown格式</MenuItem>
            </MenuList>
          </Menu>
        </Box>
      )}
    </Flex>
  );
};

export default PcSliderBar;
