import MarkdownPreview from '@uiw/react-markdown-preview'
import {
  Button,
  Checkbox,
  DatePicker,
  Form,
  FormInstance,
  Input,
  Modal,
  Radio,
  Typography,
  Select
} from 'antd'
import TextArea from 'antd/lib/input/TextArea'
import moment from 'moment'
import React, { useEffect, useMemo, useState } from 'react'
import ReactMarkdown from 'react-markdown'

import {
  getClusterComponents,
  getDMNamespace,
  operationControllerGetOperation,
  operationControllerListOperationCategories,
  operationControllerListOperations
} from 'apiClient/services/devops'
import {
  ClusterComponentInfoStorages,
  ClusterGetClusterResp,
  OperationActionStartPolicy,
  OperationOperation,
  OperationOperationTarget,
  OperationControllerGetOperationParams
} from 'apiClient/services/devops/interface'
import {
  FormOption,
  FormSection,
  FormSectionGroup
} from 'components/FormSection'
import { ClusterOpsMaintenanceWindowCheckAlert } from 'pages/Devops/Maintenance/helper'

import { SortByWeight } from '../utils'

export const COMPOSITE_AZ_OPERATION_NAMES = new Set([
  'OfflineAzWithZonalShiftForCluster',
  'RecoverAzWithStopZonalShiftForCluster'
])

const AZ_ZONAL_OPERATION_NAMES = new Set([
  ...COMPOSITE_AZ_OPERATION_NAMES,
  'UpdateZonalShiftForCluster'
])

type TidbGroupOption = { label: string; value: string }

const formOptionItemStyle = {
  marginBottom: 0
}

const actionCreateGridStyle: React.CSSProperties = {
  display: 'grid',
  gridTemplateColumns: '96px minmax(240px, 1fr) 160px minmax(220px, 1fr)',
  columnGap: 16,
  alignItems: 'start'
}

const actionGridHeaderStyle: React.CSSProperties = {
  ...actionCreateGridStyle,
  marginBottom: 16,
  fontWeight: 600
}

const actionGridRowStyle: React.CSSProperties = {
  ...actionCreateGridStyle,
  marginBottom: 8
}

const actionNameStyle: React.CSSProperties = {
  minHeight: 32,
  lineHeight: '32px',
  color: 'black',
  overflowWrap: 'anywhere',
  whiteSpace: 'normal'
}

const renderFormOption = (
  title: string,
  children: React.ReactNode,
  description?: string,
  required?: boolean
) => (
  <FormOption
    key={title}
    title={title}
    description={description}
    required={required}
  >
    {children}
  </FormOption>
)

const RCU_QUOTA_DEFAULT_KEYS = [
  'instanceMaxRCU',
  'totalMaxRCU',
  'burstyRatio',
  'idleResourcePoolTtlInHours',
  'vcpusLimitPerResourcePool',
  'minimalRcuBaseline',
  'minimalRcuCoefficient',
  'scaleDownCooldownMinutes'
]

type RcuQuotaDefaultsByPlan = Record<string, Record<string, string>>

const { RangePicker } = DatePicker

export type CreateInstanceFormType = {
  actions: {
    choose: boolean
    name: string
    start_policy: string
    schedule_time?: moment.Moment
  }[]
  description: string
  reason: string
  operation: string
  params: { [key: string]: any }
  type: OperationOperationTarget
  is_draft: boolean
  execution_window_enabled?: boolean
  execution_window_range?: [moment.Moment, moment.Moment]
}

const StorageInfo: React.FC<
  React.PropsWithChildren<{
    title: string
    storage: ClusterComponentInfoStorages
  }>
> = ({ title, storage }) => {
  if (!storage) {
    return <></>
  }
  return (
    <div>
      <h2>{title}</h2>
      <ul>
        <li>
          <h3>Data Disk</h3>
          <div>
            <div>
              <b>volume_iops</b>: {storage?.data.iops}
            </div>
            <div>
              <b>volume_size (GiB)</b>: {storage?.data.size_gi}
            </div>
            <div>
              <b>volume_throughput (MiB/s)</b>: {storage?.data.throughput_mibps}
            </div>
            <div>
              <b>volume_type</b>: {storage?.data.volume_type}
            </div>
            <div>
              <b>volume_additional_iops</b>: {storage?.data.additional_iops}
            </div>
          </div>
        </li>
        {storage.raftlog && (
          <li style={{ marginTop: 10 }}>
            <h3>Raft-Log Disk</h3>
            <div>
              <div>
                <b>volume_iops</b>: {storage?.raftlog.iops}
              </div>
              <div>
                <b>volume_size (GiB)</b>: {storage?.raftlog.size_gi}
              </div>
              <div>
                <b>volume_throughput (MiB/s)</b>:{' '}
                {storage?.raftlog.throughput_mibps}
              </div>
              <div>
                <b>volume_type</b>: {storage?.raftlog.volume_type}
              </div>
              <div>
                <b>volume_additional_iops</b>:{' '}
                {storage?.raftlog.additional_iops}
              </div>
            </div>
          </li>
        )}
      </ul>
    </div>
  )
}

export function AppendCategoryFromDeployType(
  ori: string[],
  cluster_deploy_type?: string
): string[] {
  if (cluster_deploy_type === 'DEPLOY_TYPE_DEDICATED') {
    return ori.concat(['dedicated'])
  }
  if (cluster_deploy_type === 'DEPLOY_TYPE_SERVERLESS') {
    return ori.concat(['serverless'])
  }
  if (cluster_deploy_type === 'DEPLOY_TYPE_NEXTGEN') {
    return ori.concat(['premium'])
  }
  if (cluster_deploy_type === 'DEPLOY_TYPE_RESOURCE_POOL') {
    return ori.concat(['resource-pool'])
  }

  return ori
}

const CreateInstanceForm = ({
  form,
  target_type,
  target_id,
  init_categories,
  op,
  json,
  cluster
}: {
  form: FormInstance
  target_type?: OperationOperationTarget
  target_id?: string
  init_categories?: string[]
  op: string
  json?: string
  cluster?: ClusterGetClusterResp
}) => {
  const [categories, setCategories] =
    useState<{ label: string; value: string }[]>()
  const [operations, setOperations] = useState<OperationOperation[]>()
  const [operation, setOperation] = useState<OperationOperation>()
  const [refresh, setRefresh] = useState(false)

  const [namespace, setNamespace] = useState<string>('')
  const [podNames, setPodNames] = useState<string[]>([''])
  const [tidbGroupOptions, setTidbGroupOptions] = useState<TidbGroupOption[]>(
    []
  )

  const [showCurrent, setShowCurrent] = useState(false)
  const [tikvStorage, setTikvStorage] = useState<ClusterComponentInfoStorages>()
  const [tiflashStorage, setTiflashStorage] =
    useState<ClusterComponentInfoStorages>()
  const [quotaDefaultsByPlan, setQuotaDefaultsByPlan] =
    useState<RcuQuotaDefaultsByPlan>({})
  const watchedType = Form.useWatch('type', form) as
    | OperationOperationTarget
    | undefined
  const watchedParamsClusterId = Form.useWatch(['params', 'cluster_id'], form)
  const watchedActions = Form.useWatch('actions', form) as
    | CreateInstanceFormType['actions']
    | undefined
  const executionWindowEnabled = Form.useWatch('execution_window_enabled', form)
  const executionWindowRange = Form.useWatch(
    'execution_window_range',
    form
  ) as CreateInstanceFormType['execution_window_range']
  const watchedServicePlan = Form.useWatch(['params', 'service_plan'], form) as
    | string
    | undefined
  const isClusterTarget = watchedType === OperationOperationTarget.cluster
  const clusterId = watchedParamsClusterId
    ? String(watchedParamsClusterId)
    : undefined
  const actionExecuteTimes = useMemo(() => {
    return watchedActions
      ?.filter((action) => {
        return (
          action.choose !== false &&
          action.start_policy === OperationActionStartPolicy.schedule &&
          action.schedule_time
        )
      })
      .map((action) => action.schedule_time!.unix())
  }, [watchedActions])
  const executionWindowExecuteTimes = useMemo(() => {
    if (
      !executionWindowEnabled ||
      !executionWindowRange?.[0] ||
      !executionWindowRange?.[1] ||
      !executionWindowRange[0].isBefore(executionWindowRange[1])
    ) {
      return undefined
    }

    return [executionWindowRange[0].unix(), executionWindowRange[1].unix()]
  }, [executionWindowEnabled, executionWindowRange])
  const executeTimes = executionWindowExecuteTimes || actionExecuteTimes

  // availability_zone is a free-text string param (e.g. us-east-1a).
  // Do not call /api/v1/admin/providers/*/regions — it requires admin permission.
  const loadGroupOptions = async (
    operationName: string,
    clusterIdForLoad?: string
  ) => {
    if (!AZ_ZONAL_OPERATION_NAMES.has(operationName)) {
      setTidbGroupOptions([])
      return
    }

    const cid = clusterIdForLoad || target_id
    if (cid) {
      try {
        const components = (await getClusterComponents(cid)).data
        const seen = new Set<string>()
        const options: TidbGroupOption[] = []
        for (const comp of components.tidb || []) {
          const id = comp.tidb_group_id
          if (!id || seen.has(id)) continue
          seen.add(id)
          const name = comp.tidb_group_display_name || id
          options.push({
            label: `${name} (${id})`,
            value: id
          })
        }
        setTidbGroupOptions(options)
      } catch {
        setTidbGroupOptions([])
      }
    } else {
      setTidbGroupOptions([])
    }
  }

  useEffect(() => {
    form.setFieldsValue({ categories: init_categories })

    const originCluster = form.getFieldValue(['params']) || {}
    if (json) {
      originCluster.cluster_components_to_scale = json
    }
    form.setFieldsValue({ params: originCluster })

    fetch()
  }, [])

  // logical_region only applies to Essential_V2 resource pools; clear any stale
  // value whenever the selected service plan is not Essential_V2.
  useEffect(() => {
    if (op === 'CreateResourcePool' && watchedServicePlan !== 'Essential_V2') {
      const origin = form.getFieldValue(['params']) || {}
      if (origin.logical_region !== undefined) {
        delete origin.logical_region
        form.setFieldsValue({ params: origin })
      }
    }
  }, [watchedServicePlan, op, form])

  async function fetch() {
    try {
      const categoryOps = (await operationControllerListOperationCategories())
        .data.categories
      setCategories(
        categoryOps
          ? categoryOps.map((val) => {
              return { label: val, value: val }
            })
          : []
      )
      const data = (
        await operationControllerListOperations({
          page: 1,
          per_page: 20,
          categories: form.getFieldValue(['categories'])
        })
      ).data.items
      setOperations(
        data
          ?.filter((val) => {
            return val.internal !== true
          })
          .sort((o1, o2) => {
            return o1.name!.localeCompare(o2.name!)
          }) || []
      )
      var operation
      if (op === 'impersonate') {
        operation = 'ImpersonateTenant'
      } else if (op === 'pause') {
        operation = 'PauseCluster'
      } else if (op === 'scale') {
        operation = 'ScaleCluster'
      } else if (op === 'non-standard operation') {
        operation = 'NonStandardOperation'
      } else if (op !== 'other Operations' && op.length > 0) {
        operation = op
      }
      form.setFieldsValue({ operation: operation })
      if (operation) {
        whenChangeOperation(operation)
      } else {
      }
    } catch (e) {
      console.error(e)
    }
  }

  const applyQuotaDefaultsByServicePlan = (
    defaultsByPlan: RcuQuotaDefaultsByPlan,
    plan: string
  ) => {
    const defaults = defaultsByPlan[plan]
    if (!defaults) {
      return
    }

    const origin = form.getFieldValue(['params']) || {}
    const nextParams = { ...origin, service_plan: plan }
    RCU_QUOTA_DEFAULT_KEYS.forEach((key) => {
      if (defaults[key] !== undefined) {
        nextParams[key] = defaults[key]
      }
    })
    form.setFieldsValue({ params: nextParams })
  }

  const whenChangeOperation = async (val: string) => {
    var param: OperationControllerGetOperationParams = {
      inject_param: true,
      target_type: target_type,
      target_id: target_id
    }
    const opRes = (await operationControllerGetOperation(val, param)).data
      .operation
    setOperation(opRes)
    setQuotaDefaultsByPlan({})
    form.setFieldsValue({ description: opRes?.description })
    form.setFieldsValue({ type: opRes?.target })

    if (opRes?.name === 'ModifyTenantPremiumQuota') {
      try {
        const runtimeData = (opRes as any)?.runtime_data
        const byServicePlanRaw = runtimeData?.rcu_quota_defaults_by_service_plan
        if (byServicePlanRaw) {
          const defaultsByPlan: RcuQuotaDefaultsByPlan =
            JSON.parse(byServicePlanRaw)
          setQuotaDefaultsByPlan(defaultsByPlan)
          const selectedPlan =
            form.getFieldValue(['params', 'service_plan']) ||
            opRes?.params?.service_plan?.default ||
            'Premium'
          applyQuotaDefaultsByServicePlan(defaultsByPlan, selectedPlan)
        }
      } catch (e) {
        console.error('failed to parse rcu quota defaults by service plan', e)
      }
    }

    const defaultChooseAllOptional = COMPOSITE_AZ_OPERATION_NAMES.has(
      opRes?.name || ''
    )
    const actions = opRes?.actions?.map((val) => {
      const choose = defaultChooseAllOptional || val.optional !== true
      return val.prefer_start_policy
        ? {
            choose,
            name: val.name,
            start_policy: val.prefer_start_policy,
            schedule_time:
              val.prefer_start_policy === OperationActionStartPolicy.schedule
                ? moment().add(val.prefer_schedule_hour, 'hours')
                : undefined
          }
        : { choose, name: val.name }
    })
    form.setFieldsValue({ actions: actions })
    setRefresh((pre) => !pre)
    if (opRes?.name! == 'RestartDMPod') {
      const namespace = (await getDMNamespace(target_id!)).data // target_id is cluster_id here
      setNamespace(namespace.namespace!)
      let names = namespace.pod_names
      names?.push('ALL')
      setPodNames(names!)
    }
    if (opRes?.name! == 'ModifyClusterVolume') {
      const components = (await getClusterComponents(target_id!)).data // target_id is cluster_id here
      if (!components) {
        return
      }
      if (components.tikv && components.tikv.length! > 0) {
        setTikvStorage(components.tikv[0].storages)
      }
      if (components.tiflash && components.tiflash.length! > 0) {
        setTiflashStorage(components.tiflash[0].storages)
      }
    }
    if (opRes?.name) {
      await loadGroupOptions(opRes.name, target_id)
    }
  }

  const handleChangeOperation = (val: string) => {
    if (operations) {
      whenChangeOperation(val)
    }
  }

  const handleChangeOperationCategories = (categories: string[]) => {
    fetch()
    form.setFieldsValue({ operation: undefined })
  }

  const showCurrentSettings = () => {
    setShowCurrent(true)
  }

  const handleCurrentSettingsCancel = () => {
    setShowCurrent(false)
  }

  const handleCurrentSettingsOk = () => {
    setShowCurrent(false)
  }

  return (
    <>
      <Modal
        title={'Current Settings'}
        open={showCurrent}
        onCancel={handleCurrentSettingsCancel}
        width={1000}
        destroyOnClose={true}
        okText={'Close'}
        onOk={handleCurrentSettingsOk}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'left',
            gap: '20%'
          }}
        >
          {tikvStorage && <StorageInfo title="TiKV" storage={tikvStorage} />}
          {tiflashStorage && (
            <StorageInfo title="TiFlash" storage={tiflashStorage} />
          )}
        </div>
      </Modal>

      <FormSectionGroup show_outline>
        <FormSection title="Choose Operation">
          <FormOption title="Categories">
            <Form.Item name="categories" style={formOptionItemStyle}>
              <Select
                options={categories?.sort((a, b) =>
                  a.label.localeCompare(b.label)
                )}
                onChange={handleChangeOperationCategories}
                showSearch
                disabled={op !== 'other Operations'}
                bordered={op === 'other Operations'}
              ></Select>
            </Form.Item>
          </FormOption>
          <FormOption title="Operation" required>
            <Form.Item
              name="operation"
              rules={[{ required: true }]}
              style={formOptionItemStyle}
            >
              <Select
                showSearch
                options={operations
                  ?.map((val) => {
                    return { label: val.alias || '', value: val.name || '' }
                  })
                  .sort((a, b) => {
                    return a.label.localeCompare(b.label)
                  })}
                onChange={handleChangeOperation}
                disabled={op !== 'other Operations'}
                bordered={op === 'other Operations'}
              ></Select>
            </Form.Item>
          </FormOption>
          <FormOption title="Type">
            <Form.Item name="type" style={formOptionItemStyle}>
              <Input disabled={true} style={{ color: 'black' }}></Input>
            </Form.Item>
          </FormOption>
          <FormOption title="Description">
            <Form.Item name="description" style={formOptionItemStyle}>
              <MarkdownPreview
                source={operation?.description || ``}
                style={{ fontSize: 15 }}
                wrapperElement={{
                  'data-color-mode': 'light'
                }}
              />
            </Form.Item>
          </FormOption>
        </FormSection>

        <FormSection title="Parameters">
          {operation?.name === 'ModifyClusterVolume' ? (
            <Form.Item style={{ marginTop: '20px', textAlign: 'left' }}>
              <Button type="primary" onClick={showCurrentSettings}>
                Show Current Settings
              </Button>
            </Form.Item>
          ) : (
            <></>
          )}
          {operation?.params ? (
            Object.keys(SortByWeight(operation?.params)).map((v) => {
              const paramDescription = operation.params?.[v].desc
              const paramRequired = operation.params?.[v].optional !== true

              // logical_region only applies to Essential_V2 resource pools.
              if (
                operation?.name === 'CreateResourcePool' &&
                v === 'logical_region' &&
                watchedServicePlan !== 'Essential_V2'
              ) {
                return null
              }

              if (operation?.params && operation.params[v].const) {
                const origin = form.getFieldValue(['params']) || {}
                origin[v] = operation.params[v].const
                form.setFieldsValue({ params: origin })
                return renderFormOption(
                  v,
                  <Form.Item
                    name={['params', v]}
                    rules={[
                      operation?.params &&
                      operation?.params[v].optional === true
                        ? {}
                        : { required: true, message: 'this param is required' }
                    ]}
                    style={formOptionItemStyle}
                  >
                    <Input disabled={true} style={{ color: 'black' }}></Input>
                  </Form.Item>,
                  paramDescription,
                  paramRequired
                )
              } else if (operation?.params && operation.params[v].enum) {
                let enumOptions = [...(operation.params[v].enum || [])]
                if (
                  operation.name === 'CreateResourcePool' &&
                  v === 'service_plan' &&
                  target_type === OperationOperationTarget.tenant &&
                  target_id === '0'
                ) {
                  ;['Essential_V2', 'Premium_Reserved'].forEach((plan) => {
                    if (!enumOptions.includes(plan)) {
                      enumOptions.push(plan)
                    }
                  })
                }
                return renderFormOption(
                  v,
                  <Form.Item
                    name={['params', v]}
                    rules={[
                      operation?.params &&
                      operation?.params[v].optional === true
                        ? {}
                        : { required: true, message: 'this param is required' }
                    ]}
                    initialValue={
                      (operation.params && operation.params[v].default) || null
                    }
                    style={formOptionItemStyle}
                  >
                    <Select
                      options={enumOptions.map((m) => {
                        return { label: m, value: m }
                      })}
                      onChange={(selectedPlan) => {
                        if (
                          operation?.name === 'ModifyTenantPremiumQuota' &&
                          v === 'service_plan'
                        ) {
                          applyQuotaDefaultsByServicePlan(
                            quotaDefaultsByPlan,
                            selectedPlan
                          )
                        }
                      }}
                    ></Select>
                  </Form.Item>,
                  paramDescription,
                  paramRequired
                )
              } else if (operation?.params && operation.params[v].multi_enum) {
                return renderFormOption(
                  v,
                  <Form.Item
                    name={['params', v]}
                    rules={[
                      operation?.params &&
                      operation?.params[v].optional === true
                        ? {}
                        : { required: true, message: 'this param is required' }
                    ]}
                    style={formOptionItemStyle}
                  >
                    <Select
                      mode="multiple"
                      options={operation.params[v].multi_enum?.map((m) => {
                        return { label: m, value: m }
                      })}
                    ></Select>
                  </Form.Item>,
                  paramDescription,
                  paramRequired
                )
              } else {
                if (v === 'cluster_components_to_scale') {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={[
                        operation?.params &&
                        operation?.params[v].optional === true
                          ? {}
                          : {
                              required: true,
                              message: 'this param is required'
                            }
                      ]}
                      style={formOptionItemStyle}
                    >
                      <TextArea
                        rows={5}
                        disabled={true}
                        bordered={false}
                        style={{ color: 'black' }}
                      ></TextArea>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (v === 'advance_options') {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={[
                        operation?.params &&
                        operation?.params[v].optional === true
                          ? {}
                          : {
                              required: true,
                              message: 'this param is required'
                            }
                      ]}
                      style={formOptionItemStyle}
                    >
                      <TextArea
                        rows={10}
                        disabled={false}
                        defaultValue={
                          'basic:\n' +
                          '  mAccountRole: arn:aws:iam::385595570414:role/auto-deploy-cli\n' +
                          '  outputBucket: dev-auto-deploy\n' +
                          '  tfStateBucket: dev-auto-deploy-tf-state\n' +
                          '  dAccountRoles:\n' +
                          '    - arn:aws:iam::385595570414:role/auto-deploy-cli\n' +
                          '    - arn:aws:iam::200683210682:role/auto-deploy-cli\n' +
                          'forGlobal:\n' +
                          '  openedTenantIds: []\n' +
                          '  isPublic: true\n' +
                          '  sortPriority: 1999\n' +
                          'eks:\n' +
                          '  version: "1.30"\n' +
                          '  adminRoles:\n' +
                          '    - cicd-role\n' +
                          '    - argocd-oidc-role\n' +
                          '    - full-manager-service-role\n' +
                          '    - dbaas-dev\n' +
                          '    - dbaas-dev-readonly\n' +
                          '    - dbaas-central-role-dev\n' +
                          '  vpc: # see https://eksctl.io/usage/schema/#vpc\n' +
                          '    cidr: 10.1.0.0/16\n' +
                          '    nat:\n' +
                          '      gateway: Single\n' +
                          '    clusterEndpoints:\n' +
                          '      publicAccess: true\n' +
                          '    publicAccessCIDRs:\n' +
                          '      - 0.0.0.0/0\n' +
                          '  nodeGroups: # see https://eksctl.io/usage/schema/#managedNodeGroups\n' +
                          '    - name: worker\n' +
                          '      amiFamily: Bottlerocket\n' +
                          '      instanceType: m5.large\n' +
                          '      desiredCapacity: 1\n' +
                          '      maxSize: 10\n' +
                          '      privateNetworking: true # must set to true\n' +
                          '# job Options support go template syntax in STRING value\n' +
                          '# and support extened functions:\n' +
                          '# 1. getHostedZoneId name: get hosted zone id by name\n' +
                          '# 2. getLoadBalancerHostedZoneId region: get elb hosted zone id by region name, such as us-west-2\n' +
                          '# 3. getAvailabilityZones region: get availability zones by region name\n' +
                          '# 4. getAwsRoleArn role: get role arn on m-account\n' +
                          'jobOptions:\n' +
                          '  regionalServer:\n' +
                          "    dnsName: '{{ .Name }}.regional-api.dev.aws.tidbcloud.com'\n" +
                          '    hostedZone: dev.aws.tidbcloud.com\n' +
                          '    hostedZoneId: \'{{ getHostedZoneId "dev.aws.tidbcloud.com" }}\'\n' +
                          "    loadBalancerHostedZoneId: '{{ getLoadBalancerHostedZoneId .Region }}'\n" +
                          "    availabilityZones: '{{ getAvailabilityZones .Region }}'\n" +
                          '    publicHostedZoneDomain: clusters.dev.tidb-cloud.com\n' +
                          '    publicHostedZoneID: \'{{ getHostedZoneId "clusters.dev.tidb-cloud.com" }}\'\n' +
                          '    defaultDataplaneAccount: "385595570414"\n' +
                          '    auth0Audience: dev-proxy-service\n' +
                          '    auth0Domain: tidb-dev.us.auth0.com\n' +
                          '    globalControlplaneIPs:\n' +
                          '      - "54.148.240.60/32"\n' +
                          '      - "54.71.2.116/32"\n' +
                          '      - "52.13.110.238/32"\n' +
                          '    o11yRegionalServiceIPs:\n' +
                          '      - "13.214.108.29/32" # for ap-northeast-1 region\n' +
                          '    clinicIPs:\n' +
                          '      - "35.83.225.251/32"\n' +
                          '    bastionIPs: []\n' +
                          '    authorizedSubjects:\n' +
                          '      - arn:aws:iam::552185537300:role/regional-server-role-edf68ba\n' +
                          '      - arn:aws:iam::557537366020:role/regional-server-role-o11y-prod-regional-us-east-1-e177148\n' +
                          '      - \'{{ getAwsRoleArn "devops-server-dev" }}\'\n' +
                          '    o11yRegionalServiceEndpoint: "https://www.rs.{{ .Region }}.aws.observability.tidbcloud.com"\n' +
                          '  clusterServer:\n' +
                          '    clusterProxy:\n' +
                          '      auth0Audience: dev-proxy-service\n' +
                          '      auth0Domain: tidb-dev.us.auth0.com\n' +
                          '      enableDevMode: true\n' +
                          '    configChange:\n' +
                          '      activityClinicEp: http://clinic-dev-1923272735.us-west-2.elb.amazonaws.com:8085\n' +
                          '      activityEnabled: true\n' +
                          '      activityHubEp: https://b9u12esjuf.execute-api.us-west-2.amazonaws.com\n' +
                          '      activitySource: gitops\n' +
                          '      activitySourceKey: 1017a0dafa234d0089be538661c5acef\n' +
                          '      env: dev\n' +
                          '    fullManage:\n' +
                          '      pcaArn: arn:aws:acm-pca:us-west-2:385595570414:certificate-authority/4668d5cc-1042-4371-9ff4-72ab9493c545\n' +
                          '  dpProvider:\n' +
                          '    wafIpSetName: ""\n' +
                          '    secretManager:\n' +
                          '      infraAPIServerKey: dev-dedicated-infra-kubeconfig\n' +
                          '      apiGatewayKey: dev-dp-compat-xregion-auth-key\n' +
                          '  jumpServer:\n' +
                          '    enabled: true\n' +
                          '    role: arn:aws:iam::385595570414:role/dbaas-dev'
                        }
                        style={{ color: 'black' }}
                      ></TextArea>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (
                  operation.name === 'SetDefaultResourcePool' &&
                  v === 'tenant_id' &&
                  target_type === OperationOperationTarget.resource_pool
                ) {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={
                        operation?.params && operation?.params[v].type === 'int'
                          ? [
                              {
                                validator: async (_, value) => {
                                  if (value && !isNumberString(value)) {
                                    return Promise.reject(
                                      new Error(
                                        'the input should be all digits'
                                      )
                                    )
                                  }
                                }
                              },
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                          : [
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                      }
                      initialValue={operation.params?.[v].default ?? null}
                      style={formOptionItemStyle}
                      extra="0 means global default in region; non-zero means default for the specified tenant."
                    >
                      <Input style={{ color: 'black' }}></Input>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (
                  operation.name === 'RestartDMPod' &&
                  v === 'namespace'
                ) {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={[
                        operation?.params &&
                        operation?.params[v].optional === true
                          ? {}
                          : {
                              required: true,
                              message: 'this param is required'
                            }
                      ]}
                      style={formOptionItemStyle}
                    >
                      <Select
                        disabled={false}
                        options={[
                          {
                            value: namespace,
                            label: namespace
                          }
                        ]}
                      ></Select>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (
                  operation.name === 'RestartDMPod' &&
                  v === 'pod_name'
                ) {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={[
                        operation?.params &&
                        operation?.params[v].optional === true
                          ? {}
                          : {
                              required: true,
                              message: 'this param is required'
                            }
                      ]}
                      style={formOptionItemStyle}
                    >
                      <Select
                        options={podNames!.map((m) => {
                          return { label: m, value: m }
                        })}
                      ></Select>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (
                  !!operation.name &&
                  AZ_ZONAL_OPERATION_NAMES.has(operation.name) &&
                  v === 'group_ids'
                ) {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={
                        operation?.params &&
                        operation?.params[v].optional === true
                          ? []
                          : [
                              {
                                required: true,
                                type: 'array',
                                message: 'this param is required'
                              }
                            ]
                      }
                      style={formOptionItemStyle}
                    >
                      <Select
                        mode="multiple"
                        allowClear
                        placeholder="Select TiDB groups (empty = all)"
                        options={tidbGroupOptions}
                      ></Select>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else if (v === 'change_id') {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      style={{ ...formOptionItemStyle, width: 980 }}
                      rules={
                        operation?.params && operation?.params[v].type === 'int'
                          ? [
                              {
                                validator: async (_, value) => {
                                  if (value && !isNumberString(value)) {
                                    return Promise.reject(
                                      new Error(
                                        'the input should be all digits'
                                      )
                                    )
                                  }
                                }
                              },
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                          : [
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                      }
                      initialValue={
                        (operation.params && operation.params[v].default) ||
                        null
                      }
                    >
                      <Input style={{ width: 700 }}></Input>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                } else {
                  return renderFormOption(
                    v,
                    <Form.Item
                      name={['params', v]}
                      rules={
                        operation?.params && operation?.params[v].type === 'int'
                          ? [
                              {
                                validator: async (_, value) => {
                                  if (value && !isNumberString(value)) {
                                    return Promise.reject(
                                      new Error(
                                        'the input should be all digits'
                                      )
                                    )
                                  }
                                }
                              },
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                          : [
                              operation?.params &&
                              operation?.params[v].optional === true
                                ? {}
                                : {
                                    required: true,
                                    message: 'this param is required'
                                  }
                            ]
                      }
                      initialValue={
                        (operation.params && operation.params[v].default) ||
                        null
                      }
                      style={formOptionItemStyle}
                    >
                      <Input></Input>
                    </Form.Item>,
                    paramDescription,
                    paramRequired
                  )
                }
              }
            })
          ) : (
            <></>
          )}
        </FormSection>

        <FormSection title="Actions">
          <div style={actionGridHeaderStyle}>
            <div>Select</div>
            <div>Name</div>
            <div>Schedule</div>
            <div>Schedule Time</div>
          </div>
          {operation?.actions ? (
            operation.actions.map((v, i) => {
              const actionEnabled = form.getFieldValue(['actions', i, 'choose'])

              return (
                <div style={actionGridRowStyle} key={v.name || i}>
                  <div>
                    <Form.Item
                      name={['actions', i, 'choose']}
                      valuePropName="checked"
                      initialValue={
                        COMPOSITE_AZ_OPERATION_NAMES.has(operation?.name || '')
                          ? true
                          : v.optional !== true
                      }
                    >
                      {v.optional ? (
                        <Checkbox
                          onChange={() => {
                            setRefresh((pre) => !pre)
                          }}
                        ></Checkbox>
                      ) : (
                        <>Required</>
                      )}
                    </Form.Item>
                  </div>
                  <div>
                    <Form.Item hidden name={['actions', i, 'name']}>
                      <Input />
                    </Form.Item>
                    <div
                      style={{
                        ...actionNameStyle,
                        textDecoration: actionEnabled
                          ? undefined
                          : 'line-through'
                      }}
                    >
                      {form.getFieldValue(['actions', i, 'name']) || v.name}
                    </div>
                  </div>
                  <div>
                    <Form.Item
                      name={['actions', i, 'start_policy']}
                      rules={[
                        {
                          required: form.getFieldValue([
                            'actions',
                            i,
                            'choose'
                          ]),
                          message: 'choose the policy'
                        }
                      ]}
                    >
                      <Select
                        options={[
                          {
                            label: OperationActionStartPolicy.immediate,
                            value: OperationActionStartPolicy.immediate
                          },
                          {
                            label: OperationActionStartPolicy.manual,
                            value: OperationActionStartPolicy.manual
                          },
                          {
                            label: OperationActionStartPolicy.schedule,
                            value: OperationActionStartPolicy.schedule
                          }
                        ]}
                        onChange={(val) => {
                          const origin = form.getFieldValue(['actions']) || {}
                          origin[i].start_policy = val
                          if (val !== OperationActionStartPolicy.schedule) {
                            origin[i].schedule_time = undefined
                          }
                          form.setFieldsValue({ actions: origin })
                          setRefresh((pre) => !pre)
                        }}
                        disabled={
                          v.optional &&
                          !form.getFieldValue(['actions', i, 'choose'])
                        }
                        style={{ width: '100%' }}
                      ></Select>
                    </Form.Item>
                  </div>
                  <div>
                    <Form.Item
                      name={['actions', i, 'schedule_time']}
                      rules={[
                        {
                          required:
                            form.getFieldValue([
                              'actions',
                              i,
                              'start_policy'
                            ]) === OperationActionStartPolicy.schedule,
                          message: 'choose the schedule time'
                        }
                      ]}
                    >
                      {form.getFieldValue(['actions', i, 'start_policy']) ===
                      OperationActionStartPolicy.schedule ? (
                        <DatePicker
                          showTime={true}
                          style={{ width: '100%' }}
                        ></DatePicker>
                      ) : (
                        <></>
                      )}
                    </Form.Item>
                  </div>
                </div>
              )
            })
          ) : (
            <></>
          )}
        </FormSection>

        <FormSection title="Create Options">
          {isClusterTarget && (
            <div style={{ marginTop: '12px' }}>
              <ClusterOpsMaintenanceWindowCheckAlert
                clusterId={clusterId}
                executeTimes={executeTimes}
              />
            </div>
          )}

          <FormOption title="Reason" required>
            <Form.Item
              name="reason"
              rules={[{ required: true }]}
              style={formOptionItemStyle}
            >
              <TextArea rows={3} placeholder="Briefly explain this operation" />
            </Form.Item>
          </FormOption>
          <FormOption
            title="Execution Window"
            description="Execution Window limits when this operation can be executed."
            info_link="https://pingcap.feishu.cn/wiki/KLIhwUR2Bi1MTxks5ZkcP2ZmnFh?larkTabName=space#share-GKgHdtzOAoT8xCxqrLCcHE2znFb"
          >
            <Form.Item
              name="execution_window_enabled"
              initialValue={false}
              noStyle
            >
              <Radio.Group
                onChange={(event) => {
                  if (!event.target.value) {
                    form.setFieldsValue({
                      execution_window_range: undefined
                    })
                  }
                }}
              >
                <Radio value={true}>Enable</Radio>
                <Radio value={false}>Disable</Radio>
              </Radio.Group>
            </Form.Item>
          </FormOption>
          {executionWindowEnabled && (
            <FormOption title="Execution Window Time Range (Local Time)">
              <Form.Item
                name="execution_window_range"
                rules={[
                  {
                    required: true,
                    message: 'Please select execution window time range'
                  },
                  {
                    validator: (_, value) => {
                      if (!executionWindowEnabled) {
                        return Promise.resolve()
                      }
                      if (!value?.[0] || !value?.[1]) {
                        return Promise.reject(
                          new Error('Please select execution window time range')
                        )
                      }
                      if (!value[0].isBefore(value[1])) {
                        return Promise.reject(
                          new Error('Start time must be before end time')
                        )
                      }

                      return Promise.resolve()
                    }
                  }
                ]}
                style={formOptionItemStyle}
              >
                <RangePicker showTime />
              </Form.Item>
            </FormOption>
          )}
          <FormOption
            title="Save as Draft"
            description="Save the operation as a draft. This will not trigger approval, allowing you to modify and confirm it before submission."
            required
          >
            <Form.Item
              name="is_draft"
              rules={[{ required: true, message: 'choose if save as draft' }]}
              initialValue={false}
              style={formOptionItemStyle}
            >
              <Radio.Group>
                <Radio value={true}>Yes</Radio>
                <Radio value={false}>No</Radio>
              </Radio.Group>
            </Form.Item>
          </FormOption>
        </FormSection>
      </FormSectionGroup>
    </>
  )
}

function isNumberString(str: string): boolean {
  const regex = /^[0-9]+$/
  return regex.test(str)
}

export default CreateInstanceForm
