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

import type { RegionUpdateRegionRequest } from 'apiClient/services/devops/interface'
import type { RegionRegion } from 'apiClient/services/devops/interface/regionRegion'

import {
  DefaultProviderIdentityItem,
  getDefaultProviderIdentities,
  normalizeDefaultProviderIdentities
} from '../defaultProviderIdentity'
import { REGION_STATE_OPTIONS, SERVICE_PLAN_BORDER_COLORS } from '../helper'
import { RegionWhiteListItem, getRegionWhiteLists } from '../regionWhiteList'

export interface UpdateRegionFormValues
  extends Omit<RegionUpdateRegionRequest, 'region_white_lists'> {
  display_name?: string
  enableOpenedTenantIds: boolean
  region_white_lists?: RegionWhiteListItem[]
  default_provider_identities?: DefaultProviderIdentityItem[]
}

export interface UpdateRegionFormProps {
  form: FormInstance<UpdateRegionFormValues>
  initialValues?: Partial<UpdateRegionFormValues>
  formProps?: Omit<FormProps<UpdateRegionFormValues>, 'form' | 'initialValues'>
}

const NEXTGEN_EXPANDABLE_SERVICE_PLANS = [
  'Premium',
  'Essential_V2',
  'Premium_Reserved'
]

export const buildUpdateRegionRequest = (
  values: UpdateRegionFormValues,
  changed: string
): RegionUpdateRegionRequest => {
  const normalizedRegionWhiteLists = (values.region_white_lists || [])
    .map((item) => {
      const servicePlan = item.service_plan?.trim()
      if (!servicePlan) {
        return undefined
      }
      const openedTenantIds = (item.opened_tenant_ids || [])
        .map((tenantId) => tenantId?.trim())
        .filter((tenantId): tenantId is string => Boolean(tenantId))
      return {
        service_plan: servicePlan,
        is_public: Boolean(item.is_public),
        opened_tenant_ids: openedTenantIds
      }
    })
    .filter(Boolean)

  const primaryRegionWhiteList = normalizedRegionWhiteLists[0]

  const request: RegionUpdateRegionRequest = {
    cloud_provider: values.cloud_provider,
    deploy_type: values.deploy_type,
    is_public: primaryRegionWhiteList?.is_public ?? values.is_public,
    logical_name: values.logical_name,
    reason: values.reason,
    region_state: values.region_state,
    service_address: values.service_address,
    service_plan: primaryRegionWhiteList?.service_plan || values.service_plan,
    changed: changed
  }

  if (primaryRegionWhiteList) {
    request.opened_tenant_ids = primaryRegionWhiteList.opened_tenant_ids
  } else 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
    }
  }

  if (normalizedRegionWhiteLists.length) {
    ;(request as any).region_white_lists = normalizedRegionWhiteLists
  }

  if (values.deploy_type === 'DEPLOY_TYPE_NEXTGEN') {
    ;(request as any).default_provider_identities =
      normalizeDefaultProviderIdentities(values.default_provider_identities)
  }

  return request
}

export const buildUpdateRegionInitialValues = (
  region: RegionRegion | null | undefined
): UpdateRegionFormValues => {
  const spec = region?.region
  const tenantIds = spec?.opened_tenant_ids?.filter(Boolean) ?? []
  const regionWhiteLists = getRegionWhiteLists(spec)
  const primaryWhiteList = regionWhiteLists[0]
  const defaultProviderIdentities = getDefaultProviderIdentities(region)
  const servicePlanOptions = regionWhiteLists.map(
    (item) => item.service_plan || ''
  )

  return {
    display_name: spec?.display_name,
    cloud_provider: spec?.cloud_provider_id,
    deploy_type: region?.deploy_type,
    is_public: Boolean(primaryWhiteList?.is_public ?? spec?.is_public),
    logical_name: spec?.logical_name,
    opened_tenant_ids:
      (primaryWhiteList?.opened_tenant_ids || tenantIds).length > 0
        ? primaryWhiteList?.opened_tenant_ids || tenantIds
        : undefined,
    default_provider_identities:
      region?.deploy_type === 'DEPLOY_TYPE_NEXTGEN'
        ? defaultProviderIdentities.map((item) => ({
            ...item,
            service_plan: item.service_plan || servicePlanOptions[0]
          }))
        : undefined,
    region_white_lists: regionWhiteLists,
    reason: '',
    region_state: spec?.state ?? undefined,
    service_address: spec?.service_address ?? undefined,
    service_plan: primaryWhiteList?.service_plan || spec?.service_plan,
    enableOpenedTenantIds:
      (primaryWhiteList?.opened_tenant_ids || tenantIds).length > 0
  }
}

export default function UpdateRegionForm({
  form,
  initialValues,
  formProps
}: UpdateRegionFormProps) {
  const { Text } = Typography
  const [selectedAddServicePlan, setSelectedAddServicePlan] = useState<
    string | undefined
  >(undefined)
  const mergedInitialValues = useMemo<UpdateRegionFormValues>(
    () => ({
      is_public: false,
      enableOpenedTenantIds: Boolean(initialValues?.opened_tenant_ids?.length),
      ...initialValues
    }),
    [initialValues]
  )

  useEffect(() => {
    form.setFieldsValue(mergedInitialValues)
  }, [form, mergedInitialValues])

  const enableOpenedTenantIds =
    Form.useWatch('enableOpenedTenantIds', form) ??
    mergedInitialValues.enableOpenedTenantIds
  const deployType =
    Form.useWatch('deploy_type', form) ?? mergedInitialValues.deploy_type
  const isNextgenDeployType = deployType === 'DEPLOY_TYPE_NEXTGEN'
  const regionWhiteLists =
    Form.useWatch('region_white_lists', form) ||
    mergedInitialValues.region_white_lists
  const useRegionWhiteListMode = Boolean(regionWhiteLists?.length)
  const currentServicePlan =
    Form.useWatch('service_plan', form) ?? mergedInitialValues.service_plan
  const currentServicePlans = useMemo(
    () =>
      (regionWhiteLists || [])
        .map((item) => item.service_plan?.trim())
        .filter((plan): plan is string => Boolean(plan)),
    [regionWhiteLists]
  )
  const whiteListColors = useMemo(
    () =>
      (regionWhiteLists || []).map((item) => {
        const plan = item.service_plan?.trim() || ''
        return SERVICE_PLAN_BORDER_COLORS[plan] || '#8c8c8c'
      }),
    [regionWhiteLists]
  )
  const hasByocServicePlan =
    currentServicePlans.includes('BYOC') ||
    currentServicePlan?.trim() === 'BYOC'
  const addActionButtonStyle = {
    height: 32,
    paddingInline: 12,
    fontSize: 14
  }
  const addableServicePlanOptions = useMemo(
    () =>
      hasByocServicePlan
        ? []
        : NEXTGEN_EXPANDABLE_SERVICE_PLANS.filter(
            (plan) => !currentServicePlans.includes(plan)
          ).map((plan) => ({ label: plan, value: plan })),
    [currentServicePlans, hasByocServicePlan]
  )

  useEffect(() => {
    if (!addableServicePlanOptions.length) {
      setSelectedAddServicePlan(undefined)
      return
    }
    if (
      selectedAddServicePlan &&
      addableServicePlanOptions.some(
        (option) => option.value === selectedAddServicePlan
      )
    ) {
      return
    }
    setSelectedAddServicePlan(addableServicePlanOptions[0].value)
  }, [addableServicePlanOptions, selectedAddServicePlan])

  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}
    >
      <Alert
        showIcon
        type="info"
        style={{ marginBottom: 16 }}
        message="Update scope"
        description="Please modify only the fields you intend to change. All other fields will remain unchanged."
      />

      <Card size="small" title="Basic Settings" style={{ marginBottom: 16 }}>
        <Row gutter={16}>
          <Col span={12}>
            <Form.Item
              label="Deploy Type"
              name="deploy_type"
              rules={[{ required: true, message: 'Deploy type is required' }]}
            >
              <Input
                readOnly
                bordered={false}
                style={{
                  background: 'transparent',
                  paddingInline: 0,
                  color: 'rgba(0, 0, 0, 0.88)',
                  cursor: 'default'
                }}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="Logical Name"
              name="logical_name"
              rules={[{ required: true, message: 'Logical name is required' }]}
            >
              <Input
                readOnly
                bordered={false}
                style={{
                  background: 'transparent',
                  paddingInline: 0,
                  color: 'rgba(0, 0, 0, 0.88)',
                  cursor: 'default'
                }}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="Cloud Provider"
              name="cloud_provider"
              rules={[
                { required: true, message: 'Cloud provider is required' }
              ]}
            >
              <Input
                readOnly
                bordered={false}
                style={{
                  width: '100%',
                  background: 'transparent',
                  paddingInline: 0,
                  color: 'rgba(0, 0, 0, 0.88)',
                  cursor: 'default'
                }}
              />
            </Form.Item>
          </Col>
          {!useRegionWhiteListMode && (
            <Col span={12}>
              <Form.Item
                label="Service Plan"
                name="service_plan"
                rules={[
                  { required: true, message: 'Service plan is required' }
                ]}
              >
                <Input
                  readOnly
                  bordered={false}
                  style={{
                    background: 'transparent',
                    paddingInline: 0,
                    color: 'rgba(0, 0, 0, 0.88)',
                    cursor: 'default'
                  }}
                />
              </Form.Item>
            </Col>
          )}
          <Col span={12}>
            <Form.Item
              label="Display Name"
              name="display_name"
              rules={[{ required: true, message: 'Display name is required' }]}
            >
              <Input
                readOnly
                bordered={false}
                style={{
                  background: 'transparent',
                  paddingInline: 0,
                  color: 'rgba(0, 0, 0, 0.88)',
                  cursor: 'default'
                }}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="Service Address"
              name="service_address"
              rules={[
                { required: true, message: 'Service address is required' }
              ]}
            >
              <Input placeholder="Regional service address" />
            </Form.Item>
          </Col>
          <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>
          {!useRegionWhiteListMode && (
            <Col span={12}>
              <Form.Item
                label="Is Public"
                name="is_public"
                valuePropName="checked"
              >
                <Switch checkedChildren="Public" unCheckedChildren="Private" />
              </Form.Item>
            </Col>
          )}
        </Row>
      </Card>

      <Card
        size="small"
        title="Service Plan Visibility"
        style={{ marginBottom: 16 }}
      >
        {useRegionWhiteListMode && (
          <>
            <Text type="secondary">
              Configure whether each service plan is public or private.
            </Text>
            <Divider style={{ margin: '12px 0' }} />
            <Form.List name="region_white_lists">
              {(whiteListFields, { add }) => (
                <>
                  {whiteListFields.map((whiteListField, index) => (
                    <WhiteListEditor
                      key={whiteListField.key}
                      fieldName={whiteListField.name}
                      color={whiteListColors[index] || '#8c8c8c'}
                    />
                  ))}
                  {isNextgenDeployType &&
                    addableServicePlanOptions.length > 0 && (
                      <Space align="start" style={{ marginBottom: 12 }}>
                        <Select
                          value={selectedAddServicePlan}
                          onChange={setSelectedAddServicePlan}
                          options={addableServicePlanOptions}
                          style={{ minWidth: 220 }}
                        />
                        <Button
                          type="dashed"
                          icon={<PlusOutlined />}
                          onClick={() => {
                            if (!selectedAddServicePlan) {
                              return
                            }
                            add({
                              service_plan: selectedAddServicePlan,
                              is_public: true,
                              opened_tenant_ids: []
                            })
                          }}
                        >
                          Add Service Plan
                        </Button>
                      </Space>
                    )}
                </>
              )}
            </Form.List>
          </>
        )}

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

        {!useRegionWhiteListMode && 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 />}
                    style={addActionButtonStyle}
                  >
                    Add Tenant ID
                  </Button>
                </Form.Item>
              </>
            )}
          </Form.List>
        )}
      </Card>

      {isNextgenDeployType && (
        <Card
          size="small"
          title="Default Provider Identities"
          style={{ marginBottom: 16 }}
        >
          <Text type="secondary">
            Define which provider identity to use for each service_plan +
            tenant_id pair.
          </Text>
          <Divider style={{ margin: '12px 0' }} />

          <Form.List name="default_provider_identities">
            {(fields, { add, remove }) => (
              <>
                {fields.length > 0 && (
                  <div
                    style={{
                      display: 'grid',
                      gridTemplateColumns:
                        'minmax(180px, 2fr) minmax(140px, 1fr) minmax(240px, 2fr) 32px',
                      columnGap: 12,
                      marginBottom: 8,
                      paddingInline: 4
                    }}
                  >
                    <Typography.Text type="secondary">
                      Service Plan
                    </Typography.Text>
                    <Typography.Text type="secondary">
                      Tenant ID
                    </Typography.Text>
                    <Typography.Text type="secondary">
                      Provider Identity
                    </Typography.Text>
                    <span />
                  </div>
                )}
                {fields.map(({ key, name, ...restField }) => (
                  <div
                    key={key}
                    style={{
                      display: 'grid',
                      gridTemplateColumns:
                        'minmax(180px, 2fr) minmax(140px, 1fr) minmax(240px, 2fr) 32px',
                      columnGap: 12,
                      alignItems: 'start'
                    }}
                  >
                    <div>
                      <Form.Item
                        {...restField}
                        name={[name, 'service_plan']}
                        rules={[
                          {
                            required: true,
                            message: 'Service plan is required'
                          }
                        ]}
                      >
                        <Select
                          options={currentServicePlans.map((plan) => ({
                            label: plan,
                            value: plan
                          }))}
                          placeholder="Service plan"
                        />
                      </Form.Item>
                    </div>
                    <div>
                      <Form.Item
                        {...restField}
                        name={[name, 'tenant_id']}
                        rules={[
                          { required: true, message: 'Tenant ID is required' }
                        ]}
                      >
                        <Input placeholder="0 for region default" />
                      </Form.Item>
                    </div>
                    <div>
                      <Form.Item
                        {...restField}
                        name={[name, 'identity']}
                        rules={[
                          {
                            required: true,
                            message: 'Provider identity is required'
                          }
                        ]}
                      >
                        <Input placeholder="e.g. aws_identity_xxx" />
                      </Form.Item>
                    </div>
                    <div style={{ textAlign: 'center', alignSelf: 'center' }}>
                      <Button
                        type="text"
                        danger
                        icon={<MinusCircleOutlined />}
                        aria-label="Remove default provider identity"
                        onClick={() => remove(name)}
                      />
                    </div>
                  </div>
                ))}
                <Form.Item>
                  <Button
                    type="dashed"
                    onClick={() =>
                      add({
                        service_plan: currentServicePlans[0],
                        tenant_id: '0',
                        identity: ''
                      })
                    }
                    icon={<PlusOutlined />}
                    style={addActionButtonStyle}
                  >
                    Add Default Provider Identity
                  </Button>
                </Form.Item>
              </>
            )}
          </Form.List>
        </Card>
      )}

      <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 updated"
        />
      </Form.Item>
    </Form>
  )
}

interface WhiteListEditorProps {
  fieldName: number
  color: string
}

function WhiteListEditor({ fieldName, color }: WhiteListEditorProps) {
  return (
    <div
      style={{
        border: '1px solid #E5E7EB',
        borderLeft: `4px solid ${color}`,
        borderRadius: 8,
        padding: 16,
        marginBottom: 12,
        background: '#fff'
      }}
    >
      <Row gutter={16}>
        <Col span={12}>
          <Form.Item
            label="Service Plan"
            name={[fieldName, 'service_plan']}
            rules={[
              {
                required: true,
                message: 'Service plan is required'
              }
            ]}
          >
            <Input
              readOnly
              bordered={false}
              style={{
                background: 'transparent',
                paddingInline: 0,
                color: 'rgba(0, 0, 0, 0.88)',
                cursor: 'default'
              }}
            />
          </Form.Item>
        </Col>
        <Col span={12}>
          <Form.Item label="Visibility" style={{ marginBottom: 24 }}>
            <Space size={8} align="center">
              <Form.Item
                name={[fieldName, 'is_public']}
                valuePropName="checked"
                noStyle
              >
                <Switch />
              </Form.Item>
              <Form.Item noStyle shouldUpdate>
                {({ getFieldValue }) => {
                  const isPublic =
                    getFieldValue([
                      'region_white_lists',
                      fieldName,
                      'is_public'
                    ]) ?? true
                  return (
                    <Typography.Text>
                      {isPublic ? 'Public' : 'Private'}
                    </Typography.Text>
                  )
                }}
              </Form.Item>
            </Space>
          </Form.Item>
        </Col>
      </Row>

      <Form.Item noStyle shouldUpdate>
        {({ getFieldValue }) => {
          const isPublic =
            getFieldValue(['region_white_lists', fieldName, 'is_public']) ??
            true
          if (isPublic) {
            return null
          }

          return (
            <Form.List name={[fieldName, 'opened_tenant_ids']}>
              {(tenantFields, { add, remove }) => (
                <>
                  {tenantFields.map((tenantField) => (
                    <Row gutter={16} align="middle" key={tenantField.key}>
                      <Col span={22}>
                        <Form.Item
                          name={[tenantField.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(tenantField.name)}
                        />
                      </Col>
                    </Row>
                  ))}
                  <Form.Item>
                    <Button
                      type="dashed"
                      onClick={() => add('')}
                      icon={<PlusOutlined />}
                      style={{ height: 32, paddingInline: 12, fontSize: 14 }}
                    >
                      Add Tenant ID
                    </Button>
                  </Form.Item>
                </>
              )}
            </Form.List>
          )
        }}
      </Form.Item>
    </div>
  )
}
