import { Card, Group, Loader, Stack, Typography } from '@tidbcloud/uikit'
import { PropertyCard } from '@tidbcloud/uikit/biz'
import { observer } from 'mobx-react'
import { useMemo } from 'react'
import { useParams } from 'react-router-dom'

import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import TimeComponent from 'dbaas/components/TimeComponent'
import { getChangefeedDestinationName } from 'dbaas/features/Changefeed'
import { ChangefeedStatus } from 'dbaas/features/Changefeed/ChangefeedStatus'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { TiDBPageShell } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/TiDBPageShell'
import { useNgGetChangefeed, useNgGetSinkEndpoint } from 'dbaas/services/dataflow'
import { useGetMetricsQueryRangeURL } from 'dbaas/services/useO11YQuery'
import useStores from 'dbaas/stores/useStores'

import { getMetricsConfig } from '../ChangefeedDetail/getMetricsConfig'
import { S3Properties } from '../ChangefeedDetail/S3Properties'
import { MetricsChartOnChangeFeed } from '../ConnectorCard/MetricsChart'
import { isPrivateConnect } from '../CreateOrEditChangefeedPremium/helper'

import { ChangefeedDetailActionPremium } from './ChangefeedDetailActionPremium'
import { KafkaPropertiesPremium } from './KafkaPropertiesPremium'
import { MySQLPropertiesPremium } from './MySQLPropertiesPremium'
import { PremiumSpecificationProperty } from './SpecificationProperty'

const ChangefeedDetailPremium = () => {
  const { id: tidbId, changefeedId } = useParams<{ id: string; changefeedId: string }>()
  const cluster = useSharedTiDBContext()
  const {
    store: { tenantData }
  } = useStores()

  const {
    data,
    isLoading: isLoadingChangefeed,
    isFetched: isChangefeedFetched,
    isError: isChangefeedError,
    refetch
  } = useNgGetChangefeed(cluster.tidbId!, changefeedId ?? '', {
    query: {
      enabled: !!cluster.tidbId && !!changefeedId,
      refetchOnWindowFocus: false
    }
  })
  const sinkEndpointId = data?.request?.network_info?.sink_endpoint_id
  const changefeedMetricName = `changefeed-${changefeedId}`

  const {
    data: metricsURL,
    isLoading: isLoadingMetricsURL,
    metricRequestOptions
  } = useGetMetricsQueryRangeURL(tenantData.id, cluster)

  const metricsConfig = useMemo(() => {
    return getMetricsConfig(changefeedMetricName, '8.0.0')
  }, [changefeedMetricName])

  const { data: sinkEndpointData, isLoading: isLoadingSinkEndpoint } = useNgGetSinkEndpoint(tidbId, sinkEndpointId!, {
    query: {
      enabled: !!tidbId && !!sinkEndpointId && isPrivateConnect(data?.request?.network_info?.network_type),
      refetchOnWindowFocus: false
    }
  })

  if (isLoadingChangefeed || isLoadingSinkEndpoint) {
    return (
      <TiDBPageShell title="Changefeed Detail" headerProps={{ withBack: true }}>
        <HeroComponent ready={isHeroQueryReady({ isFetched: isChangefeedFetched, isError: isChangefeedError })} />
        <Loader size="xs" />
      </TiDBPageShell>
    )
  }

  if (!data) {
    return (
      <TiDBPageShell title="Changefeed Detail" headerProps={{ withBack: true }}>
        <HeroComponent ready={isHeroQueryReady({ isFetched: isChangefeedFetched, isError: isChangefeedError })} />
        <Typography>Changefeed task not found.</Typography>
      </TiDBPageShell>
    )
  }

  return (
    <TiDBPageShell
      title="Changefeed Detail"
      headerProps={{
        withBack: true,
        rightSection: <ChangefeedDetailActionPremium cluster={cluster} changefeed={data} refetch={refetch} />
      }}
    >
      <HeroComponent ready={isHeroQueryReady({ isFetched: isChangefeedFetched, isError: isChangefeedError })} />
      <Group align="start" gap={24} wrap="nowrap">
        <Stack justify="flex-start" sx={{ flexGrow: 1 }}>
          <Card>
            <Stack>
              <Typography variant="title-lg">Metrics</Typography>
              {metricsURL && metricsConfig.length > 0 ? (
                <MetricsChartOnChangeFeed
                  metricSourceURI={metricsURL}
                  metricInfo={metricsConfig}
                  metricRequestOptions={metricRequestOptions}
                />
              ) : isLoadingMetricsURL ? (
                <Loader size="xs" />
              ) : (
                <Typography c="carbon.6">Metrics are unavailable right now.</Typography>
              )}
            </Stack>
          </Card>
        </Stack>

        <Stack w={450} justify="flex-start">
          <PropertyCard title="Properties">
            <PropertyCard.Item label="Name">{data.name || data.request?.name || 'no name'}</PropertyCard.Item>
            <PropertyCard.Item label="ID">{data.changefeed_id}</PropertyCard.Item>
            <PropertyCard.Item label="Status">
              <ChangefeedStatus status={data.status} error={data.error} />
            </PropertyCard.Item>

            <PremiumSpecificationProperty
              specId={data.changefeed_spec ?? data.request?.changefeed_spec!}
              type={data.changefeed_type}
              clusterId={data.request?.cluster_id!}
            />

            <PropertyCard.Item label="Destination">
              {getChangefeedDestinationName(data, cluster.cloudProvider)}
            </PropertyCard.Item>
            {data.created_at && (
              <PropertyCard.Item label="Created At">
                <TimeComponent time={data.created_at} />
              </PropertyCard.Item>
            )}
            {data.checkpoint_utc && (
              <PropertyCard.Item label="Checkpoint Time">
                <TimeComponent time={data.checkpoint_utc} />
              </PropertyCard.Item>
            )}
            <PropertyCard.Item label="Checkpoint TSO">{data.checkpoint_tso || '-'}</PropertyCard.Item>

            {data.changefeed_type === 'KAFKA' && (
              <KafkaPropertiesPremium
                data={data}
                sinkEndpointData={sinkEndpointData}
                cloudProvider={cluster.cloudProvider || ''}
              />
            )}

            {data.changefeed_type === 'MYSQL' && (
              <MySQLPropertiesPremium
                data={data}
                sinkEndpointData={sinkEndpointData}
                cloudProvider={cluster.cloudProvider || ''}
              />
            )}

            {data.changefeed_type === 'S3' && (
              <S3Properties
                data={data}
                clusterVersion={cluster.tidbVersion || ''}
                cloudProvider={cluster.cloudProvider}
              />
            )}
          </PropertyCard>
        </Stack>
      </Group>
    </TiDBPageShell>
  )
}

export default observer(ChangefeedDetailPremium)
