import { Card, Input, Stack, Group, Typography, ActionIcon, ScrollArea, Box, LoadingOverlay } from '@tidbcloud/uikit'
import { Tree, TreeDataNode } from '@tidbcloud/uikit/biz'
import { IconRefreshCw02 } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useMemo, useState } from 'react'

interface ClusterTableViewerProps {
  databases: TreeDataNode[]
  isFetching?: boolean
  onRefresh: () => void
  emptyMessage?: string
  checkedKeys?: {
    checked: string[]
    halfChecked: string[]
  }
  onCheck?: (nodes: { checked: string[]; halfChecked: string[] }) => void
  errorMessage?: string
  placeholder?: string
  showDatabaseOnly?: boolean
}

export const key = (schema: string, table: string) => `${schema}.${table}`
export const unkey = (key: string) => {
  const parts = key.split('.')
  return parts.length === 1 ? { schema: parts[0], table: 'all' as const } : { schema: parts[0], table: parts[1] }
}

export const ClusterTableViewer = observer(
  ({
    databases,
    isFetching = false,
    onRefresh,
    emptyMessage,
    onCheck,
    checkedKeys,
    errorMessage,
    placeholder,
    showDatabaseOnly = false
  }: ClusterTableViewerProps) => {
    const [searchQuery, setSearchQuery] = useState('')
    const filteredTargetTableTreeData: TreeDataNode[] = useMemo(() => {
      if (!searchQuery) {
        return databases
      }
      const filter = (c: any) => c.key.toString().includes(searchQuery)
      return databases
        .filter((i) => i.children && i.children.some(filter))
        .map((i) => ({
          ...i,
          children: i.children?.filter(filter)
        }))
    }, [databases, searchQuery])
    const isEmpty = showDatabaseOnly ? databases.length === 0 : databases?.some((i) => (i.children?.length ?? 0) > 0)

    return (
      <Card withBorder shadow="unset" h={360}>
        <Group>
          <ActionIcon variant="default" onClick={() => onRefresh()}>
            <IconRefreshCw02 size={14} />
          </ActionIcon>

          <Input
            placeholder={placeholder ?? 'Search for table'}
            size="xs"
            sx={{ flexGrow: 1 }}
            onChange={(e: any) => setSearchQuery(e.target.value)}
          />
        </Group>

        {isEmpty ? (
          <Stack align="center" mt={100}>
            <Typography
              variant="body-lg"
              ta="center"
              maw={270}
              dangerouslySetInnerHTML={{
                __html:
                  errorMessage ||
                  emptyMessage ||
                  `No ${showDatabaseOnly ? 'database' : 'table'} in this cluster. Please create one, then refresh.`
              }}
            />
          </Stack>
        ) : (
          <ScrollArea h={298}>
            <Box py={12}>
              <Tree
                treeData={filteredTargetTableTreeData}
                checkable
                autoExpandParent
                checkedKeys={checkedKeys}
                onCheck={(_, info) => {
                  const nodes = {
                    checked: info.checkedNodes.map((i) => i.key) as string[],
                    halfChecked: info.halfCheckedKeys as string[]
                  }
                  onCheck?.(nodes)
                }}
              />
            </Box>
          </ScrollArea>
        )}

        <LoadingOverlay visible={isFetching} overlayProps={{ blur: 2 }} loaderProps={{ color: 'carbon.6' }} />
      </Card>
    )
  }
)
