import { Button, Menu, Card, Group, Stack, Typography, Flex, Loader, Box } from '@tidbcloud/uikit'
import { DotBadge } from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { IconDotsHorizontal } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useMemo } 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 { useSharedTiDBContextSafe } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { TiDBPageShell } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/TiDBPageShell'
import {
  useDatabaseAuditLogServiceGetAuditLogSetting,
  useTidbServiceGetCloudProviderInfo
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import { V1beta1RegionCloudProvider } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'

import { FilterRules } from './filter-rules'
import { AuditlogDisabledModal } from './settings/DisableModal'
import AuditLogEditModal from './settings/EditModal'
import { LogSettingsModal } from './settings/LogSettings'

export const DBAuditLog = observer(() => {
  const [disableModalOpened, disableModalHandlers] = useDisclosure(false)
  const [logSettingsModalOpened, logSettingsModalHandlers] = useDisclosure(false)
  const [editModalOpened, editModalHandlers] = useDisclosure(false)
  const sharedTiDB = useSharedTiDBContextSafe()
  const {
    store: { lastVisitLocation }
  } = useStores()

  const {
    data: auditLogSetting,
    isLoading: isLoadingConfig,
    isFetched,
    isError,
    refetch
  } = useDatabaseAuditLogServiceGetAuditLogSetting(
    sharedTiDB?.tidbId ?? '',
    {
      orgId: lastVisitLocation.orgId,
      projectId: lastVisitLocation.projectId
    },
    {
      query: {
        enabled: !!sharedTiDB?.tidbId,
        refetchInterval: 1 * 60 * 1000,
        retry: 3
      }
    }
  )

  const { data: cloudProviderInfo } = useTidbServiceGetCloudProviderInfo(
    sharedTiDB?.tidbId ?? '',
    {
      orgId: lastVisitLocation.orgId,
      projectId: lastVisitLocation.projectId
    },
    {
      query: {
        enabled: !!(
          sharedTiDB?.tidbId &&
          lastVisitLocation.orgId &&
          lastVisitLocation.projectId &&
          sharedTiDB?.cloudProvider === V1beta1RegionCloudProvider.azure
        ),
        refetchOnWindowFocus: false
      }
    }
  )

  const enabled = auditLogSetting?.enabled ?? false
  const documentationPlan = sharedTiDB?.computed.isEssentialV2 ? 'essential' : 'premium'
  const documentationUrl = sharedTiDB?.computed.isEssentialV2
    ? 'https://docs.pingcap.com/tidbcloud/essential-database-audit-logging/'
    : 'https://docs.pingcap.com/tidbcloud/tidb-cloud-auditing-premium/'
  const tidbReady = sharedTiDB?.computed.ready ?? true
  const passivePhrase = getTidbStateToPassivePhrase(sharedTiDB?.state)
  const { accessible, reason: accessDeniedReason } = useAccessDeniedHintReason({ id: 'TidbxDBAuditLogSwitch' })
  const notReadyReason = useMemo<HoverHintReason>(
    () => ({
      id: 'notReady',
      when: !tidbReady,
      content: `This feature is unavailable while the instance is ${passivePhrase}.`
    }),
    [passivePhrase, tidbReady]
  )

  if (!sharedTiDB) {
    return null
  }

  return (
    <TiDBPageShell title="DB Audit Logging" wrapperProps={{ h: '100%' }}>
      <HeroComponent ready={isHeroQueryReady({ isFetched, isError })} />
      <Card p="xl">
        <Group justify="space-between" gap={48}>
          <Stack gap={4} sx={{ flex: 1 }}>
            <Group gap="md">
              <Typography variant="title-lg">Database Audit Logging</Typography>
              {!isLoadingConfig && (
                <DotBadge color={enabled ? 'green' : 'gray'}>{enabled ? 'Enabled' : 'Disabled'}</DotBadge>
              )}
            </Group>
            <Flex gap={4}>
              <Typography variant="body-lg" c="carbon.7">
                Track various behaviors and operations of database users.{' '}
                <a
                  href={`${documentationUrl}?plan=${documentationPlan}`}
                  target="_blank"
                  rel="noreferrer"
                  data-mp-event="Documentation Link Clicked"
                  data-mp-source="Audit Log"
                  data-mp-content="about user access and history"
                >
                  Learn more
                </a>
                .
              </Typography>
            </Flex>
          </Stack>

          {isLoadingConfig && <Loader size="sm" />}

          {!isLoadingConfig && enabled && (
            <Flex gap={8}>
              <ReasonHoverHint reasons={[accessDeniedReason, notReadyReason]}>
                {({ matched }) => (
                  <Button
                    size="sm"
                    variant="outline"
                    disabled={matched}
                    data-mp-event="DB Audit Logging Edit Config Button Clicked"
                    onClick={() => {
                      logSettingsModalHandlers.open()
                    }}
                  >
                    Settings
                  </Button>
                )}
              </ReasonHoverHint>

              <Menu>
                <Menu.Target>
                  <Button variant="outline" size="sm">
                    <Box c="carbon.8" component={IconDotsHorizontal} size={20} />
                  </Button>
                </Menu.Target>
                <Menu.Dropdown>
                  <Menu.Item
                    disabled={!accessible || !tidbReady}
                    data-mp-event="DB Audit Logging Storage Configuration Button Clicked"
                    onClick={() => {
                      editModalHandlers.open()
                    }}
                  >
                    Storage Configuration
                  </Menu.Item>

                  <Menu.Item
                    c="red"
                    disabled={!accessible || !tidbReady}
                    data-mp-event="DB Audit Logging Disable Config Button Click"
                    onClick={() => {
                      disableModalHandlers.open()
                    }}
                  >
                    Disable
                  </Menu.Item>
                </Menu.Dropdown>
              </Menu>
            </Flex>
          )}

          {!isLoadingConfig && !enabled && (
            <ReasonHoverHint reasons={[accessDeniedReason, notReadyReason]}>
              {({ matched }) => (
                <Button
                  size="sm"
                  disabled={matched}
                  data-mp-event="DB Audit Logging Enable Entrance Button Clicked"
                  onClick={() => {
                    editModalHandlers.open()
                  }}
                >
                  Enable
                </Button>
              )}
            </ReasonHoverHint>
          )}
        </Group>
      </Card>
      <AuditLogEditModal
        opened={editModalOpened}
        onClose={() => {
          editModalHandlers.close()
        }}
        tidb={sharedTiDB}
        orgId={lastVisitLocation.orgId}
        config={auditLogSetting}
        cloudProviderInfo={cloudProviderInfo}
      />
      <FilterRules tidbId={sharedTiDB.tidbId || ''} />
      <AuditlogDisabledModal
        opened={disableModalOpened}
        tidbId={sharedTiDB.tidbId || ''}
        onClose={disableModalHandlers.close}
      />
      <LogSettingsModal
        opened={logSettingsModalOpened}
        onCancel={logSettingsModalHandlers.close}
        isUpdate={true}
        tidbId={sharedTiDB.tidbId || ''}
        onConfirm={async () => {
          await refetch()
          logSettingsModalHandlers.close()
        }}
        orgId={lastVisitLocation.orgId}
        config={auditLogSetting}
      />
    </TiDBPageShell>
  )
})

export default DBAuditLog
