import React, { useCallback, useState, useRef, useMemo } from 'react';
import {
  Box,
  Card,
  IconButton,
  Flex,
  Grid,
  Button,
  useTheme,
  Drawer,
  DrawerBody,
  DrawerFooter,
  DrawerHeader,
  DrawerOverlay,
  DrawerContent,
  useDisclosure
} from '@chakra-ui/react';
import { usePagination } from '@/web/common/hooks/usePagination';
import {
  getDatasetDataList,
  delOneDatasetDataById,
  getDatasetCollectionById
} from '@/web/core/dataset/api';
import { DeleteIcon } from '@chakra-ui/icons';
import { useQuery } from '@tanstack/react-query';
import { useToast } from '@/web/common/hooks/useToast';
import { debounce } from 'lodash';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { useConfirm } from '@/web/common/hooks/useConfirm';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import MyIcon from '@/components/Icon';
import MyInput from '@/components/MyInput';
import { useLoading } from '@/web/common/hooks/useLoading';
import InputDataModal, { RawSourceText, type InputDataType } from '../components/InputDataModal';
import type { DatasetDataListItemType } from '@/global/core/dataset/type.d';
import { TabEnum } from '..';
import { useUserStore } from '@/web/support/user/useUserStore';
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
import { getDefaultIndex } from '@fastgpt/global/core/dataset/utils';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import {
  DatasetCollectionTypeMap,
  DatasetCollectionTrainingTypeMap
} from '@fastgpt/global/core/dataset/constant';
import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
import { formatFileSize } from '@fastgpt/global/common/file/tools';
import { getFileAndOpen } from '@/web/core/dataset/utils';
import MyTooltip from '@/components/MyTooltip';

const DataCard = () => {
  const BoxRef = useRef<HTMLDivElement>(null);
  const theme = useTheme();
  const lastSearch = useRef('');
  const router = useRouter();
  const { userInfo } = useUserStore();
  const { isPc } = useSystemStore();
  const { collectionId = '', datasetId } = router.query as {
    collectionId: string;
    datasetId: string;
  };
  const { Loading, setIsLoading } = useLoading({ defaultLoading: true });
  const { t } = useTranslation();
  const [searchText, setSearchText] = useState('');
  const { toast } = useToast();
  const { openConfirm, ConfirmModal } = useConfirm({
    content: t('dataset.Confirm to delete the data')
  });
  const { isOpen, onOpen, onClose } = useDisclosure();

  const {
    data: datasetDataList,
    Pagination,
    total,
    getData,
    pageNum,
    pageSize
  } = usePagination<DatasetDataListItemType>({
    api: getDatasetDataList,
    pageSize: 24,
    params: {
      collectionId,
      searchText
    },
    onChange() {
      setIsLoading(false);
      if (BoxRef.current) {
        BoxRef.current.scrollTop = 0;
      }
    }
  });

  const [editInputData, setEditInputData] = useState<InputDataType>();

  // get first page data
  const getFirstData = useCallback(
    debounce(() => {
      getData(1);
      lastSearch.current = searchText;
    }, 300),
    []
  );

  // get file info
  const { data: collection } = useQuery(
    ['getDatasetCollectionById', collectionId],
    () => getDatasetCollectionById(collectionId),
    {
      onError: () => {
        router.replace({
          query: {
            datasetId
          }
        });
      }
    }
  );

  const canWrite = useMemo(
    () => userInfo?.team?.role !== TeamMemberRoleEnum.visitor && !!collection?.canWrite,
    [collection?.canWrite, userInfo?.team?.role]
  );

  const metadataList = useMemo(
    () =>
      collection
        ? [
            {
              label: t('core.dataset.collection.metadata.source'),
              value: t(DatasetCollectionTypeMap[collection.type]?.name)
            },
            {
              label: t('core.dataset.collection.metadata.source name'),
              value: collection.file?.filename || collection?.rawLink || collection?.name
            },
            {
              label: t('core.dataset.collection.metadata.source size'),
              value: collection.file ? formatFileSize(collection.file.length) : '-'
            },
            {
              label: t('core.dataset.collection.metadata.Createtime'),
              value: formatTime2YMDHM(collection.createTime)
            },
            {
              label: t('core.dataset.collection.metadata.Updatetime'),
              value: formatTime2YMDHM(collection.updateTime)
            },
            {
              label: t('core.dataset.collection.metadata.Training Type'),
              value: t(DatasetCollectionTrainingTypeMap[collection.trainingType]?.label)
            },
            {
              label: t('core.dataset.collection.metadata.Chunk Size'),
              value: collection.chunkSize || '-'
            }
          ]
        : [],
    [collection, t]
  );

  return (
    <Box ref={BoxRef} position={'relative'} px={5} py={[1, 5]} h={'100%'} overflow={'overlay'}>
      <Flex alignItems={'center'}>
        <IconButton
          mr={3}
          icon={<MyIcon name={'backFill'} w={['14px', '18px']} color={'myBlue.600'} />}
          bg={'white'}
          boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'}
          size={'sm'}
          borderRadius={'50%'}
          aria-label={''}
          onClick={() =>
            router.replace({
              query: {
                datasetId: router.query.datasetId,
                parentId: router.query.parentId,
                currentTab: TabEnum.collectionCard
              }
            })
          }
        />
        <Flex className="textEllipsis" flex={'1 0 0'} mr={[3, 5]} alignItems={'center'}>
          <Box lineHeight={1.2}>
            <RawSourceText
              sourceName={collection?.name}
              sourceId={collection?.fileId || collection?.rawLink}
              fontSize={['md', 'lg']}
              color={'black'}
              textDecoration={'none'}
            />
            <Box fontSize={'sm'} color={'myGray.500'}>
              文件ID:{' '}
              <Box as={'span'} userSelect={'all'}>
                {collection?._id}
              </Box>
            </Box>
          </Box>
        </Flex>
        {canWrite && (
          <Box>
            <Button
              mx={2}
              variant={'base'}
              size={['sm', 'md']}
              onClick={() => {
                if (!collection) return;
                setEditInputData({
                  q: '',
                  indexes: [getDefaultIndex({ dataId: `${Date.now()}` })]
                });
              }}
            >
              {t('dataset.Insert Data')}
            </Button>
          </Box>
        )}
        {isPc && (
          <MyTooltip label={t('core.dataset.collection.metadata.Read Metadata')}>
            <IconButton
              variant={'base'}
              size={['sm', 'md']}
              icon={<MyIcon name={'menu'} w={'18px'} />}
              aria-label={''}
              onClick={onOpen}
            />
          </MyTooltip>
        )}
      </Flex>
      <Flex my={3} alignItems={'center'}>
        <Box>
          <Box as={'span'} fontSize={['md', 'lg']}>
            {total}组
          </Box>
        </Box>
        <Box flex={1} mr={1} />
        <MyInput
          leftIcon={
            <MyIcon
              name="common/searchLight"
              position={'absolute'}
              w={'14px'}
              color={'myGray.500'}
            />
          }
          w={['200px', '300px']}
          placeholder="根据匹配知识，预期答案和来源进行搜索"
          value={searchText}
          onChange={(e) => {
            setSearchText(e.target.value);
            getFirstData();
          }}
          onBlur={() => {
            if (searchText === lastSearch.current) return;
            getFirstData();
          }}
          onKeyDown={(e) => {
            if (searchText === lastSearch.current) return;
            if (e.key === 'Enter') {
              getFirstData();
            }
          }}
        />
      </Flex>
      <Grid
        minH={'100px'}
        gridTemplateColumns={['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']}
        gridGap={4}
      >
        {datasetDataList.map((item, index) => (
          <Card
            key={item._id}
            cursor={'pointer'}
            p={3}
            userSelect={'none'}
            boxShadow={'none'}
            bg={'myWhite.500'}
            border={theme.borders.sm}
            position={'relative'}
            overflow={'hidden'}
            _hover={{
              borderColor: 'myGray.200',
              boxShadow: 'lg',
              bg: 'white',
              '& .footer': { h: 'auto', p: 3 }
            }}
            onClick={() => {
              if (!collection) return;
              setEditInputData({
                id: item._id,
                q: item.q,
                a: item.a,
                indexes: item.indexes
              });
            }}
          >
            <Flex zIndex={1} alignItems={'center'} justifyContent={'space-between'}>
              <Box border={theme.borders.base} px={2} fontSize={'sm'} mr={1} borderRadius={'md'}>
                # {index + 1}
              </Box>
              <Box className={'textEllipsis'} color={'myGray.500'} fontSize={'xs'}>
                ID:{item._id}
              </Box>
            </Flex>
            <Box
              maxH={'135px'}
              minH={'90px'}
              overflow={'hidden'}
              wordBreak={'break-all'}
              pt={1}
              pb={3}
              fontSize={'13px'}
            >
              <Box color={'black'} mb={1}>
                {item.q}
              </Box>
              <Box color={'myGray.700'}>{item.a}</Box>

              <Flex
                className="footer"
                position={'absolute'}
                top={0}
                bottom={0}
                left={0}
                right={0}
                h={'0'}
                overflow={'hidden'}
                p={0}
                bg={'linear-gradient(to top, white,white 20%, rgba(255,255,255,0) 60%)'}
                alignItems={'flex-end'}
                fontSize={'sm'}
              >
                <Flex alignItems={'center'}>
                  <MyIcon name="common/text/t" w={'14px'} mr={1} color={'myGray.500'} />
                  {item.q.length + (item.a?.length || 0)}
                </Flex>
                <Box flex={1} />
                {canWrite && (
                  <IconButton
                    display={'flex'}
                    icon={<DeleteIcon />}
                    variant={'base'}
                    colorScheme={'gray'}
                    aria-label={'delete'}
                    size={'xs'}
                    borderRadius={'md'}
                    _hover={{ color: 'red.600' }}
                    onClick={(e) => {
                      e.stopPropagation();
                      openConfirm(async () => {
                        try {
                          setIsLoading(true);
                          await delOneDatasetDataById(item._id);
                          getData(pageNum);
                        } catch (error) {
                          toast({
                            title: getErrText(error),
                            status: 'error'
                          });
                        }
                        setIsLoading(false);
                      })();
                    }}
                  />
                )}
              </Flex>
            </Box>
          </Card>
        ))}
      </Grid>

      {/* metadata drawer */}
      <Drawer isOpen={isOpen} placement="right" size={'md'} onClose={onClose}>
        <DrawerOverlay />
        <DrawerContent>
          <DrawerHeader>{t('core.dataset.collection.metadata.metadata')}</DrawerHeader>

          <DrawerBody>
            {metadataList.map((item) => (
              <Flex key={item.label} alignItems={'center'} mb={5}>
                <Box color={'myGray.500'} w={'100px'}>
                  {item.label}
                </Box>
                <Box>{item.value}</Box>
              </Flex>
            ))}
            {collection?.sourceId && (
              <Button
                variant={'base'}
                onClick={() => collection.sourceId && getFileAndOpen(collection.sourceId)}
              >
                {t('core.dataset.collection.metadata.read source')}
              </Button>
            )}
          </DrawerBody>

          <DrawerFooter>
            <Button variant={'base'} onClick={onClose}>
              {t('common.Close')}
            </Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>

      {total > pageSize && (
        <Flex mt={2} justifyContent={'center'}>
          <Pagination />
        </Flex>
      )}
      {total === 0 && (
        <Flex flexDirection={'column'} alignItems={'center'} pt={'10vh'}>
          <MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
          <Box mt={2} color={'myGray.500'}>
            内容空空的，快创建一个吧！
          </Box>
        </Flex>
      )}

      {editInputData !== undefined && collection && (
        <InputDataModal
          collectionId={collection._id}
          defaultValue={editInputData}
          onClose={() => setEditInputData(undefined)}
          onSuccess={() => getData(pageNum)}
          onDelete={() => getData(pageNum)}
        />
      )}
      <ConfirmModal />
      <Loading fixed={false} />
    </Box>
  );
};

export default React.memo(DataCard);
