import { TextFileUploadProps } from '@tidb-cloud/ui-components'
import { Alert, Button, Card, Divider, Group, Stack } from '@tidbcloud/uikit'
import { IconAlertCircle } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useState } from 'react'
import { useFormContext } from 'react-hook-form'

import { FormErrorMessage } from 'dbaas/components/Form'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import {
  useValidatePremiumMigrationMigrationTargetConn,
  useValidatePremiumMigrationSourceConn
} from 'dbaas/services/dataflow'
import { V1beta2PremiumDMConnType } from 'dbaas/services/dataflow/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import { eventTracking } from 'dbaas/utils/tracking'

import { FormJobName } from '../Step1/FormJobName'
import { FormSourceConnection } from '../Step1/FormSourceConnection'
import { FormTargetConnection } from '../Step1/FormTargetConnection'

import { buildPremiumConnProfile } from './helper'
export interface PremiumStep1FormData {
  name: string
  data_source: string
  connect_method: V1beta2PremiumDMConnType
  connect_method_display_name: string
  host?: string
  sink_endpoint_id?: string
  sink_endpoint_name?: string
  port: number
  ssl: boolean
  username: string
  password: string
  cluster_username: string
  cluster_password: string
  ssl_ca?: string
  ssl_cert?: string
  ssl_key?: string
  ssl_ca_value?: TextFileUploadProps['value']
  ssl_cert_value?: TextFileUploadProps['value']
  ssl_key_value?: TextFileUploadProps['value']
}

const Step1 = ({ onCancel, onFinish }: { onFinish: () => void; onCancel: () => void }) => {
  const tidb = useSharedTiDBContext()
  const { handleSubmit, getValues } = useFormContext<PremiumStep1FormData>()
  const [errorMessage, setErrorMessage] = useState('')
  const [loading, setLoading] = useState(false)
  const [validateConnectionError, setValidateConnectionError] = useState<{
    target: string
    source: string
  }>({
    target: '',
    source: ''
  })

  const validateSourceConnMutation = useValidatePremiumMigrationSourceConn()
  const validateTargetConnMutation = useValidatePremiumMigrationMigrationTargetConn()

  const onSubmit = async (data: PremiumStep1FormData) => {
    if (window.E2E_Test) {
      onFinish()
      return
    }

    if (data.ssl) {
      if (!data.ssl_ca_value && !data.ssl_cert_value && !data.ssl_key_value) {
        setErrorMessage('SSL certificate is needed if you use SSL.')
        return
      }

      if ((data.ssl_cert_value && !data.ssl_key_value) || (!data.ssl_cert_value && data.ssl_key_value)) {
        setErrorMessage('Client certificate and Client private key should be provided at the same time.')
        return
      }
    }

    setErrorMessage('')
    setLoading(true)
    setValidateConnectionError({ target: '', source: '' })

    const values = getValues() as PremiumStep1FormData
    const connProfile = buildPremiumConnProfile(values)
    const results = await Promise.allSettled([
      validateTargetConnMutation.mutateAsync({
        tidbId: tidb.tidbId!,
        data: {
          user: values.cluster_username,
          password: values.cluster_password
        }
      }),
      validateSourceConnMutation.mutateAsync({
        tidbId: tidb.tidbId!,
        data: { conn_profile: connProfile }
      })
    ])

    const errors: string[] = []

    if (results[0].status === 'rejected') {
      const reason = getErrorMessage(results[0].reason, true) || 'Failed to validate target connection'
      errors.push(reason)
      setValidateConnectionError((prev) => ({
        ...prev,
        target: reason
      }))
    }

    if (results[1].status === 'rejected') {
      const reason = getErrorMessage(results[1].reason, true) || 'Failed to validate source connection'
      errors.push(reason)
      setValidateConnectionError((prev) => ({
        ...prev,
        source: reason
      }))
    }

    setLoading(false)

    if (errors.length > 0) {
      return
    }

    eventTracking('Premium DM Step1 Validated')
    onFinish()
  }

  return (
    <Card p={0}>
      <form onSubmit={handleSubmit((values) => onSubmit(values as PremiumStep1FormData))}>
        <FormJobName />

        <Divider />

        <FormSourceConnection />

        <Divider />

        <FormTargetConnection region={tidb.regionDisplayName} id={tidb.tidbId} name={tidb.displayName} />

        <Divider />

        <Stack m={24}>
          {errorMessage && <FormErrorMessage message={errorMessage} autoScroll />}

          {validateConnectionError.target && (
            <Alert title="Connect to target failed" icon={<IconAlertCircle />} color="red">
              {validateConnectionError.target}
            </Alert>
          )}

          {validateConnectionError.source && (
            <Alert title="Connect to source failed" icon={<IconAlertCircle />} color="red">
              {validateConnectionError.source}
            </Alert>
          )}

          <Group justify="flex-end">
            <Button variant="default" type="button" onClick={onCancel}>
              Cancel
            </Button>
            <Button type="submit" loading={loading}>
              Validate Connection and Next
            </Button>
          </Group>
        </Stack>
      </form>
    </Card>
  )
}

export const PremiumDMStep1 = observer(Step1)
