import {
  Divider,
  Form,
  InputNumber,
  Select,
  Tag,
  Typography,
  FormInstance
} from 'antd'
import React, { useEffect, useState } from 'react'

import { calcNodeProfiles } from 'apiClient/api'
import {
  FormsNodeProfilesWithComponentType,
  FormsNodeProfile
} from 'apiClient/api/interface'
import {
  ClusterClusterComponent,
  ClusterGetClusterResp
} from 'apiClient/services/devops/interface'
import ModalForm from 'components/ModalForm'

const itemStyle = { marginBottom: '0.5em' }

function SetupTiFlashComponents({
  form,
  profiles
}: {
  form: FormInstance
  profiles: FormsNodeProfile[]
}) {
  const [sel, setSel] = useState<FormsNodeProfile>(profiles[0])

  return (
    <div>
      <Typography.Text strong>TiFlash (Optional)</Typography.Text>
      <Form.Item
        name={['tiflash', 'node_profile', 'name']}
        label="vCPUs Size"
        style={itemStyle}
      >
        <Select
          placeholder="please select a profile."
          onChange={(value) => {
            const _sel = profiles.find((p: FormsNodeProfile) => p.id === value)
            if (_sel) {
              setSel(_sel)
              form.setFieldsValue({
                tiflash: {
                  node_profile: {
                    name: _sel?.name,
                    storage_gi: _sel?.min_storage_size_gi
                  },
                  replicas: _sel?.default_node_num
                }
              })
            }
          }}
        >
          {profiles.map((p) => {
            return (
              <Select.Option key={p.id} value={p.id}>
                {p.name}
              </Select.Option>
            )
          })}
        </Select>
      </Form.Item>
      <Form.Item
        name={['tiflash', 'node_profile', 'storage_gi']}
        label="Storage Size"
        style={itemStyle}
        extra={`min: ${sel?.min_storage_size_gi} GiB, max: ${sel?.max_storage_size_gi} GiB`}
      >
        <InputNumber
          min={sel?.min_storage_size_gi}
          max={sel?.max_storage_size_gi}
        />
      </Form.Item>
      <Form.Item
        name={['tiflash', 'replicas']}
        label="Node Quantity"
        style={itemStyle}
      >
        <InputNumber min={0} max={128} step="1" />
      </Form.Item>
    </div>
  )
}

export default function ScaleModalForm({
  name,
  open,
  org_id,
  cluster,
  onSubmit,
  onCancel
}: {
  name: string
  open: boolean
  org_id: string
  cluster: ClusterGetClusterResp
  onSubmit: (values: ClusterClusterComponent) => Promise<void> | void
  onCancel: () => void
}) {
  const { provider, region, project_id } = cluster
  const { tidb, tikv, tiflash } = cluster.cluster_components || {}
  const hasTiFlash = tiflash?.replicas
  const is4cCluster = tidb?.node_profile?.compute?.cpu === 4
  const [tiflashProfiles, setProfiles] =
    useState<FormsNodeProfilesWithComponentType | null>(null)

  useEffect(() => {
    async function fetch() {
      const data = (
        await calcNodeProfiles({
          org_id,
          project_id: project_id?.toString(),
          provider,
          region,
          is_dev_tier: false
        })
      ).data
      const tiflashProfiles = data?.component_node_profiles?.find(
        (p: FormsNodeProfilesWithComponentType) =>
          p.component_type === 'COMPONENT_TYPE_TIFLASH'
      )
      setProfiles(tiflashProfiles || null)
    }

    if (!hasTiFlash) {
      fetch()
    }
  }, [org_id, hasTiFlash, provider, region])

  const renderFormFields = (form: FormInstance) => {
    return (
      <>
        <div>
          <Typography.Text strong>TiDB</Typography.Text>
          <Form.Item label="vCPUs Size" style={itemStyle}>
            <Tag>{tidb?.node_profile?.name || '-'}</Tag>
          </Form.Item>
          <Form.Item
            name={['tidb', 'replicas']}
            label="Node Quantity"
            style={itemStyle}
            extra={
              is4cCluster
                ? 'The maximum number of 4 vCPU TiDB node quantity is 2.'
                : ''
            }
          >
            <InputNumber min={1} max={is4cCluster ? 2 : 128} step="1" />
          </Form.Item>
        </div>
        <Divider />
        <div>
          <Typography.Text strong>TiKV</Typography.Text>
          <Form.Item label="vCPUs Size" style={itemStyle}>
            <Tag>{tikv?.node_profile?.name || '-'}</Tag>
          </Form.Item>
          <Form.Item label="Storage Size" style={itemStyle}>
            <Tag>{tikv?.node_profile?.storage_gi || '-'} GiB</Tag>
          </Form.Item>
          <Form.Item
            name={['tikv', 'replicas']}
            label="Node Quantity"
            style={itemStyle}
            extra={
              is4cCluster ? 'The number of 4 vCPU TiKV node quantity is 3.' : ''
            }
          >
            <InputNumber min={3} max={is4cCluster ? 3 : 128} step="3" />
          </Form.Item>
        </div>
        <Divider />
        {hasTiFlash ? (
          <div>
            <Typography.Text strong>TiFlash</Typography.Text>
            <Form.Item label="vCPUs Size" style={itemStyle}>
              <Tag>{tiflash?.node_profile?.name || '-'}</Tag>
            </Form.Item>
            <Form.Item label="Storage Size" style={itemStyle}>
              <Tag>{tiflash?.node_profile?.storage_gi || '-'} GiB</Tag>
            </Form.Item>
            <Form.Item
              name={['tiflash', 'replicas']}
              label="Node Quantity"
              style={itemStyle}
            >
              <InputNumber min={0} max={128} step="1" />
            </Form.Item>
          </div>
        ) : !is4cCluster && tiflashProfiles?.profiles ? (
          // tricky to control form values
          <SetupTiFlashComponents
            profiles={tiflashProfiles.profiles}
            form={form}
          />
        ) : null}
      </>
    )
  }

  const handleSubmit = (values: ClusterClusterComponent) => {
    return onSubmit(values)
  }

  const initValues = hasTiFlash
    ? cluster.cluster_components
    : {
        ...cluster.cluster_components,
        tiflash: {
          node_profile: {
            name: tiflashProfiles?.profiles?.[0]?.name || '',
            storage_gi: tiflashProfiles?.profiles?.[0]?.min_storage_size_gi || 0
          },
          replicas: tiflashProfiles?.profiles?.[0]?.default_node_num || 0
        }
      }

  return (
    <ModalForm<ClusterClusterComponent>
      visible={open}
      name={name}
      title="Scale Cluster Components"
      initValues={initValues}
      getFields={renderFormFields}
      onSubmit={handleSubmit}
      onCancel={onCancel}
      okText="Next"
    />
  )
}
