import { Group, Skeleton, Stack, Typography, openConfirmModal, notifier } from '@tidbcloud/uikit'
import { Form, FormRadioGroup, FormSwitch, FormTextInput } from '@tidbcloud/uikit/biz'
import React from 'react'
import { useForm } from 'react-hook-form'
import { useMutation, useQuery, useQueryClient } from 'react-query'

import { getErrorMessage } from 'dbaas/services/errorCodes'
import { eventTracking } from 'dbaas/utils/tracking'

import { useKeyVizContext } from '../utils/context'
import { FEATURE_NAME } from '../utils/helpers'
import { KeyVizConfig } from '../utils/type'

type FormValues = {
  enable: boolean
  policy: string
  policy_kv_separator: string
}

type SettingFormProps = {
  onClose: () => void
  keyVizConfig: KeyVizConfig
}

const SettingForm: React.FC<React.PropsWithChildren<SettingFormProps>> = ({ onClose, keyVizConfig }) => {
  const client = useQueryClient()
  const ctx = useKeyVizContext()
  const form = useForm({
    defaultValues: {
      enable: !(keyVizConfig?.auto_collection_disabled ?? true),
      policy: keyVizConfig.policy || 'db',
      policy_kv_separator: keyVizConfig.policy_kv_separator || '/'
    }
  })
  const { watch } = form
  const enableFeature = watch('enable')
  const policy = watch('policy')

  const { mutateAsync } = useMutation(async (config: KeyVizConfig) => {
    return ctx.ds.updateKeyVizConfig(config)
  })

  const onSubmit = async (data: FormValues) => {
    async function update() {
      const newConfig: KeyVizConfig = { ...keyVizConfig, ...data, auto_collection_disabled: !data.enable }
      try {
        await mutateAsync(newConfig)
        client.invalidateQueries(['keyviz', 'config', ctx.cfg.clusterId])
        onClose()
      } catch (e) {
        notifier.error(getErrorMessage(e))
      }
    }

    // return directly if status not change
    if (keyVizConfig.auto_collection_disabled && !data.enable) {
      onClose()
      return
    }

    let shouldUpdate = true
    // if disable the feature, show warning before confirming
    if (!keyVizConfig.auto_collection_disabled && !data.enable) {
      shouldUpdate = await new Promise((resolve, _reject) => {
        openConfirmModal({
          title: 'Disable Key Visualizer Feature',
          centered: true,
          children: (
            <Typography size="sm">
              Are you sure want to disable this feature? Current visual reports will be cleared.
            </Typography>
          ),
          labels: { confirm: 'Disable', cancel: 'Cancel' },
          confirmProps: { color: 'red' },
          onCancel: () => resolve(false),
          onConfirm: () => resolve(true)
        })
      })
    }

    if (shouldUpdate) {
      eventTracking(`${FEATURE_NAME} Update Setting`)
      await update()
    }
  }

  return (
    <Form<FormValues>
      form={form}
      onSubmit={onSubmit}
      onCancel={onClose}
      actionsProps={{
        confirmText: 'Save'
      }}
    >
      <Stack gap={8}>
        <FormSwitch name="enable" label="Enable Feature" />
        <Typography size="xs" color="dimmed">
          Whether Key Visualizer feature is enabled. When enabled, there will be small overhead.
        </Typography>
      </Stack>

      {enableFeature && (
        <>
          <FormRadioGroup
            label="Policy"
            name="policy"
            data={[
              { label: 'TiDB', value: 'db' },
              { label: 'Raw KV', value: 'kv' }
            ]}
          />

          {policy === 'kv' && <FormTextInput label="Separator" name="policy_kv_separator" />}
        </>
      )}
    </Form>
  )
}

export const Setting: React.FC<React.PropsWithChildren<{ onClose: () => void }>> = ({ onClose }) => {
  const ctx = useKeyVizContext()
  const { data: keyVizConfig } = useQuery(
    ['keyviz', 'config', ctx.cfg.clusterId],
    () => {
      return ctx.ds.getKeyVizConfig()
    },
    {
      refetchOnWindowFocus: false
    }
  )

  if (!keyVizConfig) {
    return (
      <Group gap="xs">
        <Skeleton height={10} />
        <Skeleton height={10} />
        <Skeleton height={10} width="70%" />
      </Group>
    )
  }

  return <SettingForm onClose={onClose} keyVizConfig={keyVizConfig} />
}
