import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import { Button, Col, Form, Input, Row, Select, Switch } from 'antd'
import type { FormInstance, FormProps } from 'antd'
import { useEffect, useMemo } from 'react'

import type { RegionRegisterRegionRequest } from 'apiClient/services/devops/interface'

import {
  REGION_STATE_OPTIONS,
  getCloudProviderOptions,
  getServicePlanOptions
} from '../helper'

const sanitize = (value?: string) => value?.trim() || undefined
const sanitizeRequired = (value?: string) => value?.trim() || ''

export interface RegisterRegionFormValues extends RegionRegisterRegionRequest {
  enableOpenedTenantIds: boolean
}

interface RegisterRegionFormProps {
  deployType: RegionRegisterRegionRequest['deploy_type']
  form: FormInstance<RegisterRegionFormValues>
  initialValues?: Partial<RegisterRegionFormValues>
  formProps?: Omit<
    FormProps<RegisterRegionFormValues>,
    'form' | 'initialValues'
  >
}

export const buildRegisterRegionRequest = (
  values: RegisterRegionFormValues
): RegionRegisterRegionRequest => {
  const request: RegionRegisterRegionRequest = {
    cloud_provider: sanitizeRequired(values.cloud_provider),
    deploy_type: sanitizeRequired(values.deploy_type),
    display_name: sanitizeRequired(values.display_name),
    is_public: Boolean(values.is_public),
    logical_region_name: sanitizeRequired(values.logical_region_name),
    region_name: sanitizeRequired(values.region_name),
    region_state: sanitizeRequired(values.region_state),
    reason: sanitizeRequired(values.reason),
    service_address: sanitizeRequired(values.service_address),
    service_plan: sanitizeRequired(values.service_plan)
  }

  const backupTime = sanitize(values.default_backup_time)
  if (backupTime) {
    request.default_backup_time = backupTime
  }

  if (values.enableOpenedTenantIds && values.opened_tenant_ids?.length) {
    const tenantIds = values.opened_tenant_ids
      .map((tenantId) => tenantId?.trim())
      .filter((tenantId): tenantId is string => Boolean(tenantId))
    if (tenantIds.length) {
      request.opened_tenant_ids = tenantIds
    }
  }

  return request
}

export default function RegisterRegionForm({
  deployType,
  form,
  initialValues,
  formProps
}: RegisterRegionFormProps) {
  const mergedInitialValues = useMemo(
    () => ({
      is_public: false,
      enableOpenedTenantIds: Boolean(initialValues?.opened_tenant_ids?.length),
      ...initialValues,
      deploy_type: deployType
    }),
    [initialValues, deployType]
  )
  const cloudProviderOptions = useMemo(
    () => getCloudProviderOptions(deployType),
    [deployType]
  )
  const servicePlanOptions = useMemo(
    () => getServicePlanOptions(deployType),
    [deployType]
  )

  useEffect(() => {
    form.setFieldsValue({ deploy_type: deployType })
  }, [deployType, form])

  useEffect(() => {
    if (!cloudProviderOptions.length) {
      return
    }
    const currentProvider = form.getFieldValue('cloud_provider')
    const isValidOption = cloudProviderOptions.some(
      (option) => option.value === currentProvider
    )
    if (currentProvider && !isValidOption) {
      form.setFieldsValue({ cloud_provider: undefined })
    }
  }, [cloudProviderOptions, form])

  useEffect(() => {
    if (!servicePlanOptions.length) {
      return
    }
    const currentServicePlan = form.getFieldValue('service_plan')
    const isValidServicePlan = servicePlanOptions.some(
      (option) => option.value === currentServicePlan
    )
    if (currentServicePlan && !isValidServicePlan) {
      form.setFieldsValue({ service_plan: undefined })
    }
  }, [form, servicePlanOptions])

  const enableOpenedTenantIds =
    Form.useWatch('enableOpenedTenantIds', form) ??
    Boolean(mergedInitialValues.enableOpenedTenantIds)
  const handleOpenedTenantToggle = (checked: boolean) => {
    if (!checked) {
      form.setFieldsValue({ opened_tenant_ids: undefined })
      return
    }
    const currentValue = form.getFieldValue('opened_tenant_ids') as
      | string[]
      | undefined
    if (!currentValue || currentValue.length === 0) {
      form.setFieldsValue({ opened_tenant_ids: [''] })
    }
  }

  return (
    <Form
      layout="vertical"
      form={form}
      initialValues={mergedInitialValues}
      {...formProps}
    >
      <Form.Item label="Deploy Type" name="deploy_type">
        <Input disabled />
      </Form.Item>

      <Form.Item
        label="Display Name"
        name="display_name"
        rules={[{ required: true, message: 'Display name is required' }]}
      >
        <Input placeholder="The display name of the region" />
      </Form.Item>
      <Form.Item
        label="Region Name"
        name="region_name"
        rules={[{ required: true, message: 'Region name is required' }]}
      >
        <Input placeholder="The region name in global service, like `AWS_US_EAST_2`, `GCP_ASIA_EAST1`" />
      </Form.Item>

      <Form.Item
        label="Logical Region Name"
        name="logical_region_name"
        rules={[{ required: true, message: 'Logical region name is required' }]}
      >
        <Input placeholder="Logic region name, such as cn-north-1" />
      </Form.Item>

      <Row gutter={16}>
        <Col span={12}>
          <Form.Item
            label="Cloud Provider"
            name="cloud_provider"
            rules={[{ required: true, message: 'Cloud provider is required' }]}
          >
            <Select
              placeholder="Select cloud provider"
              options={cloudProviderOptions}
              disabled={!cloudProviderOptions.length}
            />
          </Form.Item>
        </Col>
        <Col span={12}>
          <Form.Item
            label="Service Plan"
            name="service_plan"
            rules={[{ required: true, message: 'Service plan is required' }]}
          >
            <Select
              placeholder="Select service plan"
              options={servicePlanOptions}
              disabled={!servicePlanOptions.length}
            />
          </Form.Item>
        </Col>
      </Row>

      <Form.Item
        label="Service Address"
        name="service_address"
        rules={[{ required: true, message: 'Service address is required' }]}
      >
        <Input placeholder="Regional service address" />
      </Form.Item>

      <Row gutter={16}>
        <Col span={12}>
          <Form.Item
            label="State"
            name="region_state"
            rules={[{ required: true, message: 'Region state is required' }]}
          >
            <Select placeholder="Select state" options={REGION_STATE_OPTIONS} />
          </Form.Item>
        </Col>

        <Col span={12}>
          <Form.Item label="Is Public" name="is_public" valuePropName="checked">
            <Switch checkedChildren="Public" unCheckedChildren="Private" />
          </Form.Item>
        </Col>
      </Row>

      <Form.Item label="Backup Time (UTC)" name="default_backup_time">
        <Input placeholder="Cluster's default auto backup time in this region(dataflow-service), such as 10:00" />
      </Form.Item>

      <Form.Item
        label="Open Tenant IDs"
        name="enableOpenedTenantIds"
        valuePropName="checked"
      >
        <Switch
          checkedChildren="Limited"
          unCheckedChildren="All Tenants"
          onChange={handleOpenedTenantToggle}
        />
      </Form.Item>

      {enableOpenedTenantIds && (
        <Form.List name="opened_tenant_ids">
          {(fields, { add, remove }) => (
            <>
              {fields.map(({ key, name, ...restField }) => (
                <Row gutter={16} align="middle" key={key}>
                  <Col span={22}>
                    <Form.Item
                      {...restField}
                      name={name}
                      rules={[
                        {
                          required: true,
                          message: 'Tenant ID is required'
                        }
                      ]}
                    >
                      <Input placeholder="Enter tenant ID" />
                    </Form.Item>
                  </Col>
                  <Col span={2} style={{ textAlign: 'center' }}>
                    <Button
                      type="text"
                      danger
                      icon={<MinusCircleOutlined />}
                      aria-label="Remove tenant ID"
                      onClick={() => remove(name)}
                    />
                  </Col>
                </Row>
              ))}
              <Form.Item>
                <Button
                  type="dashed"
                  onClick={() => add('')}
                  icon={<PlusOutlined />}
                  size="small"
                >
                  Add Tenant ID
                </Button>
              </Form.Item>
            </>
          )}
        </Form.List>
      )}

      <Form.Item
        label="Reason"
        name="reason"
        rules={[{ required: true, message: 'Reason is required' }]}
      >
        <Input.TextArea
          rows={4}
          placeholder="Describe why this region needs to be registered"
        />
      </Form.Item>
    </Form>
  )
}
