import { Badge, Group, Tabs, Typography } from '@tidbcloud/uikit'
import { LabelTooltip } from '@tidbcloud/uikit/biz'
import { useLocalStorage } from '@tidbcloud/uikit/hooks'
import { observer } from 'mobx-react'
import { useEffect, useMemo } from 'react'
import { useHistory, useLocation } from 'react-router-dom'

import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { CloudProviderConst } from 'dbaas/features/Project'
import { ExpFeatHashmap } from 'dbaas/stores/localStorage'
import useStores from 'dbaas/stores/useStores'
import { isIndexAdvisorEnabled } from 'dbaas/utils/feature-flags'

import { AdvisorHelperButton } from './IndexAdvisor/components/AdvisorHelperButton'
import { useShouldShowSQLRepository } from './SQLRepository/utils/context-impl'

type TabConfig = {
  path: string
  title: string | React.ReactElement
  hide?: boolean
  tooltip?: string
}
interface DiagnosisTabsLayoutProps {
  cluster: SharedCluster
}

const DiagnosisTabsLayout: React.FC<React.PropsWithChildren<DiagnosisTabsLayoutProps>> = observer(
  ({ cluster, children }) => {
    const {
      store: { tenantData, activeProjectId, expWhiteList }
    } = useStores()
    const history = useHistory()
    const location = useLocation()
    const [lastTab, setLastTab] = useLocalStorage<{ clusterId: string; tab: string }>({
      key: 'dbaas.diagnosis.last_tab',
      defaultValue: { clusterId: '', tab: '' },
      getInitialValueInEffect: false
    })

    const TAB_CONFIGS_SERVERLESS: TabConfig[] = [
      {
        path: 'slow-query',
        title: 'Slow Query',
        hide: cluster.provider === CloudProviderConst.AZURE,
        tooltip: cluster.provider === CloudProviderConst.AZURE ? 'Coming Soon' : ''
      },
      {
        path: 'sql-statement-v2',
        title: (
          <Group gap={8}>
            Statement Insight
            <Badge variant="outline" size="sm" color="carbon" c="carbon.7" fw={500}>
              Preview
            </Badge>
          </Group>
        ),
        hide: !cluster.computed.isEssential || !expWhiteList[ExpFeatHashmap.EssentialEnhancedStatementEnable]
      },
      {
        path: 'sql-statement',
        title: 'SQL Statement'
      },
      {
        path: 'index-advisor',
        hide: cluster.provider === CloudProviderConst.AZURE || !isIndexAdvisorEnabled(tenantData.id),
        title: (
          <Group gap={8}>
            Index Advisor
            <Badge variant="outline" size="sm" color="carbon" c="carbon.7" fw={500}>
              Preview
            </Badge>
          </Group>
        )
      }
    ]

    const dsInfo = useMemo(
      () => ({
        orgId: tenantData.id,
        projectId: activeProjectId,
        clusterId: cluster.id,
        clusterProvider: cluster.provider,
        clusterRegion: cluster.region,
        computed: cluster.computed
      }),
      [tenantData.id, activeProjectId, cluster.id, cluster.provider, cluster.region, cluster.computed]
    )
    const shouldShowSQLRepository = useShouldShowSQLRepository(dsInfo)

    const TAB_CONFIGS_DEDICATED: TabConfig[] = [
      {
        path: 'slow-query',
        title: 'Slow Query'
      },
      {
        path: 'sql-statement',
        title: 'SQL Statement'
      },
      {
        path: 'sql-repository',
        title: (
          <Group gap={4}>
            SQL Repository
            <Badge variant="outline" size="sm" color="carbon" c="carbon.7" fw={500}>
              Preview
            </Badge>
            <LabelTooltip
              position="bottom-start"
              withArrow={false}
              label={
                <Typography>
                  <Typography fw="bold" component="span">
                    SQL Repository
                  </Typography>{' '}
                  comes up with{' '}
                  <Typography fw="bold" component="span">
                    extended history
                  </Typography>
                  , providing deeper insights and advanced utilities like{' '}
                  <Typography fw="bold" component="span">
                    SQL Binding
                  </Typography>{' '}
                  for enhanced diagnostics.
                </Typography>
              }
            />
          </Group>
        ),
        hide: !shouldShowSQLRepository
      },
      {
        path: 'key-viz',
        title: 'Key Visualizer'
      }
    ]

    const tabConfigs = cluster.computed.isServerless ? TAB_CONFIGS_SERVERLESS : TAB_CONFIGS_DEDICATED
    const visibleTabPaths = useMemo(() => tabConfigs.filter((v) => !v.hide).map((v) => v.path), [tabConfigs])

    const tabValue = useMemo(
      () =>
        [...tabConfigs]
          .sort((left, right) => right.path.length - left.path.length)
          .find((cfg) => location.pathname.includes(cfg.path))?.path,
      [location, tabConfigs]
    )

    function changeTab(path: string) {
      history.push(path)
      setLastTab({ clusterId: cluster.id, tab: path })
    }

    useEffect(() => {
      if (!location.pathname.endsWith('/diagnosis/')) {
        return
      }
      const firstValidPath = tabConfigs.find((v) => !v.hide)?.path ?? ''
      if (lastTab.clusterId !== cluster.id) {
        history.replace(firstValidPath)
      } else {
        history.replace(visibleTabPaths.includes(lastTab.tab) ? lastTab.tab : firstValidPath)
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    return (
      <Tabs value={tabValue} onChange={changeTab} className="wd-h-full" keepMounted={false}>
        <Tabs.List className="wd-border-0 wd-mb-16px wd-relative">
          {tabConfigs
            .filter((v) => !v.hide)
            .map((cfg) => (
              <Tabs.Tab
                key={cfg.path}
                value={cfg.path}
                data-mp-event={`${cfg.title} Tab Clicked`}
                data-mp-source="LayoutV2 - Cluster - SQL Diagnosis"
                data-mp-path={cfg.path}
              >
                {cfg.title}
              </Tabs.Tab>
            ))}
          {tabValue === 'index-advisor' && <AdvisorHelperButton />}
        </Tabs.List>
        {children}
      </Tabs>
    )
  }
)

export default DiagnosisTabsLayout
