import { DownOutlined } from '@ant-design/icons'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import {
  Button,
  Card,
  Collapse,
  Descriptions,
  Divider,
  Dropdown,
  Menu,
  Tooltip
} from 'antd'
import Title from 'antd/lib/typography/Title'
import { useEffect, useState } from 'react'
import { Link, useLocation, useParams } from 'react-router-dom'

import { cloudConfigControllerGetInternalChangefeed } from 'apiClient/services/devops'
import { CloudconfigInternalChangefeed } from 'apiClient/services/devops/interface'
import { toLocal } from 'utils/time'

import ChangefeedConfig from './Config'
import PauseChangefeed from './Operation/Pause'
import RestartChangefeed from './Operation/Restart'
import ResumeChangefeed from './Operation/Resume'

const mapChangfeedClusterTypeToCDCClusterType = (
  changefeed_cluster_type: string
) => {
  switch (changefeed_cluster_type) {
    case 'CHANGEFEED':
      return 'TICDC'
    case 'CHANGEFEED_NG':
      return 'TICDC_NG'
    case 'CHANGEFEED_ESSENTIAL':
      return ''
    default:
      return ''
  }
}

const JsonConfig = ({ title, value }: { title: string; value: unknown }) => (
  <Collapse>
    <Collapse.Panel header={title} key={title}>
      <CodeBlock language="json">{JSON.stringify(value, null, 2)}</CodeBlock>
    </Collapse.Panel>
  </Collapse>
)

export default function ChangefeedDetail() {
  const { org_id, cluster_id, changefeed_id } = useParams<{
    changefeed_id: string
    org_id: string
    cluster_id: string
  }>()
  const { search } = useLocation()
  const query = new URLSearchParams(search)
  const clusterType = query.get('cluster_type') || ''
  const [changefeedDetail, setChangefeedDetail] =
    useState<CloudconfigInternalChangefeed>()
  const isCreating = changefeedDetail?.status?.toLowerCase() === 'creating'
  const kernelChangefeedId = changefeedDetail?.id
  const actionsDisabled = isCreating || !kernelChangefeedId
  const actionsDisabledReason = isCreating
    ? 'Actions are unavailable while the changefeed is being created.'
    : !kernelChangefeedId
    ? 'Actions are unavailable because the kernel changefeed ID is not ready.'
    : ''

  useEffect(() => {
    if (changefeed_id) {
      cloudConfigControllerGetInternalChangefeed(clusterType, changefeed_id)
        .then(({ data }) => {
          setChangefeedDetail(data.changefeed)
        })
        .catch((e) => {
          console.error(e)
        })
    }
  }, [changefeed_id, clusterType])

  const menu = (
    <Menu>
      <Menu.Item key="restart">
        <RestartChangefeed
          changefeed_id={kernelChangefeedId || ''}
          cluster_type={clusterType}
        ></RestartChangefeed>
      </Menu.Item>
      <Menu.Item key="pause">
        <PauseChangefeed
          changefeed_id={kernelChangefeedId || ''}
          cluster_type={clusterType}
        ></PauseChangefeed>
      </Menu.Item>
      <Menu.Item key="resume">
        <ResumeChangefeed
          changefeed_id={kernelChangefeedId || ''}
          cluster_type={clusterType}
        ></ResumeChangefeed>
      </Menu.Item>
    </Menu>
  )

  return (
    <Card
      title={<Title level={4}>{changefeedDetail?.display_name}</Title>}
      bordered={false}
      extra={
        changefeedDetail && (
          <Tooltip title={actionsDisabledReason}>
            <span>
              <Dropdown overlay={menu} disabled={actionsDisabled}>
                <Button type="primary" disabled={actionsDisabled}>
                  Actions <DownOutlined />
                </Button>
              </Dropdown>
            </span>
          </Tooltip>
        )
      }
    >
      <Descriptions title={changefeedDetail?.display_name}>
        <Descriptions.Item label="Changefeed ID">
          {changefeedDetail?.display_id}
        </Descriptions.Item>
        <Descriptions.Item label="Status">
          {changefeedDetail?.status}
        </Descriptions.Item>
        <Descriptions.Item label="Destination">
          {changefeedDetail?.downstream_type}
        </Descriptions.Item>
        <Descriptions.Item label="Create Time">
          {toLocal(changefeedDetail?.created_at)}
        </Descriptions.Item>
        <Descriptions.Item label="Checkpoint TSO">
          {changefeedDetail?.checkpoint_tso || '-'}
        </Descriptions.Item>
        <Descriptions.Item label="Checkpoint Time">
          {toLocal(changefeedDetail?.checkpoint_ts) || '-'}
        </Descriptions.Item>
        <Descriptions.Item label="RCU">
          {changefeedDetail?.rcu || '-'}
        </Descriptions.Item>
        <Descriptions.Item label="TiCDC Cluster">
          {clusterType === 'CHANGEFEED_ESSENTIAL'
            ? changefeedDetail?.arch === 'replication_worker'
              ? 'Legacy'
              : changefeedDetail?.ticdc_cluster_name || '-'
            : changefeedDetail?.ticdc_cluster && (
                <Button type="link" size="small" style={{ padding: '0 4px' }}>
                  <Link
                    target="_blank"
                    to={`/orgs/${org_id}/clusters/${cluster_id}/ticdc_clusters/${
                      changefeedDetail.ticdc_cluster.id
                    }?cluster_type=${mapChangfeedClusterTypeToCDCClusterType(
                      clusterType
                    )}`}
                  >
                    {changefeedDetail.ticdc_cluster.name}
                  </Link>
                </Button>
              )}
        </Descriptions.Item>
      </Descriptions>

      {changefeedDetail?.network_info && (
        <>
          <Divider />
          <Descriptions title="Network Info">
            <Descriptions.Item label="Network Type">
              {changefeedDetail.network_info.network_type || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Private Link Service">
              {changefeedDetail.network_info.private_link_service_name || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Kafka ID">
              {changefeedDetail.network_info.kafka_id || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Sink Endpoint ID">
              {changefeedDetail.network_info.sink_endpoint_id || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Ports">
              {changefeedDetail.network_info.ports?.join(', ') || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Advertised Pattern Group">
              {changefeedDetail.network_info.advertised_pattern_group
                ? JSON.stringify(
                    changefeedDetail.network_info.advertised_pattern_group
                  )
                : '-'}
            </Descriptions.Item>
          </Descriptions>
        </>
      )}

      {changefeedDetail?.start_position && (
        <>
          <Divider />
          <Descriptions title="Start Position">
            <Descriptions.Item label="Mode">
              {changefeedDetail.start_position.mode || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="TSO">
              {changefeedDetail.start_position.tso || '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Timestamp">
              {changefeedDetail.start_position.timestamp || '-'}
            </Descriptions.Item>
          </Descriptions>
        </>
      )}

      {changefeedDetail?.table_config && (
        <>
          <Divider />
          <JsonConfig
            title="Table Config"
            value={changefeedDetail.table_config}
          />
        </>
      )}

      {changefeedDetail?.downstream_config && (
        <>
          <Divider />
          <JsonConfig
            title="Downstream Config"
            value={changefeedDetail.downstream_config}
          />
        </>
      )}

      {changefeedDetail && !isCreating && kernelChangefeedId && (
        <>
          <Divider />
          <ChangefeedConfig
            clusterType={clusterType}
            changefeedId={kernelChangefeedId}
          />
        </>
      )}
    </Card>
  )
}
