import { Alert, Button, Card, Group, Loader, 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 { observer } from 'mobx-react'
import { useMemo, useState } from 'react'

import { ReasonHoverHint, type HoverHintReason } from 'dbaas/components/HoverHint/ReasonHoverHint'
import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import { useAccessDeniedHintReason } from 'dbaas/contexts/access-control'
import { getTidbStateToPassivePhrase } from 'dbaas/screens/NextGen/shared/model/tidb-state'
import {
  useLogRedactionPolicyServiceGetLogRedactionPolicy,
  useLogRedactionPolicyServiceUpdateLogRedactionPolicy
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'

import { SharedTiDB } from '../../shared/model/shared-tidb-state'

export const LogRedaction = observer(({ tidb }: { tidb: SharedTiDB }) => {
  const [opened, modalHandlers] = useDisclosure()
  const [errorMsg, setErrorMsg] = useState()

  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()

  const logRedactionQuery = useLogRedactionPolicyServiceGetLogRedactionPolicy(
    tidb?.tidbId || '',
    {
      orgId,
      projectId
    },
    {
      query: {
        enabled: !!(tidb?.tidbId && orgId && projectId) && tidb?.computed.ready,
        retry: 3
      }
    }
  )

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

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

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

  const logRedactionMutator = useLogRedactionPolicyServiceUpdateLogRedactionPolicy()
  const tidbReady = tidb?.computed.ready
  const passivePhrase = getTidbStateToPassivePhrase(tidb?.state)
  const { accessible, reason: accessDeniedReason } = useAccessDeniedHintReason({ id: 'TidbxLogRedactionAction' })
  const notReadyReason = useMemo<HoverHintReason>(
    () => ({
      id: 'notReady',
      when: !tidbReady,
      content: `This feature is unavailable while the instance is ${passivePhrase}.`
    }),
    [passivePhrase, tidbReady]
  )

  const handleSwitch = async () => {
    setErrorMsg(undefined)
    try {
      await logRedactionMutator.mutateAsync({
        tidbId: tidb.tidbId || '',
        data: { redactLog: !enabled },
        params: { orgId, projectId }
      })
      logRedactionQuery.refetch()
      modalHandlers.close()
    } catch (error) {
      setErrorMsg(getErrorMessage(error))
    }
  }

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

  return (
    <Card>
      <HeroComponent
        ready={
          !tidb.computed.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 ? 'green' : 'gray'}>{statusName}</DotBadge>}
          </Group>
          {logRedactionQuery.isLoading ? (
            <Loader size="sm" />
          ) : (
            <ReasonHoverHint reasons={[accessDeniedReason, notReadyReason]}>
              {({ matched }) => (
                <Button
                  color={accessible && tidbReady && enabled ? 'red' : undefined}
                  size="sm"
                  variant="default"
                  disabled={matched}
                  onClick={modalHandlers.open}
                >
                  {actionName}
                </Button>
              )}
            </ReasonHoverHint>
          )}
        </Group>
        <Typography variant="body-md">
          Sensitive information contained in SQL text in the instance 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/?plan=premium"
            target="_blank"
            rel="noreferrer"
          >
            User-Controlled Log Redaction
          </a>
          .
        </Typography>
        {!enabled && (
          <Alert color="yellow" icon={<IconAlertTriangle size={14} />}>
            Execution log redaction is currently disabled, resulting in TiDB logs being stored with sensitive
            information. This configuration is not recommended due to potential security risks.
          </Alert>
        )}
      </Stack>
      <Modal size={560} title={`${actionName} Execution Log Redaction`} opened={opened} onClose={handleClose}>
        <Stack>
          {enabled ? (
            <>
              <Typography variant="body-lg">
                Disabling log redaction causes TiDB logs to be stored with sensitive information, which is not
                recommended for security reasons. TiDB Cloud Support personnel may access these unredacted logs during
                required instance maintenance operations.
              </Typography>
              <Typography variant="body-lg">
                By disabling this feature, you acknowledge and accept the associated security risks.
              </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.
              </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>
  )
})
