import {
  Form,
  InputNumber,
  Select,
  Button,
  Row,
  Col,
  Input,
  Space,
  Modal,
  Divider,
  Radio
} from 'antd'
import { FormInstance } from 'antd/es/form/Form'
import { SelectValue } from 'antd/lib/select'
import moment from 'moment'
import React, { useEffect, useState } from 'react'

import {
  spuServiceListComputeMus,
  spuServiceListSkus,
  spuServiceListSpus,
  spuServiceListStorageMus
} from 'apiClient/services/sku'
import {
  Dedicatedv1ComponentType,
  InstanceMuCpuArch,
  SpuServiceListSkusCloudProvider,
  SpuServiceListSkusComponentTypesItem,
  StorageMuVolumeType,
  TidbMgmtServicev1Sku,
  TidbMgmtServicev1Spu,
  TidbMgmtServicev1StorageMu,
  V1ComputeMu
} from 'apiClient/services/sku/interface'

import {
  getAvailableDisplaynames,
  getAvailableSPUKeys,
  getAvailableVolumeTypes
} from '..'

export type StorageType = {
  //below is related to storage.
  volumeType: StorageMuVolumeType
  storageMuId: string
  defaultStorageSize: number
  minStorageSize: number
  maxStorageSize: number
  minIops: number
  maxIops: number
  minThroughput: number
  maxThroughput: number
  iopsStrategy: 'Fixed' | 'Dynamic'
  throughputStrategy: 'Fixed' | 'Dynamic'
  iopsValue?: number
  throughputValue?: number
  throughputMibpsPerSizeGi?: number
  throughputMibpsPerIops?: number
}

export type SKUFormType = StorageType & {
  displayName: string
  componentType: SpuServiceListSkusComponentTypesItem
  provider: SpuServiceListSkusCloudProvider
  spuKey: string
  spuId: string
  instanceType: string
  instanceMuId: string
  cpuArch: InstanceMuCpuArch
  vCPUNumber: number
  memorySize: number
  defaultNodeNumber: number
  skuKey: string
  raft: StorageType
  //pd related.
  tikvSkuKey?: string[]
}

const SKUPage = ({ form, type }: { form: FormInstance; type: string }) => {
  const getSelectPopupContainer = (triggerNode: HTMLElement) =>
    triggerNode.parentElement || document.body

  const [availableComputeMus, setAvailableComputeMus] =
    useState<V1ComputeMu[]>()
  // 在组件顶部添加
  const [componentType, setComponentType] =
    useState<SpuServiceListSkusComponentTypesItem>(
      form.getFieldValue('componentType')
    )
  const [dataSource, setDataSource] = useState<TidbMgmtServicev1Sku[]>()
  const [spus, setSpus] = useState<TidbMgmtServicev1Spu[]>()
  const [tikvDataSource, setTikvDataSource] = useState<TidbMgmtServicev1Sku[]>()
  const [provider, setProvider] = useState<SpuServiceListSkusCloudProvider>()
  const [availableStorageMus, setAvailableStorageMus] =
    useState<TidbMgmtServicev1StorageMu[]>()
  const [displayName, setDisplayName] = useState<string>()
  const handleProviderChange = async (v: SelectValue) => {
    const p = String(v) as SpuServiceListSkusCloudProvider
    form.resetFields()
    form.setFieldsValue({
      provider: String(v),
      componentType: componentType
    })
    setProvider(p)
    // List instance types.
    const resp = (
      await spuServiceListComputeMus({ cloudProvider: p })
    ).data.computeMus?.sort((a, b) =>
      a.instanceType.localeCompare(b.instanceType)
    )
    setAvailableComputeMus(resp)
  }
  useEffect(() => {
    async function init() {
      if (provider || form.getFieldValue('provider')) {
        const p =
          provider ||
          (form.getFieldValue('provider') as SpuServiceListSkusCloudProvider)
        const data = (
          await spuServiceListSkus({
            cloudProvider: p,
            componentTypes: [SpuServiceListSkusComponentTypesItem.TIKV]
          })
        ).data.skus
        setTikvDataSource(data)
        const mus = (await spuServiceListStorageMus({ cloudProvider: p })).data
          .storageMus
        setAvailableStorageMus(mus)
      }
      if (componentType) {
        const spusResp = (
          await spuServiceListSpus({ componentType: componentType })
        ).data.spus
        setSpus(spusResp)
      }
    }
    init()
  }, [provider, componentType])
  useEffect(() => {
    async function init() {
      if (provider) {
        const data = (
          await spuServiceListSkus({
            cloudProvider: provider,
            componentTypes: [componentType]
          })
        ).data.skus
        setDataSource(data)
      }
    }
    init()
  }, [provider, componentType])

  const handleInstanceTypeChange = async (i: String) => {
    form.setFieldsValue({ instanceType: i })
    // Fill the corresponding fields
    let targetMu!: V1ComputeMu
    for (const item of availableComputeMus || []) {
      if (item.instanceType === i) {
        targetMu = item
        break
      }
    }
    form.setFieldsValue({
      vCPUNumber: targetMu.cpuCore,
      memorySize: targetMu.memoryGi,
      cpuArch: targetMu.cpuArch,
      instanceMuId: targetMu.id
    })
  }

  const handleGenerate = () => {
    const p = form.getFieldValue('provider')
    const componentValue = form.getFieldValue('componentType')
    const instanceType = form.getFieldValue('instanceType')
    let storageType = form.getFieldValue('volumeType')
    if (componentValue === SpuServiceListSkusComponentTypesItem.TIDB) {
      storageType = StorageMuVolumeType.LOCAL_STORAGE
    }
    if (
      p === undefined ||
      componentType === undefined ||
      instanceType === undefined ||
      storageType == undefined
    ) {
      Modal.warn({
        title: 'fill the required fields before generating',
        content:
          'Please fill the previous required fields to generate the sku key'
      })
    } else {
      const sku =
        `${p}:${componentValue}:${instanceType}:${storageType}:${moment().format(
          'YYYY-MM-DD-HH:mm:ss'
        )}`.toLocaleLowerCase()
      form.setFieldsValue({ skuKey: sku })
    }
  }

  const dataStoragePage = (name: string, prefix?: string) => {
    return (
      <>
        <Divider>{name}</Divider>
        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              labelCol={{ span: 24 }}
              label="Volume Type"
              name={
                prefix ? [prefix, 'storageMuSelector'] : 'storageMuSelector'
              }
              rules={[
                { required: true, message: 'Please select a Volume type!' }
              ]}
            >
              <Select
                getPopupContainer={getSelectPopupContainer}
                disabled={type === 'modify'}
                options={availableStorageMus?.map((v) => ({
                  label: `${v.volumeType}(${v.id})`,
                  value: v.id,
                  volumeType: v.volumeType
                }))}
                style={{ width: 150 }}
                onChange={(v) => {
                  const selected = availableStorageMus?.find(
                    (item) => item.id === v
                  )
                  if (!selected) return

                  if (prefix) {
                    form.setFieldsValue({
                      [prefix]: {
                        storageMuSelector: selected.id,
                        storageMuId: selected.id,
                        volumeType: selected.volumeType
                      }
                    })
                  } else {
                    form.setFieldsValue({
                      storageMuSelector: selected.id,
                      storageMuId: selected.id,
                      volumeType: selected.volumeType
                    })
                  }
                }}
              />
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="StorageMu Id"
              name={prefix ? [prefix, 'storageMuId'] : 'storageMuId'}
              labelCol={{ span: 24 }}
              rules={[
                {
                  required: true,
                  message: 'Please input default storage size!'
                }
              ]}
            >
              <Input disabled={true} style={{ width: 150 }}></Input>
            </Form.Item>
          </Col>
        </Row>
        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              label="Default Storage"
              name={
                prefix ? [prefix, 'defaultStorageSize'] : 'defaultStorageSize'
              }
              labelCol={{ span: 24 }}
              rules={[
                {
                  required: true,
                  message: 'Please input default storage size!'
                }
              ]}
            >
              <InputNumber min={0} placeholder="GiB" style={{ width: 150 }} />
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="Min Storage"
              labelCol={{ span: 24 }}
              name={prefix ? [prefix, 'minStorageSize'] : 'minStorageSize'}
              rules={[
                { required: true, message: 'Please input min storage size!' }
              ]}
            >
              <InputNumber min={0} placeholder="GiB" style={{ width: 150 }} />
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="Max Storage"
              name={prefix ? [prefix, 'maxStorageSize'] : 'maxStorageSize'}
              labelCol={{ span: 24 }}
              rules={[
                { required: true, message: 'Please input max storage size!' }
              ]}
            >
              <InputNumber min={0} placeholder="GiB" style={{ width: 150 }} />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              label="Min IOPS"
              name={prefix ? [prefix, 'minIops'] : 'minIops'}
              labelCol={{ span: 24 }}
              rules={[
                { required: true, message: 'Please input minimum iops!' }
              ]}
            >
              <InputNumber
                min={0}
                placeholder="Operations/s"
                style={{ width: 150 }}
              />
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="Max IOPS"
              name={prefix ? [prefix, 'maxIops'] : 'maxIops'}
              labelCol={{ span: 24 }}
              rules={[
                { required: true, message: 'Please input maximum IOPS!' }
              ]}
            >
              <InputNumber
                min={0}
                placeholder="Operations/s"
                style={{ width: 150 }}
              />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              label="Iops Strategy"
              name={prefix ? [prefix, 'iopsStrategy'] : 'iopsStrategy'}
              labelCol={{ span: 24 }}
              rules={[
                { required: true, message: 'Please select iops strategy' }
              ]}
            >
              <Radio.Group optionType="button" buttonStyle="solid">
                <Radio
                  value="Fixed"
                  // style={radioStyle}
                  className="custom-radio-active" // 自定义选中样式
                >
                  Fixed
                </Radio>

                <Radio
                  value="Dynamic"
                  // style={radioStyle}
                  className="custom-radio-inactive" // 自定义未选中样式
                >
                  Dynamic
                </Radio>
              </Radio.Group>
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              shouldUpdate={(prev, current) => prev !== current}
              noStyle
            >
              {() => (
                <Form.Item
                  label={
                    form.getFieldValue(
                      prefix ? [prefix, 'iopsStrategy'] : ['iopsStrategy']
                    ) === 'Fixed'
                      ? 'Fixed Value'
                      : 'Iops per Gi'
                  }
                  name={prefix ? [prefix, 'iopsValue'] : 'iopsValue'}
                  labelCol={{ span: 24 }}
                  rules={[{ required: true, message: 'Please input !' }]}
                >
                  <InputNumber min={0} style={{ width: 150 }} />
                </Form.Item>
              )}
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              label="Min Throughput"
              name={prefix ? [prefix, 'minThroughput'] : 'minThroughput'}
              labelCol={{ span: 24 }}
              rules={[
                {
                  required: true,
                  message: 'Please input minimum throughput!'
                }
              ]}
            >
              <InputNumber min={0} placeholder="MB/s" style={{ width: 150 }} />
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="Max Throughput"
              name={prefix ? [prefix, 'maxThroughput'] : 'maxThroughput'}
              labelCol={{ span: 24 }}
              rules={[
                {
                  required: true,
                  message: 'Please input maximum throughput!'
                }
              ]}
            >
              <InputNumber min={0} placeholder="MB/s" style={{ width: 150 }} />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col span={8}>
            <Form.Item
              label="Throughput Strategy"
              name={
                prefix ? [prefix, 'throughputStrategy'] : 'throughputStrategy'
              }
              labelCol={{ span: 24 }}
              rules={[
                {
                  required: true,
                  message: 'Please select throughput strategy'
                }
              ]}
            >
              <Radio.Group optionType="button" buttonStyle="solid">
                <Radio
                  value="Fixed"
                  // style={radioStyle}
                  className="custom-radio-active" // 自定义选中样式
                >
                  Fixed
                </Radio>

                <Radio
                  value="Dynamic"
                  // style={radioStyle}
                  className="custom-radio-inactive" // 自定义未选中样式
                >
                  Dynamic
                </Radio>
              </Radio.Group>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Form.Item shouldUpdate={(prev, current) => prev !== current} noStyle>
            {() =>
              form.getFieldValue(
                prefix ? [prefix, 'throughputStrategy'] : ['throughputStrategy']
              ) === 'Fixed' ? (
                <Col span={8}>
                  <Form.Item
                    label={'Fixed Value'}
                    name={
                      prefix ? [prefix, 'throughputValue'] : 'throughputValue'
                    }
                    labelCol={{ span: 24 }}
                    rules={[{ required: true, message: 'Please input!' }]}
                  >
                    <InputNumber min={0} style={{ width: 150 }} />
                  </Form.Item>
                </Col>
              ) : (
                <>
                  <Col span={8}>
                    <Form.Item
                      label={'Mibps per SizeGi'}
                      name={
                        prefix
                          ? [prefix, 'throughputMibpsPerSizeGi']
                          : 'throughputMibpsPerSizeGi'
                      }
                      labelCol={{ span: 24 }}
                      rules={[{ required: true, message: 'Please input!' }]}
                    >
                      <InputNumber min={0} style={{ width: 150 }} />
                    </Form.Item>
                  </Col>
                  <Col span={8}>
                    <Form.Item
                      label={'Mibps per Iops'}
                      name={
                        prefix
                          ? [prefix, 'throughputMibpsPerIops']
                          : 'throughputMibpsPerIops'
                      }
                      labelCol={{ span: 24 }}
                      rules={[{ required: true, message: 'Please input!' }]}
                    >
                      <InputNumber min={0} style={{ width: 150 }} />
                    </Form.Item>
                  </Col>
                </>
              )
            }
          </Form.Item>
        </Row>
      </>
    )
  }

  return (
    <>
      <Row gutter={16}>
        <Col span={8}>
          <Form.Item
            label="Component Type"
            name="componentType"
            labelCol={{ span: 24 }}
            rules={[
              { required: true, message: 'Please select a component type!' }
            ]}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              disabled={type === 'modify'}
              onChange={(v) => {
                form.resetFields()
                form.setFieldsValue({ componentType: String(v) })
                setComponentType(
                  String(v) as SpuServiceListSkusComponentTypesItem
                )
              }}
              options={Object.entries(SpuServiceListSkusComponentTypesItem).map(
                ([key, value]) => ({
                  label: key,
                  value: value
                })
              )}
              style={{ width: 150 }}
            />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="Provider"
            name="provider"
            labelCol={{ span: 24 }}
            rules={[{ required: true, message: 'Please select a provider!' }]}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              disabled={type === 'modify'}
              onChange={handleProviderChange}
              options={Object.entries(SpuServiceListSkusCloudProvider).map(
                ([key, value]) => ({
                  label: key,
                  value: value
                })
              )}
              style={{ width: 150 }}
            />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="Display Name"
            name="displayName"
            labelCol={{ span: 24 }}
            rules={[
              { required: true, message: 'Please input a display name!' }
            ]}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              disabled={type === 'modify'}
              options={spus
                ?.map((v) => ({
                  label: v.displayName,
                  value: v.displayName,
                  displayName: v.displayName
                }))
                .filter(
                  (item, index, arr) =>
                    index ===
                    arr.findIndex((v) => v.displayName === item.displayName)
                )}
              onChange={(v) => {
                form.setFieldsValue({ spuKey: undefined, spuId: undefined })
                setDisplayName(String(v))
              }}
              style={{ width: 200 }}
              showSearch
              allowClear
              placeholder="provider is required"
            ></Select>
          </Form.Item>
        </Col>
      </Row>

      <Row gutter={0}>
        <Col span={24}>
          <Form.Item
            label="SPU Key"
            name="spuKey"
            rules={[{ required: true, message: 'select a spu key!' }]}
            labelCol={{
              style: {
                width: 110,
                flex: '0 0 auto'
              }
            }}
            wrapperCol={{
              style: {
                flex: 1,
                minWidth: 0
              }
            }}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              disabled={type === 'modify'}
              onChange={(v) => {
                let spuId
                for (let d of spus || []) {
                  if (d.key === v) {
                    spuId = d.id
                  }
                }
                form.setFieldsValue({ spuId: spuId })
              }}
              options={spus
                ?.filter((v) => {
                  return (
                    v.displayName === displayName &&
                    v.componentType === componentType
                  )
                })
                .map((v) => ({
                  label: v.key,
                  value: v.key!
                }))}
              style={{ width: '70%' }}
              showSearch
              allowClear
              placeholder="spu key is required"
            />
          </Form.Item>
        </Col>
      </Row>

      <Row>
        <Col span={8}>
          <Form.Item
            label="SPU ID"
            name="spuId"
            rules={[{ required: true, message: 'Please input!' }]}
          >
            <Input disabled={true} style={{ width: 150 }}></Input>
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="Instance Type"
            name="instanceType"
            labelCol={{ span: 24 }}
            rules={[
              { required: true, message: 'Please select a instance type!' }
            ]}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              disabled={type === 'modify'}
              onChange={(v) => handleInstanceTypeChange(String(v))}
              options={availableComputeMus?.map((v) => ({
                label: v.instanceType,
                value: v.instanceType
              }))}
              style={{ width: 150 }}
            />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="InstanceMu ID"
            labelCol={{ span: 24 }}
            name="instanceMuId"
            rules={[{ required: true, message: 'Please input!' }]}
          >
            <Input disabled={true} style={{ width: 150 }}></Input>
          </Form.Item>
        </Col>
      </Row>

      <Row gutter={16}>
        <Col span={8}>
          <Form.Item
            label="CPU Arch"
            name="cpuArch"
            labelCol={{ span: 24 }}
            rules={[{ required: true, message: 'Please select a CPU Arch!' }]}
          >
            <Select
              getPopupContainer={getSelectPopupContainer}
              options={Object.entries(InstanceMuCpuArch).map(
                ([key, value]) => ({
                  label: key,
                  value: value
                })
              )}
              disabled={true}
              bordered={false}
              style={{ color: 'black', width: 150 }}
            />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="vCPU Number"
            labelCol={{ span: 24 }}
            name="vCPUNumber"
            rules={[{ required: true, message: 'Please input cpu number!' }]}
          >
            <InputNumber
              min={0}
              placeholder="vCPU"
              disabled={true}
              bordered={false}
              style={{ color: 'black', width: 150 }}
            />
          </Form.Item>
        </Col>
        <Col span={8}>
          <Form.Item
            label="Memory Size"
            name="memorySize"
            labelCol={{ span: 24 }}
            rules={[{ required: true, message: 'Please input memory size!' }]}
          >
            <InputNumber
              min={0}
              placeholder="GiB"
              style={{ width: 150, color: 'black' }}
              disabled={true}
              bordered={false}
            />
          </Form.Item>
        </Col>
      </Row>

      <Row gutter={16}>
        <Col span={12}>
          <Form.Item
            label="Default Node Num"
            name="defaultNodeNumber"
            rules={[
              { required: true, message: 'Please input default node number!' }
            ]}
            style={{ whiteSpace: 'normal' }}
          >
            <InputNumber min={0} style={{ width: 150 }} />
          </Form.Item>
        </Col>
      </Row>

      {componentType ===
      (SpuServiceListSkusComponentTypesItem.TIDB ||
        SpuServiceListSkusComponentTypesItem.TIPROXY) ? (
        <></>
      ) : (
        dataStoragePage('Data Storage')
      )}
      {componentType !==
      (SpuServiceListSkusComponentTypesItem.TIDB ||
        SpuServiceListSkusComponentTypesItem.TIPROXY) ? (
        <Row gutter={16}>
          <Col span={12}>
            <Form.Item
              label="Edit Raft Storage"
              name="raftEnable"
              rules={[
                {
                  required: true,
                  message: 'Please select if you want to edit raft storage'
                }
              ]}
            >
              <Radio.Group
                optionType="button"
                buttonStyle="solid"
                disabled={type === 'modify'}
              >
                <Radio
                  value={true}
                  // style={radioStyle}
                  className="custom-radio-active" // 自定义选中样式
                >
                  True
                </Radio>

                <Radio
                  value={false}
                  // style={radioStyle}
                  className="custom-radio-inactive" // 自定义未选中样式
                >
                  False
                </Radio>
              </Radio.Group>
            </Form.Item>
          </Col>
        </Row>
      ) : (
        <></>
      )}

      {componentType ===
      (SpuServiceListSkusComponentTypesItem.TIDB ||
        SpuServiceListSkusComponentTypesItem.TIPROXY) ? (
        <></>
      ) : (
        <>
          <Form.Item
            shouldUpdate={(prev, current) =>
              prev.raftEnable !== current.raftEnable
            }
            noStyle
          >
            {() =>
              form.getFieldValue('raftEnable') === true ? (
                dataStoragePage('Raft Storage', 'raft')
              ) : (
                <></>
              )
            }
          </Form.Item>
        </>
      )}

      <Form.Item
        label="SKU KEY"
        labelCol={{
          style: {
            width: 110,
            flex: '0 0 auto'
          }
        }}
        wrapperCol={{
          style: {
            flex: 1,
            minWidth: 0
          }
        }}
      >
        <Row gutter={0}>
          <Col span={24}>
            <Form.Item
              name="skuKey"
              noStyle
              rules={[{ required: true, message: 'Please input SKU KEY!' }]}
            >
              <Input disabled={type === 'modify'} style={{ width: '70%' }} />
            </Form.Item>

            {/* <Button
              type="primary"
              onClick={handleGenerate}
              disabled={type === 'modify'}
            >
              Generate
            </Button> */}
          </Col>
          <Col span={12}></Col>
        </Row>
      </Form.Item>

      {componentType === SpuServiceListSkusComponentTypesItem.PD ? (
        <Form.Item
          label="TiKV SKU Key"
          name="tikvSkuKey"
          rules={[{ required: true, message: 'Please input tikv sku key!' }]}
          labelCol={{
            style: {
              width: 110,
              flex: '0 0 auto'
            }
          }}
          wrapperCol={{
            style: {
              flex: 1,
              minWidth: 0
            }
          }}
        >
          <Select
            getPopupContainer={getSelectPopupContainer}
            mode="multiple"
            options={tikvDataSource?.map((v) => ({
              label: v.key,
              value: v.key
            }))}
            style={{ width: '100%' }}
            showSearch
            allowClear
          ></Select>
        </Form.Item>
      ) : (
        <></>
      )}
    </>
  )
}

export default SKUPage
