import { Alert, Box, Button, Card, Divider, Group, Stack } from '@tidbcloud/uikit'
import { FormRadioGroup, FormRadioGroupProps } from '@tidbcloud/uikit/biz'
import { IconAlertCircle } from '@tidbcloud/uikit/icons'
import { omit } from 'lodash-es'
import { useEffect, useRef } from 'react'
import { useFormContext } from 'react-hook-form'

import { ChangefeedNames, useIsEditingChangefeed } from 'dbaas/features/Changefeed'
import { CloudProviderConst } from 'dbaas/features/Project'
import { FormGCS } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/step1/FormGCS'
import { FormKafka } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/step1/FormKafka'
import { FormMySQL } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/step1/FormMySQL'
import { FormPulsar } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/step1/FormPulsar'
import { FormS3 } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/step1/FormS3'
import type { CreateOrEditChangefeedFormData } from 'dbaas/screens/Changefeed/CreateOrEditChangefeedPremium/types'
import HeadLabel from 'dbaas/screens/ClustersV2/new/components/HeadLabel'
import { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { useConnectorServiceDescribeAdminProfile, useNgTestChangefeed } from 'dbaas/services/dataflow'
import { ConsoleapiChangefeedType, DataflowConnectorType } from 'dbaas/services/dataflow/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { sleep } from 'dbaas/utils/chore'
import { eventTracking } from 'dbaas/utils/tracking'

import { isTestEnv } from '../helper'

import { buildTestChangefeedStep1Payload } from './payloadBuilders'

export const ConfigureTarget = ({
  cluster,
  onFinish,
  onCancel
}: {
  cluster: SharedTiDB
  onFinish: () => void
  onCancel: () => void
}) => {
  const {
    store: { tenantData, activeProjectId }
  } = useStores()

  const methods = useFormContext<CreateOrEditChangefeedFormData>()
  const isEditing = useIsEditingChangefeed()
  const { clearErrors, handleSubmit, resetField, unregister, watch } = methods
  const type = watch('changefeed_type')
  const previousTypeRef = useRef(type)
  const isAliCloud = cluster.cloudProvider === CloudProviderConst.ALICLOUD

  const testChangefeedMutation = useNgTestChangefeed({
    mutation: { retry: false },
    request: { timeout: 120 * 1000 }
  })

  useEffect(() => {
    if (previousTypeRef.current === type) {
      return
    }

    previousTypeRef.current = type
    unregister('network_info.sink_endpoint_id')
    resetField('network_info.sink_endpoint_id')
    clearErrors('network_info.sink_endpoint_id')
    testChangefeedMutation.reset()
  }, [clearErrors, resetField, testChangefeedMutation, type, unregister])

  const { data: gcsProfile } = useConnectorServiceDescribeAdminProfile(
    tenantData.id,
    activeProjectId,
    cluster.tidbId!,
    {
      query: {
        enabled: type === ConsoleapiChangefeedType.GCS && !!cluster.tidbId,
        refetchOnWindowFocus: false
      }
    }
  )

  // const supportPulsarChangefeed = useSupportPulsarChangefeedPremium(cluster)
  const TARGETS: FormRadioGroupProps['data'] = [
    {
      label: ChangefeedNames.KAFKA,
      value: DataflowConnectorType.KAFKA,
      disabled: isEditing
    },
    {
      label: ChangefeedNames.MYSQL,
      value: DataflowConnectorType.MYSQL,
      disabled: isEditing
    },
    {
      label: isAliCloud ? 'Alibaba Cloud OSS' : ChangefeedNames.S3,
      value: DataflowConnectorType.S3,
      disabled: isEditing,
      show:
        ((cluster.computed.isEssentialV2 || cluster.computed.isPremium) &&
          cluster.cloudProvider === CloudProviderConst.AWS) ||
        ((cluster.computed.isEssentialV2 || cluster.computed.isPremium) && isAliCloud)
    }
    // {
    //   label: ChangefeedNames.PULSAR,
    //   value: DataflowConnectorType.PULSAR,
    //   disabled: isEditing,
    //   show: supportPulsarChangefeed
    // },
    // {
    //   label: ChangefeedNames.GCS,
    //   value: DataflowConnectorType.GCS,
    //   disabled: isEditing,
    //   show: cluster.cloudProvider === CloudProviderConst.GCP
    // }
  ]
    .filter((i) => i?.show !== false)
    .map((i) => omit(i, 'show'))

  const onSubmit = async (data: CreateOrEditChangefeedFormData) => {
    const payload = buildTestChangefeedStep1Payload(data)
    try {
      // Skip test connection in test environment
      if (isTestEnv()) {
        console.log(payload)
        onFinish()
        return
      }

      // test connection when create or edited password/secrets
      if (!isEditing) {
        await testChangefeedMutation.mutateAsync({
          clusterId: cluster?.tidbId!,
          data: payload
        })
      }

      await sleep(300)
      onFinish()
    } catch (_e) {
      eventTracking('Failed when precheck in kafka changefeed', {
        'Cluster Type': cluster.computed.clusterType
      })
    }
  }

  const error = testChangefeedMutation.error

  return (
    <Card p={0}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Stack m={24} gap={6}>
          <HeadLabel label="Destination" />

          <FormRadioGroup name="changefeed_type" data={TARGETS} sx={{ marginTop: 0 }} />
        </Stack>

        {type === DataflowConnectorType.KAFKA && <FormKafka cluster={cluster} />}
        {type === DataflowConnectorType.MYSQL && <FormMySQL cluster={cluster} />}
        {type === DataflowConnectorType.S3 && <FormS3 cluster={cluster} />}
        {type === DataflowConnectorType.GCS && <FormGCS gcp_account_id={gcsProfile?.gcp_account_id} />}
        {type === DataflowConnectorType.PULSAR && <FormPulsar cluster={cluster} />}

        <Divider />

        {error && (
          <Alert icon={<IconAlertCircle size={16} />} color="red" m={24}>
            <Box
              sx={{ wordBreak: 'break-all' }}
              dangerouslySetInnerHTML={{
                __html: getErrorMessage(error)
              }}
            />
          </Alert>
        )}

        <Group m={24} justify="flex-end">
          <Button
            variant="default"
            type="button"
            data-mp-event="Configure Target Cancel Button Clicked"
            onClick={onCancel}
          >
            Cancel
          </Button>
          <Button
            type="submit"
            data-mp-event="Configure Target Next Button Clicked"
            data-mp-plan="Premium"
            loading={testChangefeedMutation.isLoading}
          >
            Next
          </Button>
        </Group>
      </form>
    </Card>
  )
}
