import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'
import { Button, DatePicker, Form, Input, InputNumber, Select } from 'antd'
import { useMemo } from 'react'
import { useQuery } from 'react-query'

import { devopsInstance } from 'apiClient/custom-instance'

type SupportedVersionsResp = {
  versions?: Record<string, string[]>
}

const DEFAULT_SUPPORTED_VERSIONS = [
  '1.30',
  '1.31',
  '1.32',
  '1.33',
  '1.34',
  '1.35',
  '1.37'
]

type SelectorType =
  | 'none'
  | 'internal'
  | 'non_prod'
  | 'by_region'
  | 'by_tenant_ids'
  | 'by_project_ids'
  | 'by_tidb_cluster_ids'
  | 'by_k8s_names'

type PlanFormFieldsProps = {
  mode: 'create' | 'edit'
}

const PlanFormFields = ({ mode }: PlanFormFieldsProps) => {
  const form = Form.useFormInstance()
  const selectorType = (Form.useWatch('selector_type', form) ??
    'none') as SelectorType
  const cloudProvider = Form.useWatch('cloud_provider', form) as
    | string
    | undefined

  const {
    data: supportedVersionsResp,
    isLoading: supportedVersionsLoading,
    isError: supportedVersionsError
  } = useQuery(
    ['k8sUpgradeSupportedVersions'],
    async () => {
      const resp = await devopsInstance<SupportedVersionsResp>({
        url: '/api/v1/devops/cluster/k8sUpgradeSupportedVersions',
        method: 'GET'
      })
      return resp.data
    },
    {
      staleTime: 10 * 60 * 1000,
      enabled: mode === 'create'
    }
  )

  const eosVersionOptions = useMemo(() => {
    if (!cloudProvider) return []
    const versionsFromApi =
      supportedVersionsResp?.versions?.[cloudProvider] ?? []
    const versions =
      supportedVersionsError || versionsFromApi.length === 0
        ? DEFAULT_SUPPORTED_VERSIONS
        : versionsFromApi
    return versions.map((v) => ({ value: v, label: v }))
  }, [cloudProvider, supportedVersionsError, supportedVersionsResp?.versions])

  return (
    <>
      <Form.Item
        name="name"
        label="Name"
        rules={[{ required: true }]}
        style={{ width: 600 }}
      >
        <Input style={{ width: 280 }} />
      </Form.Item>
      {mode === 'create' && (
        <>
          <Form.Item
            name="cloud_provider"
            label="Cloud Provider"
            initialValue="aws"
            rules={[
              { required: true, message: 'Please select cloud provider' }
            ]}
            style={{ width: 600 }}
          >
            <Select
              style={{ width: 280 }}
              options={[
                { value: 'aws', label: 'AWS' },
                { value: 'gcp', label: 'GCP' }
              ]}
              onChange={() => {
                form.setFieldsValue({ eos_version: undefined })
              }}
            />
          </Form.Item>
          <Form.Item
            name="eos_version"
            label="EOS Version"
            rules={[{ required: true, message: 'Please select EOS version' }]}
            style={{ width: 600 }}
          >
            <Select
              style={{ width: 280 }}
              loading={supportedVersionsLoading}
              disabled={!cloudProvider}
              options={eosVersionOptions}
            />
          </Form.Item>
          <Form.Item
            name="eos_date"
            label="EOS Date"
            rules={[{ required: true, message: 'Please select EOS date' }]}
            style={{ width: 600 }}
          >
            <DatePicker style={{ width: 280 }} />
          </Form.Item>
        </>
      )}
      <Form.Item
        name="max_restart_times"
        label="Max Restart Times"
        rules={[{ required: mode === 'create' }]}
        style={{ width: 600 }}
      >
        <InputNumber min={0} style={{ width: 280 }} />
      </Form.Item>
      <Form.Item
        name="deadline"
        label="Deadline"
        rules={[{ required: true, message: 'Please select deadline' }]}
        style={{ width: 600 }}
      >
        <DatePicker showTime style={{ width: 280 }} />
      </Form.Item>
      <Form.Item
        name="trigger_time"
        label="Trigger Time"
        style={{ width: 600 }}
      >
        <DatePicker showTime style={{ width: 280 }} />
      </Form.Item>
      <Form.Item
        name="selector_type"
        label="Selector"
        initialValue="none"
        style={{ width: 600 }}
      >
        <Select
          style={{ width: 280 }}
          options={[
            { value: 'none', label: 'None' },
            { value: 'internal', label: 'Internal Clusters' },
            { value: 'non_prod', label: 'Non-prod Clusters' },
            { value: 'by_region', label: 'By Region' },
            { value: 'by_tenant_ids', label: 'By Tenant IDs' },
            { value: 'by_project_ids', label: 'By Project IDs' },
            { value: 'by_tidb_cluster_ids', label: 'By Cluster IDs' },
            { value: 'by_k8s_names', label: 'By K8s Names' }
          ]}
          onChange={(val: SelectorType) => {
            if (
              val !== 'by_tenant_ids' &&
              val !== 'by_project_ids' &&
              val !== 'by_tidb_cluster_ids' &&
              val !== 'by_k8s_names'
            ) {
              form.setFieldsValue({ selector_values: [] })
            }
          }}
        />
      </Form.Item>
      {selectorType === 'by_region' ? (
        <Form.Item
          name="selector_value"
          label="Selector Value"
          style={{ width: 600 }}
        >
          <Select
            style={{ width: 280 }}
            options={[
              { value: 'APAC', label: 'APAC' },
              { value: 'EMEA', label: 'EMEA' },
              { value: 'JAPAN', label: 'JAPAN' },
              { value: 'NA', label: 'NA' }
            ]}
          />
        </Form.Item>
      ) : selectorType === 'by_tenant_ids' ||
        selectorType === 'by_project_ids' ||
        selectorType === 'by_tidb_cluster_ids' ||
        selectorType === 'by_k8s_names' ? (
        <Form.List
          name="selector_values"
          rules={[
            {
              validator: async (_, values) => {
                if (Array.isArray(values) && values.filter(Boolean).length > 0)
                  return
                return Promise.reject(
                  new Error('Please add at least one selector value!')
                )
              }
            }
          ]}
        >
          {(fields, { add, remove }, { errors }) => (
            <Form.Item
              label="Selector Value"
              style={{ width: 600, marginBottom: 0 }}
            >
              <div style={{ width: 280 }}>
                {fields.map((field) => (
                  <div
                    key={field.key}
                    style={{
                      display: 'flex',
                      gap: 8,
                      marginBottom: 8,
                      alignItems: 'center'
                    }}
                  >
                    <Form.Item
                      {...field}
                      style={{ marginBottom: 0, flex: 1 }}
                      rules={[
                        { required: true, message: 'Please input a value!' }
                      ]}
                    >
                      <Input
                        onChange={() => {
                          form.validateFields(['selector_values'])
                        }}
                      />
                    </Form.Item>
                    <Button
                      aria-label="remove"
                      icon={<DeleteOutlined />}
                      onClick={() => remove(field.name)}
                    />
                  </div>
                ))}
                <Button
                  type="dashed"
                  icon={<PlusOutlined />}
                  onClick={() => add()}
                  block
                >
                  Add
                </Button>
                <Form.ErrorList errors={errors} />
              </div>
            </Form.Item>
          )}
        </Form.List>
      ) : null}
    </>
  )
}

export default PlanFormFields
