import { Button, FormInstance, Modal } from 'antd'
import { useCallback, useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'

import {
  cloudConfigControllerCreateClusterConfigurationChange,
  cloudConfigControllerCreateTenantInitConfigurationChange,
  cloudConfigControllerGetClusterConfiguration,
  cloudConfigControllerGetTemplate,
  cloudConfigControllerGetTenantInitConfiguration,
  cloudConfigControllerPreviewClusterConfigurationChange,
  cloudConfigControllerPreviewTenantInitConfigurationChange
} from 'apiClient/services/devops'
import {
  CloudconfigClusterType,
  CloudconfigChangeFileReq,
  CloudConfigControllerGetTenantInitConfigurationClusterType,
  CloudconfigParameterApplyPolicy,
  CloudconfigPreviewConfigurationChangeResp
} from 'apiClient/services/devops/interface'
import ModalForm from 'components/ModalForm'
import PreviewForm, {
  PreviewFormType,
  buildPreviewExecutionWindow
} from 'pages/Tenants/ClusterDetail/Configs/Forms/PreviewForm'

import TenantInitDMVersionForm from './TenantInitDMVersionForm'
import TenantInitVersionForm, {
  TenantInitVersionFormType
} from './TenantInitVersionForm'

export default function TenantInitVersion({
  change_type
}: {
  change_type: string
}) {
  const { org_id } = useParams<{
    org_id: string
  }>()

  useEffect(() => {
    fetch()
  }, [])

  async function fetch() {
    try {
      const resp = (
        await cloudConfigControllerGetTenantInitConfiguration({
          cluster_type:
            CloudConfigControllerGetTenantInitConfigurationClusterType.DEDICATED_TIDB,
          tenant_id: org_id
        })
      ).data
      if (change_type == 'tidb' || change_type == 'fulltidb') {
        setCurrentVersion(resp.default_version?.tidb)
      } else if (change_type == 'data-migration') {
        setCurrentVersion(resp.default_version?.['data-migration'])
      }
    } catch (error) {
      Modal.error({
        title: error.response.data.errcode,
        content: error.response.data.errmsg
      })
    }
  }

  const [currentVersion, setCurrentVersion] = useState<string>()
  const [versionForm, setVersionForm] = useState(false)
  const [modalCommit, setModalCommit] = useState(false)
  const [targetVersion, setTargetVersion] = useState<string>()
  const [preview, setPreview] =
    useState<CloudconfigPreviewConfigurationChangeResp>()

  const renderVersiontParamFields = useCallback(
    (form: FormInstance) => {
      form.setFieldsValue({ curVersion: currentVersion })
      if (change_type == 'tidb' || change_type == 'fulltidb') {
        return <TenantInitVersionForm current={currentVersion} />
      } else if (change_type == 'data-migration') {
        return <TenantInitDMVersionForm current={currentVersion} />
      }
    },
    [currentVersion]
  )

  const renderPreviewParamFields = useCallback(
    (form: FormInstance) => {
      return <PreviewForm preview={preview} type={'tenant'} form={form} />
    },
    [modalCommit]
  )

  const [configChangeFiles, setConfigChangeFiles] = useState<
    CloudconfigChangeFileReq[]
  >([])

  const handleVersion = useCallback(
    async (payload: TenantInitVersionFormType) => {
      setTargetVersion(payload.version)
      setVersionForm(false)

      const newConfigChangeFiles: CloudconfigChangeFileReq[] = []
      if (payload.custom_template > 0) {
        const customTemplate = (
          await cloudConfigControllerGetTemplate(
            payload.custom_template.toString(),
            {
              cluster_type: CloudconfigClusterType.DEDICATED_TIDB
            }
          )
        ).data

        if (customTemplate.template?.custom_template_info?.data) {
          for (const t of Object.values(
            customTemplate.template.custom_template_info.data
          )) {
            newConfigChangeFiles.push({
              filename: t.config_type,
              config_type: t.config_type,
              custom_parameters: t.parameters ? Object.values(t.parameters) : []
            })
          }
          setConfigChangeFiles(newConfigChangeFiles)
        }
      }
      const previewResp = (
        await cloudConfigControllerPreviewTenantInitConfigurationChange({
          change_type: change_type,
          cluster_type: CloudconfigClusterType.DEDICATED_TIDB,
          tenant_id: org_id,
          version: { to_version: payload.version },
          files: newConfigChangeFiles
        })
      ).data
      setPreview(previewResp)
      setModalCommit(true)
    },
    []
  )

  const handleApply = useCallback(
    async (payload: PreviewFormType) => {
      try {
        let resp = (
          await cloudConfigControllerCreateTenantInitConfigurationChange({
            change_type: change_type,
            cluster_type: CloudconfigClusterType.DEDICATED_TIDB,
            tenant_id: org_id,
            version: { to_version: targetVersion },
            files: configChangeFiles,
            execution_window: buildPreviewExecutionWindow(payload),
            apply_policy:
              payload.apply_policy ||
              CloudconfigParameterApplyPolicy.RollingRestart
          })
        ).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, configChangeFiles]
  )

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

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

  if (change_type == 'tidb' || change_type == 'fulltidb') {
    return (
      <div>
        <a
          onClick={() => {
            setVersionForm(true)
          }}
        >
          Modify Default Version/Config
        </a>
        <ModalForm<TenantInitVersionFormType>
          title={'Choose the target default version'}
          visible={!!versionForm}
          onCancel={handleCancelVersion}
          width={1000}
          name="version"
          getFields={renderVersiontParamFields}
          onSubmit={handleVersion}
          destoryOnClose={true}
          okText="Next"
        />
        <ModalForm<PreviewFormType>
          visible={!!modalCommit}
          name="preview"
          title={'Preview of Change'}
          getFields={renderPreviewParamFields}
          onSubmit={handleApply}
          onCancel={handleCancelPreview}
          width={1000}
          okText="Commit"
        />
      </div>
    )
  }
  return (
    <div>
      <a
        onClick={() => {
          setVersionForm(true)
        }}
      >
        Modify Default DM Version
      </a>
      <ModalForm<TenantInitVersionFormType>
        title={'Choose the target default version'}
        visible={!!versionForm}
        onCancel={handleCancelVersion}
        width={1000}
        name="version"
        getFields={renderVersiontParamFields}
        onSubmit={handleVersion}
        destoryOnClose={true}
        okText="Next"
      />
      <ModalForm<PreviewFormType>
        visible={!!modalCommit}
        name="preview"
        title={'Preview of Change'}
        getFields={renderPreviewParamFields}
        onSubmit={handleApply}
        onCancel={handleCancelPreview}
        width={1000}
        okText="Commit"
      />
    </div>
  )
}
