import { Form, Input, Select } from 'antd'
import TextArea from 'antd/lib/input/TextArea'
import { FormInstance } from 'rc-field-form'
import { useEffect, useState } from 'react'

import {
  cloudConfigControllerListConfigTypes,
  cloudConfigControllerListParameterVersions
} from 'apiClient/services/devops'
import {
  CloudconfigClusterType,
  CloudconfigParameterApplyPolicy
} from 'apiClient/services/devops/interface'
import {
  IsBool,
  IsFloat,
  IsInt,
  IsJson
} from 'pages/Tenants/ClusterDetail/Configs/Forms/EditParamForm'
import {
  CONFIG_IDENTIFIER_PATTERN,
  sanitizeConfigIdentifier
} from 'utils/string'

export type AddConfigFormType = {
  clusterType: CloudconfigClusterType
  configType: string
  apply_policy: CloudconfigParameterApplyPolicy
  param_name: string
  version: string
  type: string
  defaultVal: string
  description: string
  validation: string
}

function AddConfigForm({
  form,
  defaultClusterType
}: {
  form: FormInstance
  defaultClusterType?: string
}) {
  const [type, setType] = useState<string>()
  const [clusterType, setClusterType] = useState<
    CloudconfigClusterType | undefined
  >(defaultClusterType as CloudconfigClusterType | undefined)
  const [configTypeOpts, setConfigTypeOpts] = useState<string[]>()
  const [versionOpts, setVersionOpts] = useState<string[]>()

  useEffect(() => {
    if (defaultClusterType) {
      form.setFieldsValue({ clusterType: defaultClusterType })
    }
  }, [defaultClusterType])

  useEffect(() => {
    if (!clusterType) return
    ;(async () => {
      try {
        const configTypes = (
          await cloudConfigControllerListConfigTypes(clusterType)
        ).data.config_types
        const versions = (
          await cloudConfigControllerListParameterVersions({
            cluster_type: clusterType
          })
        ).data.versions
        setConfigTypeOpts(configTypes)
        setVersionOpts(versions)
        form.setFieldsValue({ configType: undefined, version: undefined })
      } catch (e) {
        console.error(e)
      }
    })()
  }, [clusterType])

  return (
    <>
      <Form.Item
        label="Cluster Type"
        name="clusterType"
        rules={[{ required: true }]}
      >
        <Select
          options={[
            { label: 'Dedicated', value: 'DEDICATED_TIDB' },
            { label: 'TiCDC', value: 'TICDC' },
            { label: 'Changefeed', value: 'CHANGEFEED' },
            { label: 'Resource Pool', value: 'SHARED_POOL' },
            { label: 'Premium & BYOC', value: 'LOGICAL_CLUSTER' },
            { label: 'TiCDC NG', value: 'TICDC_NG' },
            { label: 'Changefeed NG', value: 'CHANGEFEED_NG' }
          ]}
          onChange={(val) => {
            setClusterType(val)
          }}
        ></Select>
      </Form.Item>
      <Form.Item label="Version" name="version" rules={[{ required: true }]}>
        <Select
          options={versionOpts?.map((v) => {
            return { label: v, value: v }
          })}
          onChange={(e) => {
            form.setFieldsValue({ version: e })
          }}
        ></Select>
      </Form.Item>
      <Form.Item
        label="Config Type"
        name="configType"
        rules={[{ required: true }]}
      >
        <Select
          options={configTypeOpts?.map((v) => {
            return { label: v, value: v }
          })}
          onChange={(e) => {
            form.setFieldsValue({ confgType: e })
          }}
        ></Select>
      </Form.Item>
      <Form.Item
        label="Config Name"
        name="param_name"
        normalize={(value) => sanitizeConfigIdentifier(value || '')}
        rules={[
          { required: true },
          {
            pattern: CONFIG_IDENTIFIER_PATTERN,
            message:
              'Only letters, numbers, underscores, hyphens, and dots are allowed'
          }
        ]}
      >
        <Input></Input>
      </Form.Item>
      <Form.Item label="Type" name="type" rules={[{ required: true }]}>
        <Select
          options={[
            { label: 'int', value: 'int' },
            { label: 'float', value: 'float' },
            { label: 'string', value: 'string' },
            { label: 'bool', value: 'bool' },
            { label: 'json', value: 'json' }
          ]}
          onChange={(e) => {
            form.setFieldsValue({ type: e })
            setType(String(e))
          }}
        ></Select>
      </Form.Item>
      <Form.Item
        label="Default Value"
        name="defaultVal"
        rules={
          form.getFieldValue(['type']) === 'int'
            ? [
                {
                  validator: async (_, value) => {
                    if (!IsInt(value)) {
                      return Promise.reject(
                        new Error('the input should be an int')
                      )
                    }
                  }
                },
                {
                  required: true,
                  message: 'new value is required'
                }
              ]
            : form.getFieldValue(['type']) === 'float'
            ? [
                {
                  validator: async (_, value) => {
                    if (!IsFloat(value)) {
                      return Promise.reject(
                        new Error('the input should be float')
                      )
                    }
                  }
                },
                {
                  required: true,
                  message: 'new float value is required'
                }
              ]
            : form.getFieldValue(['type']) === 'bool'
            ? [
                {
                  validator: async (_, value) => {
                    if (!IsBool(value)) {
                      return Promise.reject(
                        new Error('the input should be bool')
                      )
                    }
                  }
                },
                {
                  required: true,
                  message: 'new value is required'
                }
              ]
            : form.getFieldValue(['type']) === 'json'
            ? [
                {
                  validator: async (_, value) => {
                    if (!IsJson(value)) {
                      return Promise.reject(
                        new Error('the input should be json format')
                      )
                    }
                  }
                },
                {
                  required: true,
                  message: 'new value is required'
                }
              ]
            : [
                {
                  required: true,
                  message: 'new value is required'
                }
              ]
        }
      >
        <TextArea autoSize></TextArea>
      </Form.Item>
      <Form.Item
        label="Validation"
        name="validation"
        rules={[{ required: false }]}
      >
        <Input></Input>
      </Form.Item>
      <Form.Item
        label="Apply Policy"
        name="apply_policy"
        rules={[{ required: true }]}
      >
        <Select
          options={[
            {
              label: CloudconfigParameterApplyPolicy.HotReload,
              value: CloudconfigParameterApplyPolicy.HotReload
            },
            {
              label: CloudconfigParameterApplyPolicy.RollingRestart,
              value: CloudconfigParameterApplyPolicy.RollingRestart
            }
          ]}
        ></Select>
      </Form.Item>
      <Form.Item label="Description" name="description">
        <TextArea autoSize></TextArea>
      </Form.Item>
    </>
  )
}

export default AddConfigForm
