import React, { useEffect, useMemo } from 'react'

import { Card, SimpleGrid, Stack, Text } from '@mantine/core'
import dayjs from 'dayjs'
import { Link, useParams } from 'react-router-dom'

import { useCurCluster, useUserStore } from '~/hooks/state'
import { useParentClusterOrgId } from '~/hooks/use-parent-cluster-org-id'
import { ClusterStatus } from '~/utils/cluster-status'
import { formatDateTimeWithTz } from '~/utils/date-time'

export const BasicInfo: React.FC = () => {
  const { curCluster, reloadCurCluster } = useCurCluster()
  const { orgId } = useParams<'orgId'>()
  const physicalClusterOrgId = useParentClusterOrgId(curCluster?.parentID)
  const isInternalUser = useUserStore((state) => state.user?.internal)

  const isDeletedCluster =
    curCluster?.status === ClusterStatus.Deleted ||
    curCluster?.status === ClusterStatus.Deletecomplete ||
    curCluster?.status === ClusterStatus.Cleared

  const isServerlessBranchCluster =
    !!curCluster?.computed.isServerless &&
    !!curCluster?.id &&
    String(curCluster.id).startsWith('bran-')

  // 设置页面 title
  useEffect(() => {
    if (curCluster?.name) {
      document.title = `TiDB Clinic - ${curCluster.name}`
    }
  }, [curCluster?.name])

  useEffect(() => {
    // update cluster status every 60 seconds
    const id = setInterval(() => {
      reloadCurCluster()
    }, 60 * 1000)
    return () => {
      clearInterval(id)
    }
  }, [reloadCurCluster])

  let componentList = ['tidb', 'tikv', 'tiflash', 'tiproxy']
  if (isInternalUser) {
    componentList = ['tidb', 'tikv', 'pd', 'tiflash', 'tiproxy']
  }

  type NodeGroupLike = {
    id?: number | string
    displayName?: string
    replicas?: number
    cpuNum?: number
    memoryGi?: number
    tierName?: string
    deletedAt?: number | string
  }

  const isTidbGroupDeleted = (ng: NodeGroupLike) => {
    const deletedAt = ng.deletedAt
    if (typeof deletedAt === 'number') return deletedAt > 0
    if (typeof deletedAt === 'string') return deletedAt.length > 0
    return false
  }

  const formatDeletedAtLocal = (deletedAt: number | string) => {
    if (typeof deletedAt === 'string') {
      const d = dayjs(deletedAt)
      return d.isValid() ? d.format('YYYY-MM-DD') : '-'
    }
    const tsSeconds = deletedAt > 10_000_000_000 ? deletedAt / 1000 : deletedAt
    return dayjs.unix(tsSeconds).format('YYYY-MM-DD')
  }

  const formatComponentSummary = (
    replicas: number,
    name: string,
    nodeInfo: any
  ) => {
    const cpuNum = nodeInfo?.cpuNum as number | undefined
    const memoryGi = nodeInfo?.memoryGi as number | undefined
    const storageType = nodeInfo?.storageType as string | undefined
    const storageSizeGi = nodeInfo?.storageSizeGi as number | undefined

    let infoStr = `${replicas}-${name}-${cpuNum}C${memoryGi}G`

    if (typeof storageSizeGi === 'number' && storageSizeGi > 0) {
      infoStr += `-${storageSizeGi}G`
    }
    if (storageType) {
      infoStr += ` (${storageType})`
    }
    return infoStr
  }

  const topology = useMemo(() => {
    //   curCluster.components example:
    //   {
    //     "COMPONENT_TYPE_PD": {
    //         "replicas": 3,
    //         "cpuNum": 4,
    //         "memoryGi": 8,
    //         "storageSizeGi": 20
    //     },
    //     "COMPONENT_TYPE_TIDB": {
    //         ...
    //     },
    //     "COMPONENT_TYPE_TIFLASH": {
    //         ...
    //     },
    //     "COMPONENT_TYPE_TIKV": {
    //         ...
    //     }
    // }
    return componentList
      .map((c) => {
        const compType = `COMPONENT_TYPE_${c.toUpperCase()}`
        const nodeInfo: any = curCluster?.components?.[compType]
        if (!nodeInfo) return ''
        const replicas = nodeInfo.replicas as number | undefined
        if (!replicas) return ''
        // TiDB summary only shows replica count (no spec)
        if (c === 'tidb') return `${replicas}-tidb`
        return formatComponentSummary(replicas, c, nodeInfo)
      })
      .filter((s) => s !== '')
      .join(' / ')
  }, [curCluster?.components, componentList])

  const tidbGroupLines = useMemo(() => {
    const tidbInfo: any = curCluster?.components?.COMPONENT_TYPE_TIDB
    const groups = (tidbInfo?.tidbGroups as NodeGroupLike[] | null) || []
    const shown = isDeletedCluster
      ? groups
      : groups.filter((g) => !isTidbGroupDeleted(g))

    return shown.map((g) => {
      const name = g.displayName || String(g.id ?? 'unknown')
      const spec = `${g.cpuNum ?? ''}C${g.memoryGi ?? ''}G`
      const deletedSuffix =
        isDeletedCluster && g.deletedAt
          ? ` deleted-at: ${formatDeletedAtLocal(g.deletedAt)}`
          : ''
      return `Nodegroup(${name}): ${g.replicas ?? 0} * ${spec}${deletedSuffix}`
    })
  }, [curCluster?.components, isDeletedCluster])

  return (
    <Card withBorder>
      <Stack>
        <SimpleGrid
          cols={3}
          spacing={8}
          breakpoints={[
            { maxWidth: 'md', cols: 2 },
            { maxWidth: 'sm', cols: 1 }
          ]}
        >
          <div>
            <Text color='dimmed' fw={300}>
              Cluster ID
            </Text>
            <Text>{curCluster?.id}</Text>
          </div>
          {(curCluster?.computed.isServerless ||
            curCluster?.computed.isDedicated) && (
            <div>
              <Text color='dimmed' fw={300}>
                Project ID
              </Text>
              <Text>{curCluster?.projectID}</Text>
            </div>
          )}
          <div>
            <Text color='dimmed' fw={300}>
              Version
            </Text>
            <Text>{curCluster?.version}</Text>
          </div>
          {!curCluster?.computed.isResourcePool && (
            <div>
              <Text color='dimmed' fw={300}>
                Created At
              </Text>
              <Text>{formatDateTimeWithTz(curCluster?.created!)}</Text>
            </div>
          )}
          <div>
            <Text color='dimmed' fw={300}>
              Provider & Region
            </Text>
            <Text>
              {curCluster?.provider} / {curCluster?.region}
            </Text>
          </div>
          {curCluster?.computed.isDedicated && (
            <div>
              <Text color='dimmed' fw={300}>
                Topology
              </Text>
              <Stack spacing={2}>
                <Text size='sm'>{topology || '-'}</Text>
                {tidbGroupLines.map((line, idx) => (
                  <Text
                    key={`tidbGroup-${idx}`}
                    size='sm'
                    c='dimmed'
                    style={{ paddingLeft: 12 }}
                  >
                    {line}
                  </Text>
                ))}
              </Stack>
            </div>
          )}
          {curCluster?.computed.isServerless && (
            <div>
              {isServerlessBranchCluster ? (
                <>
                  <Text color='dimmed' fw={300}>
                    Master Cluster
                  </Text>
                  {curCluster.parentID ? (
                    <Link
                      to={`/orgs/${orgId}/clusters/${curCluster?.parentID}`}
                      target='_blank'
                    >
                      {curCluster?.parentID}
                    </Link>
                  ) : (
                    <Text>-</Text>
                  )}
                </>
              ) : (
                <>
                  <Text color='dimmed' fw={300}>
                    Branches
                  </Text>
                  {curCluster?.branches &&
                    curCluster?.branches.map((branch) => (
                      <Link
                        to={`/orgs/${orgId}/clusters/${branch}`}
                        target='_blank'
                      >
                        {branch}
                      </Link>
                    ))}
                </>
              )}
            </div>
          )}
          {curCluster?.computed.isServerless &&
            !isDeletedCluster &&
            !isServerlessBranchCluster && (
              <>
                <div>
                  <Text color='dimmed' fw={300}>
                    Keyspace
                  </Text>
                  <Stack spacing={2}>
                    <Text>
                      ID:{' '}
                      {curCluster.keyspaceID != null
                        ? String(curCluster.keyspaceID)
                        : '-'}
                    </Text>
                    <Text>
                      Name (token):{' '}
                      {curCluster.keyspaceName?.trim()
                        ? curCluster.keyspaceName.trim()
                        : '-'}
                    </Text>
                  </Stack>
                </div>
                <div>
                  <Text color='dimmed' fw={300}>
                    Spend Limit
                  </Text>
                  <Text>
                    {curCluster.spendLimit != null
                      ? curCluster.spendLimit
                      : '-'}
                  </Text>
                </div>
              </>
            )}
          {(curCluster?.computed.isPremium ||
            curCluster?.computed.isByoc ||
            (curCluster?.computed.isServerless &&
              !isDeletedCluster &&
              !isServerlessBranchCluster)) && (
            <div>
              <Text color='dimmed' fw={300}>
                RCU
              </Text>
              <Text>
                Min: {curCluster?.minRCU}
                <br />
                Max: {curCluster?.maxRCU}
              </Text>
            </div>
          )}
          {isInternalUser &&
            (curCluster?.computed.isDedicated ||
              curCluster?.computed.isPremium ||
              curCluster?.computed.isByoc) && (
              <div>
                <Text color='dimmed' fw={300}>
                  Physic Cluster
                </Text>
                <Text>
                  {physicalClusterOrgId && curCluster?.parentID ? (
                    <Link
                      to={`/orgs/${physicalClusterOrgId}/clusters/${curCluster.parentID}`}
                      target='_blank'
                    >
                      {curCluster.parentID}
                    </Link>
                  ) : (
                    curCluster?.parentID || '-'
                  )}
                </Text>
              </div>
            )}
        </SimpleGrid>
      </Stack>
    </Card>
  )
}
