import { DownOutlined } from '@ant-design/icons'
import {
  Button,
  Card,
  Descriptions,
  Divider,
  Dropdown,
  FormInstance,
  Menu,
  Modal
} from 'antd'
import Title from 'antd/lib/typography/Title'
import { useCallback, useEffect, useState } from 'react'
import { useLocation, useParams } from 'react-router-dom'

import {
  cloudConfigControllerCreateClusterConfigurationChange,
  cloudConfigControllerGetClusterConfiguration,
  cloudConfigControllerGetInternalTiCDCCluster,
  cloudConfigControllerPreviewClusterConfigurationChange
} from 'apiClient/services/devops'
import {
  CloudConfigControllerGetClusterConfigurationClusterType,
  CloudconfigChangeComponentReq,
  CloudconfigChangeFileReq,
  CloudconfigClusterType,
  CloudconfigConfiguration,
  CloudconfigCreateClusterConfigurationChangeReq,
  CloudconfigInternalTiCDCCluster,
  CloudconfigParameterApplyPolicy,
  CloudconfigPreviewConfigurationChangeResp
} from 'apiClient/services/devops/interface'
import ModalForm from 'components/ModalForm'
import CreateOperation from 'pages/Devops/Operations/CreateOperation'
import { toLocal } from 'utils/time'

import PreviewForm, {
  PreviewFormType,
  buildPreviewExecutionWindow
} from '../../Configs/Forms/PreviewForm'
import ImageTagForm, { ImageTagType } from '../../Operations/Image/ImageTagForm'
import UpgradeOperation from '../../Operations/Upgrade'
import VersionForm, {
  VersionFormType
} from '../../Operations/Upgrade/VersionForm'

import TiCDCConfig from './Config'
import RestartCDC from './Operation/Restart'
import ShutdownCDC from './Operation/ShutDown'

export default function TiCDCClusterDetail() {
  const { ticdc_cluster_id } = useParams<{
    ticdc_cluster_id: string
  }>()
  const { search } = useLocation()
  const query = new URLSearchParams(search)
  const clusterType = query.get('cluster_type') || ''
  const [cdcDetail, setCDCDetail] = useState<CloudconfigInternalTiCDCCluster>()
  const [curConfig, setCurConfig] = useState<CloudconfigConfiguration>()
  const [reload, setReload] = useState(false)

  async function fetch() {
    try {
      const data = (
        await cloudConfigControllerGetInternalTiCDCCluster(
          clusterType,
          ticdc_cluster_id
        )
      ).data
      const conf = (
        await cloudConfigControllerGetClusterConfiguration({
          cluster_type:
            clusterType === 'TICDC_NG'
              ? CloudConfigControllerGetClusterConfigurationClusterType.TICDC_NG
              : CloudConfigControllerGetClusterConfigurationClusterType.TICDC,
          cluster_id: ticdc_cluster_id
        })
      ).data
      setCDCDetail(data.ticdc_cluster)
      setCurConfig(conf.configuration)
    } catch (e) {
      console.error(e)
    }
  }

  useEffect(() => {
    if (ticdc_cluster_id) {
      fetch()
    }
  }, [reload, ticdc_cluster_id])

  const [versionForm, setVersionForm] = useState(false)

  const [targetVersion, setTargetVersion] = useState<string>()

  const renderVersionParamFields = useCallback(
    (form: FormInstance) => {
      form.setFieldsValue({
        curVersion: curConfig?.version,
        version: curConfig?.version
      })
      return (
        <VersionForm
          component={'ticdc'}
          current={curConfig?.version}
          cluster_type={clusterType}
        />
      )
    },
    [curConfig, reload]
  )

  const handleVersion = useCallback(
    async (payload: VersionFormType) => {
      setTargetVersion(payload.version)
      setVersionForm(false)
      let files: CloudconfigChangeFileReq[] = []
      // Object.keys(curConfig?.files || {}).map((key) => {
      //     files.push({ previous_text: curConfig?.files![key]!.text, ...curConfig?.files![key]! })
      // })
      let components: CloudconfigChangeComponentReq[] = []
      // Object.keys(curConfig?.components || {}).map((key) => {
      //     components.push({ component: key, overwrite_image_tag: { to_image_tag: curConfig?.components![key]!.effective_image_tag } })
      // })
      const previewResp = (
        await cloudConfigControllerPreviewClusterConfigurationChange({
          change_type: clusterType === 'TICDC_NG' ? 'ticdc_ng' : 'ticdc',
          cluster_type: clusterType as CloudconfigClusterType,
          cluster_id: ticdc_cluster_id,
          files: files,
          components: components,
          version: { to_version: payload.version }
        })
      ).data
      setPreview(previewResp)
      setModalCommit(true)
    },
    [targetVersion]
  )

  const handleCancelVersion = useCallback(() => {
    setVersionForm(false)
  }, [])

  const [imageForm, setImageForm] = useState(false)

  const renderImageParamFields = useCallback(
    (form: FormInstance) => {
      form.setFieldsValue({
        name: 'ticdc',
        image_tag: curConfig?.components!['ticdc'].effective_image_tag
      })
      return (
        <ImageTagForm
          name="ticdc"
          image_tag={curConfig?.components!['ticdc'].effective_image_tag}
        />
      )
    },
    [curConfig, reload]
  )

  const handleImage = useCallback(
    async (payload: ImageTagType) => {
      setImageForm(false)
      //   setTargetVersion(curConfig?.version)
      let files: CloudconfigChangeFileReq[] = []
      // Object.keys(curConfig?.files || {}).map((key) => {
      //     files.push({ previous_text: curConfig?.files![key]!.text, ...curConfig?.files![key]! })
      // })
      let components: CloudconfigChangeComponentReq[] = [
        {
          component: 'ticdc',
          overwrite_image_tag: { to_image_tag: payload.image_tag }
        }
      ]
      const previewResp = (
        await cloudConfigControllerPreviewClusterConfigurationChange({
          change_type: clusterType === 'TICDC_NG' ? 'ticdc_ng' : 'ticdc',
          cluster_type: clusterType as CloudconfigClusterType,
          cluster_id: ticdc_cluster_id,
          files: files,
          components: components
          //   version: { to_version: curConfig?.version }
        })
      ).data
      setPreview(previewResp)
      setModalCommit(true)
    },
    [curConfig, reload]
  )

  const handleCancelImage = useCallback(() => {
    setImageForm(false)
  }, [])

  const [modalCommit, setModalCommit] = useState(false)
  const [preview, setPreview] =
    useState<CloudconfigPreviewConfigurationChangeResp>()
  const renderPreviewParamFields = useCallback(
    (form: FormInstance) => {
      return (
        <PreviewForm
          preview={preview}
          type={'ticdc'}
          form={form}
          clusterId={ticdc_cluster_id}
        />
      )
    },
    [modalCommit, ticdc_cluster_id]
  )

  const handleApply = useCallback(
    async (payload: PreviewFormType) => {
      let req: CloudconfigCreateClusterConfigurationChangeReq = {
        apply_policy: CloudconfigParameterApplyPolicy.None,
        change_type: clusterType === 'TICDC_NG' ? 'ticdc_ng' : 'ticdc',
        cluster_id: ticdc_cluster_id,
        cluster_type: clusterType as CloudconfigClusterType,
        execution_window: buildPreviewExecutionWindow(payload),
        reason: payload.reason
      }
      if (preview?.change?.scope?.version) {
        req.version = { to_version: preview?.change?.scope?.version.to }
      }
      if (preview?.change?.scope?.components) {
        req.components = []
        for (const component of preview?.change?.scope?.components) {
          if (component.modified_image_tag) {
            req.components.push({
              component: component.component,
              overwrite_image_tag: {
                to_image_tag: component.modified_image_tag?.to
              }
            })
          }
        }
      }
      try {
        let resp = (
          await cloudConfigControllerCreateClusterConfigurationChange(req)
        ).data.change_id
        Modal.success({
          title: 'Info',
          content: (
            <div>
              <p>
                This config change has been created.
                <br></br>
                However, you should go to to the <b>Detail</b> Page to check the
                Approval information and Apply it. Click <b>OK</b> will redirect
                you to that page.
              </p>
            </div>
          ),
          onOk() {
            window.open(`/confighistories/${resp}`, '_blank')
          }
        })
        setModalCommit(false)
      } catch (error) {
        Modal.error({
          title: error.response.data.errcode,
          content: error.response.data.errmsg
        })
      } finally {
      }
    },
    [targetVersion, preview]
  )

  const handleCancelPreview = useCallback(() => {
    setModalCommit(false)
  }, [])

  const menu = (
    <Menu>
      {clusterType === 'TICDC' ? (
        <Menu.Item>
          <UpgradeOperation
            changeType={'ticdc'}
            clusterType={CloudconfigClusterType.TICDC}
            cluster_id={ticdc_cluster_id}
          ></UpgradeOperation>
        </Menu.Item>
      ) : (
        <></>
      )}

      <Menu.Item></Menu.Item>
      <Menu.Item>
        <a
          onClick={() => {
            setImageForm(true)
          }}
        >
          Modify the Image
        </a>
      </Menu.Item>
      <Menu.Item>
        <RestartCDC
          ticdc_cluster_id={ticdc_cluster_id}
          cluster_type={clusterType}
        ></RestartCDC>
      </Menu.Item>
      {clusterType === 'TICDC' ? (
        <Menu.Item>
          <ShutdownCDC
            ticdc_cluster_id={ticdc_cluster_id}
            cluster_type={clusterType}
          ></ShutdownCDC>
        </Menu.Item>
      ) : (
        <></>
      )}
    </Menu>
  )

  return (
    <>
      <Card
        title={<Title level={4}>{cdcDetail?.name}</Title>}
        bordered={false}
        extra={
          <Dropdown overlay={menu}>
            <Button type="primary">
              Actions <DownOutlined />
            </Button>
          </Dropdown>
        }
      >
        <Descriptions title="Basic Information">
          <Descriptions.Item label="ID">{cdcDetail?.id}</Descriptions.Item>
          <Descriptions.Item label="Status">
            {cdcDetail?.status}
          </Descriptions.Item>
          <Descriptions.Item label="Version">
            {cdcDetail?.version}
          </Descriptions.Item>
          <Descriptions.Item label="Create Time">
            {toLocal(cdcDetail?.created_at)}
          </Descriptions.Item>
          <Descriptions.Item label="Deploy Type">
            {cdcDetail?.deploy_type}
          </Descriptions.Item>
          <Descriptions.Item label="Specification">
            {cdcDetail?.specification_code}
          </Descriptions.Item>
          <Descriptions.Item label="Region">
            {cdcDetail?.region}
          </Descriptions.Item>
          <Descriptions.Item label="Provider">
            {cdcDetail?.provider_type}
          </Descriptions.Item>
          <Descriptions.Item label="Control Plane Arch">
            {cdcDetail?.control_plane_arch}
          </Descriptions.Item>
          <Descriptions.Item label="Operator Version">
            {cdcDetail?.operator_version}
          </Descriptions.Item>
        </Descriptions>

        <Divider></Divider>

        <TiCDCConfig
          availableFiles={Object.keys(curConfig?.files || {})}
          clusterType={clusterType}
        ></TiCDCConfig>
      </Card>

      <ModalForm<VersionFormType>
        title={'Choose the target version'}
        visible={!!versionForm}
        onCancel={handleCancelVersion}
        width={1000}
        name="version"
        getFields={renderVersionParamFields}
        onSubmit={handleVersion}
        destoryOnClose={true}
        okText="Next"
      />
      <ModalForm<ImageTagType>
        title={'Modify the image'}
        visible={!!imageForm}
        onCancel={handleCancelImage}
        width={1000}
        name="image"
        getFields={renderImageParamFields}
        onSubmit={handleImage}
        destoryOnClose={true}
        okText="Next"
      />
      <ModalForm<PreviewFormType>
        visible={!!modalCommit}
        name="preview"
        title={'Preview of Change'}
        getFields={renderPreviewParamFields}
        onSubmit={handleApply}
        onCancel={handleCancelPreview}
        width={1000}
        okText="Commit"
      />
    </>
  )
}
