import { Alert, Box, Button, Divider, Flex, Modal, Typography } from '@tidbcloud/uikit'
import { Form, FormRadioGroup, FormSelect, FormSwitch } from '@tidbcloud/uikit/biz'
import { IconAlertTriangle, IconCheckCircle } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'

import { useDatabaseAuditLogServiceUpdateAuditLogSetting } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import { Nextgenv1beta2AuditLogSetting } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'

import {
  maxAgeDefaultOptions,
  maxAgeDisabledOptions,
  maxSizeDefaultOptions,
  LOG_FORMATS,
  LogSettingDefaultValues,
  normalizeLogFormat
} from './helper'

interface LogSettingsProps {
  opened: boolean
  isUpdate?: boolean
  tidbId?: string
  orgId: string
  onCancel: () => void
  onPrevious?: () => void
  config?: Nextgenv1beta2AuditLogSetting
  onConfirm?: () => Promise<void>
}

interface LogSettingsFormData extends Pick<Nextgenv1beta2AuditLogSetting, 'format'> {
  maxSizeMib: string
  maxAgeSecond: string
  redacted: boolean
}

export const LogSettingsModal = observer(
  ({ opened, isUpdate, onCancel, onPrevious, config, tidbId, orgId, onConfirm }: LogSettingsProps) => {
    const form = useForm<LogSettingsFormData>({
      defaultValues: {
        ...config,
        format: normalizeLogFormat(config?.format)
      }
    })

    const {
      store: { lastVisitLocation }
    } = useStores()
    const [loading, setLoading] = useState(false)

    const { watch } = form
    const redacted = watch('redacted')

    const { mutateAsync: updateAuditLogSetting, error } = useDatabaseAuditLogServiceUpdateAuditLogSetting()

    const formSelectBaseStyles = (theme) => ({
      root: {
        flex: 1
      },
      section: {
        '&[data-position="left"]': {
          color: theme.colors.carbon[9],
          borderRight: `1px solid ${theme.colors.carbon[4]}`,
          backgroundColor: theme.colors.carbon[2],
          marginRight: 10
        }
      },
      input: {
        flex: 1
      }
    })

    const maxAgeSeconds = [...maxAgeDisabledOptions, ...maxAgeDefaultOptions]

    const onSubmit = async (data: LogSettingsFormData) => {
      try {
        setLoading(true)
        await updateAuditLogSetting({
          tidbId: tidbId ?? '',
          data: isUpdate
            ? {
                rotationPolicy: {
                  maxAgeSecond: Number(data.maxAgeSecond),
                  maxSizeMib: Number(data.maxSizeMib)
                },
                format: data.format,
                enabled: true,
                unredacted: !data.redacted
              }
            : {
                format: data.format,
                unredacted: !data.redacted,
                rotationPolicy: {
                  maxAgeSecond: Number(data.maxAgeSecond),
                  maxSizeMib: Number(data.maxSizeMib)
                },
                enabled: true,
                storageSetting: {
                  bucketRegionId: config?.storageSetting?.bucketRegionId || '',
                  bucketUri: config?.storageSetting?.bucketUri || '',
                  cloudRoleIdentity: config?.storageSetting?.cloudRoleIdentity || ''
                }
              },
          params: { orgId, projectId: lastVisitLocation.projectId }
        })
        await onConfirm?.()
        form.reset()
        setLoading(false)
      } catch (_e) {
        setLoading(false)
      }
    }

    const onClose = () => {
      form.reset()
      onCancel()
    }

    useEffect(() => {
      if (config) {
        form.setValue('format', normalizeLogFormat(config.format))
        form.setValue(
          'maxSizeMib',
          config.rotationPolicy?.maxSizeMib && config.rotationPolicy?.maxSizeMib !== 0
            ? config.rotationPolicy?.maxSizeMib?.toString()
            : LogSettingDefaultValues.rotationPolicy.maxSizeMib.toString()
        )
        form.setValue(
          'maxAgeSecond',
          config.rotationPolicy?.maxAgeSecond?.toString() ??
            LogSettingDefaultValues.rotationPolicy.maxAgeSecond.toString()
        )
        form.setValue('redacted', !config.unredacted)
      }
    }, [config, form])

    return (
      <Modal
        opened={opened}
        onClose={onClose}
        closeOnClickOutside={false}
        title={isUpdate ? 'Edit Database Audit Log Settings' : 'Enable Database Audit Logging'}
        size={800}
      >
        <Form layout="none" form={form} withActions={false} onSubmit={onSubmit} onCancel={onClose} stopPropagation>
          <Box>
            {!isUpdate && (
              <Alert color="green" mb={24} icon={<IconCheckCircle />}>
                The connection is successful
              </Alert>
            )}

            <FormRadioGroup
              name="format"
              label="Log Format"
              data={LOG_FORMATS}
              rules={{ required: 'Log Format is required' }}
            />
            <Divider mx={-24} my={24} />
            <Typography variant="label-lg" mb={8}>
              Log File Rotation
            </Typography>
            <Flex gap={16}>
              <FormSelect
                name="maxSizeMib"
                leftSectionWidth={112}
                leftSection="File Size Limit"
                styles={(theme) => ({
                  ...formSelectBaseStyles(theme),
                  input: {
                    paddingLeft: 126
                  }
                })}
                rules={{
                  required: 'File Size Limit is required'
                }}
                data={maxSizeDefaultOptions}
              />

              <FormSelect
                name="maxAgeSecond"
                leftSectionWidth={132}
                leftSection="Rotation Interval"
                data={maxAgeSeconds}
                rules={{
                  required: 'Rotation Interval is required'
                }}
                styles={(theme) => ({
                  ...formSelectBaseStyles(theme),
                  input: {
                    paddingLeft: 146
                  }
                })}
              />
            </Flex>
            <Divider mx={-24} my={24} />

            <Flex justify="space-between" align="center" gap={32}>
              <Box>
                <Typography variant="label-lg">Log Redaction</Typography>
                <Typography variant="body-lg" mt={4}>
                  Sensitive information contained in SQL text in the instance log will be replaced by "?".
                </Typography>
                {!redacted && (
                  <Alert color="yellow" icon={<IconAlertTriangle size={16} />} mt={8}>
                    Database audit log redaction is currently disabled, resulting in log files pushed to the user's
                    cloud storage service containing sensitive information. This configuration is not recommended due to
                    potential security risks.
                  </Alert>
                )}
              </Box>

              <FormSwitch name="redacted" />
            </Flex>

            {error && <Form.ErrorMessage mt={8} message={getErrorMessage(error) || ''} />}

            <Divider mx={-24} my={24} />

            <Flex gap={16} justify="flex-end">
              <Button variant="default" onClick={onCancel}>
                Cancel
              </Button>

              {!isUpdate && (
                <Button variant="default" onClick={() => onPrevious?.()}>
                  Previous
                </Button>
              )}

              <Button type="submit" loading={loading}>
                Save {isUpdate ? '' : 'and Enable'}
              </Button>
            </Flex>
          </Box>
        </Form>
      </Modal>
    )
  }
)
