import { Alert, Button, Card, Group, Modal, Stack, Typography } from '@tidbcloud/uikit'
import { DotBadge } from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { IconAlertTriangle } from '@tidbcloud/uikit/icons'
import { useState } from 'react'

import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import { AccessDeniedHoverHint } from 'dbaas/contexts/access-control/ui/AccessDeniedHoverHint'
import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import {
  useClusterServiceGetLogRedactionPolicy,
  useClusterServiceUpdateLogRedactionPolicy
} from 'dbaas/services/api-clients/v2023/dedicated/v1beta1'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

export const LogRedaction = ({ cluster }: { cluster: SharedCluster }) => {
  const [opened, modalHandlers] = useDisclosure()

  const [errorMsg, setErrorMsg] = useState()

  const {
    store: {
      tenantData: { id: orgId },
      activeProjectId: projectId
    }
  } = useStores()

  const logRedactionQuery = useClusterServiceGetLogRedactionPolicy(cluster.id, { orgId, projectId })

  const enabled = logRedactionQuery.data?.redactLog ?? false

  const statusName = enabled ? 'Enabled' : 'Disabled'

  const actionName = enabled ? 'Disable' : 'Enable'

  const logRedactionMutator = useClusterServiceUpdateLogRedactionPolicy()

  const handleSwitch = async () => {
    setErrorMsg(undefined)
    try {
      await logRedactionMutator.mutateAsync({
        clusterId: cluster.id,
        data: { redactLog: !enabled },
        params: { orgId, projectId }
      })
      eventTracking(`${enabled ? 'Disable' : 'Enable'} Log Redaction`, {
        clusterId: cluster.id,
        orgId
      })
      logRedactionQuery.refetch()
      modalHandlers.close()
    } catch (error) {
      setErrorMsg(getErrorMessage(error))
    }
  }

  const handleClose = () => {
    setErrorMsg(undefined)
    modalHandlers.close()
  }

  return (
    <Card>
      <HeroComponent
        ready={isHeroQueryReady({ isFetched: logRedactionQuery.isFetched, isError: logRedactionQuery.isError })}
      />
      <Stack gap="xs">
        <Group justify="space-between">
          <Group gap="xs">
            <Typography variant="title-lg">Execution Log Redaction</Typography>
            {!logRedactionQuery.isLoading && <DotBadge color={enabled ? 'peacock' : 'gray'}>{statusName}</DotBadge>}
          </Group>
          {!logRedactionQuery.isLoading && (
            <AccessDeniedHoverHint id="ClusterSecurityAction">
              {({ accessible }) => (
                <Button
                  disabled={!accessible}
                  color={enabled ? 'red' : undefined}
                  size="xs"
                  variant="default"
                  onClick={modalHandlers.open}
                >
                  {actionName}
                </Button>
              )}
            </AccessDeniedHoverHint>
          )}
        </Group>
        <Typography variant="body-md">
          Sensitive information contained in SQL text in the cluster log will be replaced by "?". It will affect SQL
          analysis functions such as SQL Statement and Slow Query. Learn more about{' '}
          <a href="https://docs.pingcap.com/tidbcloud/tidb-cloud-log-redaction" target="_blank" rel="noreferrer">
            User-Controlled Log Redaction
          </a>
          .
        </Typography>
        {!enabled && (
          <Alert color="yellow" icon={<IconAlertTriangle size={14} />}>
            Disabling log redaction may expose sensitive information and increase the risk of data leakage.
          </Alert>
        )}
      </Stack>
      <Modal size={560} title={`${actionName} Execution Log Redaction`} opened={opened} onClose={handleClose}>
        <Stack>
          {enabled ? (
            <>
              <Typography variant="body-lg">
                After disabling log redaction, TiDB logs will be recorded in plain text. Support personnel may access
                these plain text log information when performing necessary cluster maintenance operations.
              </Typography>
              <Typography variant="body-lg">
                Therefore, this may cause the risk of log data leakage. If you decide to disable log redaction, it means
                that you are willing to accept this risk.
              </Typography>
              <Typography variant="body-lg">Are you sure you want to disable execution log redaction?</Typography>
            </>
          ) : (
            <>
              <Typography variant="body-lg">
                After enabling log redaction, sensitive information in TIDB logs will be hidden. This can improve data
                security. Are you sure you want to enable execution log redaction?
              </Typography>
              <Typography variant="body-lg">
                However, this may be disadvantageous for scenarios such as log analysis and SQL tuning.{' '}
              </Typography>
              <Typography variant="body-lg">Are you sure you want to enable execution log redaction?</Typography>
            </>
          )}
          <Alert color="yellow" icon={<IconAlertTriangle size={14} />}>
            After changing the setting, please reconnect to the database. The new setting will take effect automatically
            on your new connection.
          </Alert>
        </Stack>
        {errorMsg && (
          <Alert color="red" mt="md">
            {errorMsg}
          </Alert>
        )}
        <Group justify="flex-end" mt="md">
          <Button variant="default" onClick={handleClose}>
            Cancel
          </Button>
          <Button
            variant={enabled ? 'default' : 'filled'}
            color={enabled ? 'red' : undefined}
            loading={logRedactionMutator.isLoading}
            onClick={handleSwitch}
          >
            {actionName}
          </Button>
        </Group>
      </Modal>
    </Card>
  )
}
