import { Badge, Code, HoverCard, SegmentedControl, notifier } from '@tidbcloud/uikit'
import {
  Anchor,
  ActionIcon,
  Alert,
  Button,
  CopyButton,
  Flex,
  Group,
  TextInput,
  Tooltip,
  Typography,
  Box,
  Menu,
  Modal,
  Card,
  Popover
} from '@tidbcloud/uikit'
import { Form, FormSelect, FormTextInput, FormNumberInput } from '@tidbcloud/uikit/biz'
import { ProTable, MRT_ColumnDef } from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import {
  IconCopy01,
  IconInfoCircle,
  IconDotsHorizontal,
  IconAlertCircle,
  IconClockSnooze,
  IconEdit05,
  IconTrash01
} from '@tidbcloud/uikit/icons'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useForm, useFormContext } from 'react-hook-form'

import TimeComponent from 'dbaas/components/TimeComponent'
import { useAccessCheck } from 'dbaas/contexts/access-control'
import { useRequestSupport } from 'dbaas/screens/HelpCenter/RequestSupport/helper'
import {
  useGetListApiKeys,
  createAPIKey,
  useDeleteApiKey,
  updateDataAppKey,
  useExpireApiKey,
  useExpireAllApiKeys
} from 'dbaas/services/dataservice'
import { DtoRbacApiKey } from 'dbaas/services/dataservice/interface'
import useStores from 'dbaas/stores/useStores'

import RoleAdditionalInfo from '../../common/RoleAdditionalInfo'
import { useDataApiContext } from '../../context'
import { ROLE_MAP, CHAT2QUERY_ROLE_MAP_KEY, ROLE_MAP_KEY_PROPS } from '../../helpers'
import { EXPIRE_TIPS_MAP, EXPIRE_TIPS_MAP_KEY } from '../../utils'

import { useStyles } from './index.styles'

const CreateFormItems = ({ value, type }: any) => {
  const { open: openSupport } = useRequestSupport()
  const { editApp } = useDataApiContext()
  const writeEnabled = useAccessCheck('ProjectDataServiceDataWrite')
  const [opened, { close, open }] = useDisclosure(false)
  const {
    store: { currentCluster, tenantData }
  } = useStores()
  const { setValue, watch, trigger, getValues } = useFormContext()
  const rateLimitTips = `Invalid rate limit, valid number is from 1 to ${editApp?.apikey_max_rpm ?? 1000}.`
  const defaultRole = type === 'chat2query' ? ROLE_MAP['Chat2Query Admin'] : ROLE_MAP['ReadOnly']

  const unitValue = watch('unit')
  const [expireMethod, setExpireMethod] = useState('Never Expires')

  useEffect(() => {
    setValue('name', value?.name || 'New Key')
    setValue('role', value?.role || defaultRole)
    setValue('rate_limit_rpm', value?.rate_limit_rpm || 100)
    if (!value?.ttl_in_min) {
      setExpireMethod('Never Expires')
    } else {
      setExpireMethod('Expires in')
    }
  }, [value])

  useEffect(() => {
    if (expireMethod === 'Expires in') {
      setValue('ttl_in_min', value?.ttl_in_min ?? '')
    }
  }, [expireMethod])

  useEffect(() => {
    if (getValues('ttl_in_min')) {
      trigger('ttl_in_min')
    }
  }, [unitValue])

  return (
    <>
      <FormTextInput
        label="API Key Description"
        placeholder="New API Key"
        maxLength={255}
        data-autofocus
        name="name"
        rules={{
          required: 'Please enter a description.'
        }}
      />

      <FormSelect
        my={16}
        name="role"
        label={
          <Flex align="center">
            {type === 'chat2query' ? 'Role for Chat2Query Endpoints' : 'Role'}
            <RoleAdditionalInfo type={type} />
          </Flex>
        }
        data={
          type === 'chat2query'
            ? [
                'Chat2Query Admin',
                'Chat2Query Data Summary Management',
                'Chat2Query SQL ReadOnly',
                'Chat2Query SQL ReadWrite'
              ].map((item) => ({
                label: item,
                value: ROLE_MAP[item as CHAT2QUERY_ROLE_MAP_KEY]
              }))
            : [
                {
                  label: 'ReadOnly',
                  value: ROLE_MAP['ReadOnly']
                },
                {
                  label: 'ReadAndWrite',
                  value: ROLE_MAP['ReadAndWrite'],
                  disabled: !writeEnabled
                }
              ].filter((item) => !item.disabled)
        }
      />

      {type !== 'chat2query' && (
        <FormNumberInput
          label={
            <Flex align="center">
              Rate Limit (requests/minute)
              <Popover position="top" width={400} withArrow shadow="md" opened={opened}>
                <Popover.Target>
                  <ActionIcon
                    aria-label="Rate Limit info"
                    color="carbon.8"
                    variant="transparent"
                    onMouseEnter={open}
                    onMouseLeave={close}
                  >
                    <IconInfoCircle size={14} />
                  </ActionIcon>
                </Popover.Target>

                <Popover.Dropdown>
                  <Typography variant="body-lg">
                    Set the rate limit for how many API requests can be made per minute with this key. Choose a value
                    between 1 and {editApp?.apikey_max_rpm ?? 1000}.
                  </Typography>
                </Popover.Dropdown>
              </Popover>
            </Flex>
          }
          min={1}
          max={editApp?.apikey_max_rpm ?? 1000}
          defaultValue={100}
          name="rate_limit_rpm"
          clampBehavior="none"
          autoComplete="off"
          rules={{
            required: rateLimitTips,
            min: {
              value: 1,
              message: rateLimitTips
            },
            max: {
              value: editApp?.apikey_max_rpm ?? 1000,
              message: rateLimitTips
            }
          }}
        />
      )}

      <Box>
        <Flex align="center" mt={16}>
          <Typography variant="title-md" fw={500}>
            API Key Expiry
          </Typography>
          <HoverCard withArrow shadow="md" position="top" zIndex={9999} width={400}>
            <HoverCard.Target>
              <ActionIcon aria-label="API Key Expiry info" color="carbon.8" variant="transparent">
                <IconInfoCircle size={14} />
              </ActionIcon>
            </HoverCard.Target>

            <HoverCard.Dropdown>
              <Typography>
                Set an expiration period for API keys to enhance security. Recommended for production environments. Use
                'Never Expires' for development and testing. After the specified period, expired API keys will no longer
                be valid and must be renewed or replaced.
              </Typography>
            </HoverCard.Dropdown>
          </HoverCard>
        </Flex>

        <SegmentedControl
          my={8}
          data={['Never Expires', 'Expires in']}
          value={expireMethod}
          onChange={(e) => {
            setExpireMethod(e)
            if (e === 'Expires in') {
              setTimeout(() => {
                setValue('unit', 'Days')
                setValue('ttl_in_min', 365)
              })
            }
          }}
        />
        {expireMethod === 'Never Expires' ? (
          <Typography variant="body-lg" c="carbon.7">
            Select 'Never Expire' to keep the API key valid indefinitely, suitable for development and testing
            environments where key expiration is not required.
          </Typography>
        ) : (
          <>
            <Typography variant="body-lg" c="carbon.7">
              Specify the duration for API key expiration. You can choose to set the expiry in minutes, days, or months.
            </Typography>
            <Flex gap={8} mt={8}>
              <FormNumberInput
                name="ttl_in_min"
                hideControls
                sx={{ flex: '1' }}
                placeholder={EXPIRE_TIPS_MAP[(unitValue ?? 'Minutes') as EXPIRE_TIPS_MAP_KEY].tips}
                clampBehavior="none"
                min={1}
                max={EXPIRE_TIPS_MAP[(unitValue ?? 'Minutes') as EXPIRE_TIPS_MAP_KEY].max}
                rules={{
                  required: 'Enter the duration for API key expiration',
                  min: {
                    value: 1,
                    message: 'The minimum value is 1'
                  },
                  max: {
                    value: EXPIRE_TIPS_MAP[(unitValue ?? 'Minutes') as EXPIRE_TIPS_MAP_KEY].max,
                    message: EXPIRE_TIPS_MAP[(unitValue ?? 'Minutes') as EXPIRE_TIPS_MAP_KEY].tips
                  }
                }}
              />

              <FormSelect
                name="unit"
                sx={{ width: 240 }}
                defaultValue={unitValue ?? 'Minutes'}
                data={['Days', 'Months', 'Minutes']}
                renderOption={({ option, checked, ...others }) => {
                  return (
                    <Flex {...others} align="center">
                      <Typography>{option.label}</Typography>
                      <Typography ml={8} variant="label-sm" fw={400} c="carbon.6">
                        (Max Allowed {EXPIRE_TIPS_MAP[option.label as EXPIRE_TIPS_MAP_KEY].max})
                      </Typography>
                    </Flex>
                  )
                }}
              ></FormSelect>
            </Flex>
          </>
        )}
      </Box>

      {type === 'chat2query' && (
        <Alert color="yellow" mt={16}>
          The limit of Chat2Query requests is 100 times per day per organization. For higher quota,
          <Anchor
            ml={4}
            fw={600}
            onClick={() => {
              openSupport({
                orgId: tenantData.id,
                cluster: currentCluster ?? undefined
              })
            }}
          >
            Contact support
          </Anchor>
        </Alert>
      )}
    </>
  )
}

const APIKeyList = ({ open, onClose }: { open?: boolean; onClose: (key: string) => void }) => {
  const { orgId, projectId, editApp, createApiKeyModalOpened } = useDataApiContext()
  const [opened, setOpened] = useState(false)
  const [isGenerating, setIsGenerating] = useState(false)
  const [bornKey, setBornKey] = useState('')
  const [publicKey, setPublicKey] = useState('')
  const editKey = useRef<DtoRbacApiKey | null>(null)
  const { classes } = useStyles()
  const [deleteModalOpened, setDeleteModalOpened] = useState(false)
  const [deletApi, setDeleteApi] = useState<DtoRbacApiKey | null>(null)
  const [apikeyDetail, setApikeyDetail] = useState<DtoRbacApiKey | null>(null)
  const [expireItemModalOpened, setExpireItemModalOpened] = useState(false)
  const [expireApi, setExpireApi] = useState<DtoRbacApiKey | null>(null)
  const [expireAllModalOpened, setExpireAllModalOpened] = useState(false)
  const formProps = useForm<{ confirmText: string }>({})
  const { watch } = formProps
  const confirmText = watch('confirmText')

  const { data, refetch } = useGetListApiKeys(orgId, projectId, `${editApp?.id}`, undefined, {
    query: {
      enabled: !!orgId && !!projectId && !!editApp?.id,
      refetchInterval: false,
      refetchOnWindowFocus: false
    }
  })

  const deleteMutation = useDeleteApiKey({
    mutation: {
      onSuccess: () => {
        refetch()
        setDeleteModalOpened(false)
      }
    }
  })

  useEffect(() => {
    setOpened(open ?? false)
  }, [open])

  useEffect(() => {
    setOpened(createApiKeyModalOpened ?? false)
  }, [createApiKeyModalOpened])

  useEffect(() => {
    if (!opened) {
      setTimeout(() => {
        editKey.current = null
      }, 10)
      refetch()
      onClose(bornKey ? `${publicKey}:${bornKey}` : '')

      setBornKey('')
      setPublicKey('')
    }
  }, [opened])

  const editKeyHandler = (keyItem: DtoRbacApiKey) => {
    editKey.current = keyItem
    setOpened(true)
  }

  const deleteKeyModal = () => {
    const apiKey = deletApi || {}
    return (
      <Modal
        centered
        trapFocus={false}
        title={
          <>
            Delete API Key
            <Box className={classes.keyContent}>{apiKey.access_key}</Box>
          </>
        }
        opened={deleteModalOpened}
        onClose={() => {
          setDeleteModalOpened(false)
          setDeleteApi(null)
        }}
      >
        <Typography variant="body-lg">
          Deleting the API Key will revoke your access to the Data App. This operation cannot be undone.
        </Typography>

        <Flex justify="flex-end" gap={16} mt={24}>
          <Button
            variant="default"
            onClick={() => {
              setDeleteModalOpened(false)
              setDeleteApi(null)
            }}
          >
            Cancel
          </Button>
          <Button
            color="red"
            variant="light"
            loading={deleteMutation.isLoading}
            onClick={async () => {
              deleteMutation.mutateAsync({
                orgId,
                projectId,
                appId: `${editApp?.id}`,
                apikeyId: `${apiKey.id}`,
                params: {
                  role: apiKey.role || ''
                }
              })
            }}
          >
            I understand, delete it
          </Button>
        </Flex>
      </Modal>
    )
  }

  const expireItemMutation = useExpireApiKey()
  const expireAllMutation = useExpireAllApiKeys()
  const expireApiItem = async () => {
    const apiKey = expireApi || {}

    await expireItemMutation.mutateAsync({
      orgId,
      projectId,
      appId: `${editApp?.id}`,
      apikeyId: `${apiKey.id}`
    })

    setExpireItemModalOpened(false)
    setExpireApi(null)
    refetch()
  }

  const expireAll = async () => {
    await expireAllMutation.mutateAsync({
      orgId,
      projectId,
      appId: `${editApp?.id}`
    })

    setExpireAllModalOpened(false)
    refetch()
  }

  const expireApiKeyModal = () => {
    return (
      <Modal
        centered
        size={480}
        trapFocus={false}
        title="Are you sure to expire this API key now?"
        opened={expireItemModalOpened}
        onClose={() => {
          setExpireItemModalOpened(false)
          setExpireApi(null)
        }}
      >
        <Typography variant="body-lg">
          This action will immediately expire the selected API key. Any applications using this key will cease to
          function and return a '401 Unauthorized request, API key is no longer valid' response.
        </Typography>
        <Typography mt={16} variant="body-lg">
          This action can not be undone.
        </Typography>

        <Flex justify="flex-end" align="center" gap={16} mt={32}>
          <Button
            variant="default"
            onClick={() => {
              setExpireItemModalOpened(false)
              setExpireApi(null)
            }}
          >
            Cancel
          </Button>
          <Button onClick={expireApiItem} loading={expireItemMutation.isLoading}>
            I understand, proceed
          </Button>
        </Flex>
      </Modal>
    )
  }

  const expireAllApiKeyModal = () => {
    return (
      <Modal
        centered
        size={480}
        trapFocus={false}
        title="Are you sure to expire all API keys?"
        opened={expireAllModalOpened}
        onClose={() => setExpireAllModalOpened(false)}
      >
        <Typography variant="body-lg">
          This action will immediately expire all API Keys. All applications using these keys will cease to function and
          return '401 Unauthorized request' responses. This action can not be undone and will disrupt business
          operations.
        </Typography>
        <Typography mb={16} mt={24} variant="body-lg">
          To proceed, please enter{' '}
          <Code fz={13} fw={600} bg="carbon.3">
            CONFIRM
          </Code>{' '}
          below.
        </Typography>

        <Form
          onCancel={() => setExpireAllModalOpened(false)}
          formMode="onChange"
          actionsProps={{
            confirmProps: {
              disabled: confirmText !== 'CONFIRM',
              loading: expireAllMutation.isLoading,
              color: 'red'
            },
            confirmText: 'Proceed'
          }}
          form={formProps}
          onSubmit={expireAll}
        >
          <FormTextInput
            name="confirmText"
            autoComplete="off"
            rules={{
              required: true,
              validate: (value) => value === 'CONFIRM' || 'Incorrect'
            }}
          />
        </Form>
      </Modal>
    )
  }

  const keyDescList = [
    {
      label: 'Description',
      key: 'name'
    },
    {
      label: 'Role',
      key: 'role'
    },
    {
      label: editApp?.app_type !== 'chat2query' ? 'Rate Limit' : '',
      key: 'rate_limit_rpm'
    },
    {
      label: 'Created by',
      key: 'created_by'
    },
    {
      label: 'Created at',
      key: 'created_at',
      type: 'time'
    },
    {
      label: 'Updated at',
      key: 'updated_at',
      type: 'time'
    }
  ]

  const ApiKeyDetail = () => {
    return (
      <Modal
        centered
        trapFocus={false}
        title="API Key Details"
        opened={!!apikeyDetail}
        size={600}
        zIndex={9999}
        onClose={() => setApikeyDetail(null)}
      >
        <TextInput
          label="Public Key"
          value={apikeyDetail?.access_key}
          disabled
          rightSection={
            <CopyButton value={apikeyDetail?.access_key || ''} timeout={2000}>
              {({ copied, copy }) => (
                <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="top">
                  <ActionIcon aria-label="Copy" color="carbon.8" variant="transparent" onClick={copy}>
                    <IconCopy01 size={14} />
                  </ActionIcon>
                </Tooltip>
              )}
            </CopyButton>
          }
          mb={16}
        />

        <TextInput label="Private Key" value={apikeyDetail?.secret_key} disabled mb={32} />

        {keyDescList
          .filter((desc) => desc.label)
          .map((desc, idx) => (
            <Flex align="center" mb={16} key={idx}>
              <Typography sx={{ width: 100 }} variant="label-lg">
                {desc.label}
              </Typography>
              <Box sx={{ flex: 1 }}>
                <Typography variant="body-lg">
                  {desc.label === 'Role' ? (
                    ROLE_MAP[apikeyDetail?.role as ROLE_MAP_KEY_PROPS]
                  ) : desc.type === 'time' ? (
                    <TimeComponent time={apikeyDetail?.[desc.key as keyof DtoRbacApiKey]!} />
                  ) : (
                    apikeyDetail?.[desc.key as keyof DtoRbacApiKey]
                  )}
                </Typography>
              </Box>
            </Flex>
          ))}
        <Alert mb={32} color="peacock">
          For security reason, a full private key is not displayed after creation.
        </Alert>

        <Flex justify="flex-end" direction="row">
          <Button variant="default" onClick={() => setApikeyDetail(null)} data-mp-event="mp-close-1691461016795">
            Close
          </Button>
        </Flex>
      </Modal>
    )
  }

  const columns = useMemo<MRT_ColumnDef<DtoRbacApiKey>[]>(
    () => [
      {
        header: 'Public Key',
        size: 80,
        accessorFn: (column) => (
          <Typography
            variant="label-sm"
            c="peacock.7"
            sx={{ cursor: 'pointer' }}
            onClick={() => setApikeyDetail(column)}
          >
            {column.access_key}
          </Typography>
        )
      },
      {
        header: 'Private Key',
        size: 80,
        accessorFn: (column) => (
          <Typography variant="body-sm">
            *...{(column.secret_key || '').substring((column.secret_key || '').length - 4)}
          </Typography>
        )
      },
      {
        header: 'Description',
        size: 100,
        accessorFn: (column) => (
          <Typography variant="body-sm" sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces' }}>
            {column.name}
          </Typography>
        )
      },
      {
        header: 'Status',
        size: 70,
        accessorFn: (column) => (
          <Badge color={(column.ttl_in_min ?? 0) >= 0 ? 'green' : 'red'} variant="dot" size="lg" sx={{ padding: 0 }}>
            <Typography variant="body-sm">{(column.ttl_in_min ?? 0) >= 0 ? 'Active' : 'Expired'}</Typography>
          </Badge>
        )
      },
      {
        header: 'Expiry(minutes)',
        size: 70,
        accessorFn: (column) => (
          <Typography variant="body-sm">
            {(column.ttl_in_min ?? 0) > 0 ? column.ttl_in_min : column.ttl_in_min === 0 ? 'Never Expires' : 'Expired'}
          </Typography>
        )
      },
      {
        header: 'Role',
        size: editApp?.app_type === 'chat2query' ? 220 : 80,
        accessorFn: (column) => (
          <Typography variant="body-sm">{column.role && ROLE_MAP[column.role as ROLE_MAP_KEY_PROPS]}</Typography>
        )
      },
      {
        header: 'Rate Limit',
        size: 60,
        accessorFn: (column) => <Typography variant="body-sm">{column.rate_limit_rpm}</Typography>
      },
      {
        header: 'Created Time',
        size: 140,
        accessorFn: (column) => (
          <Typography variant="body-sm">
            <TimeComponent time={column.created_at!} />
          </Typography>
        )
      },
      {
        header: 'Action',
        size: 50,
        accessorFn: (column) => (
          <Menu position="bottom-end" offset={4}>
            <Menu.Target>
              <ActionIcon aria-label={`${column.name} actions`} variant="subtle">
                <IconDotsHorizontal size={12} />
              </ActionIcon>
            </Menu.Target>
            <Menu.Dropdown>
              <Menu.Item
                disabled={(column.ttl_in_min ?? 0) < 0}
                data-mp-event="DataService api key edit button clicked"
                onClick={() => editKeyHandler(column)}
              >
                <Flex align="center" gap={8}>
                  <IconEdit05 size={16} />
                  Edit
                </Flex>
              </Menu.Item>
              <Menu.Item
                disabled={(column.ttl_in_min ?? 0) < 0}
                data-mp-event="DataService api key expire button clicked"
                onClick={() => {
                  setExpireItemModalOpened(true)
                  setExpireApi(column)
                }}
              >
                <Flex align="center" gap={8}>
                  <IconClockSnooze size={16} />
                  Expire Now
                </Flex>
              </Menu.Item>
              <Menu.Item
                data-mp-event="DataService api key delete button clicked"
                onClick={() => {
                  setDeleteModalOpened(true)
                  setDeleteApi(column)
                }}
              >
                <Flex align="center" gap={8}>
                  <IconTrash01 size={16} />
                  Delete
                </Flex>
                <Typography c="red"></Typography>
              </Menu.Item>
            </Menu.Dropdown>
          </Menu>
        )
      }
    ],
    [editApp?.app_type]
  )

  const ApiKeyInfo = () => {
    return (
      <>
        <Group align="flex-end">
          <TextInput
            label="Public Key"
            value={publicKey}
            disabled
            rightSection={
              <CopyButton value={publicKey} timeout={2000}>
                {({ copied, copy }) => (
                  <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="top">
                    <ActionIcon aria-label="Copy" size="md" color="carbon.8" variant="transparent" onClick={copy}>
                      <IconCopy01 size={16} />
                    </ActionIcon>
                  </Tooltip>
                )}
              </CopyButton>
            }
          />

          <TextInput
            label="Private Key"
            value={bornKey}
            name="name"
            disabled
            rightSection={
              <CopyButton value={bornKey} timeout={2000}>
                {({ copied, copy }) => (
                  <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="top">
                    <ActionIcon aria-label="Copy" size="md" color="carbon.8" variant="transparent" onClick={copy}>
                      <IconCopy01 size={16} />
                    </ActionIcon>
                  </Tooltip>
                )}
              </CopyButton>
            }
          />

          <CopyButton value={`${publicKey}:${bornKey}`} timeout={2000}>
            {({ copied, copy }) => (
              <Button variant="default" onClick={copy} data-mp-event="mp-copyall-1691461016797">
                {copied ? 'Copied' : 'Copy All'}
              </Button>
            )}
          </CopyButton>
        </Group>

        <Alert
          icon={
            <ActionIcon aria-label="Info" color="yellow.8" variant="transparent">
              <IconAlertCircle size={16} />
            </ActionIcon>
          }
          color="yellow"
          m="24px 0"
        >
          <Typography variant="body-lg" c="yellow.8" ml={8}>
            Your Data API key only gives you access to the data app.
            <br />
            Copy your <b>private key</b> and store it in a secure location. After you leave this page, the full private
            key will be unavailable.
          </Typography>
        </Alert>

        <Flex justify="flex-end" align="center" direction="row" wrap="wrap">
          <Button
            onClick={() => {
              setOpened(false)
            }}
            data-mp-event="mp-done-1691461016798"
          >
            Done
          </Button>
        </Flex>
      </>
    )
  }

  return (
    <Card mt={24} p={24}>
      <Flex align="center" justify="space-between" mb={12}>
        <Box sx={{ whiteSpace: 'break-spaces' }}>
          <Typography variant="title-md" mb={4}>
            Authentication
          </Typography>
          {editApp?.app_type !== 'dataapi' ? (
            <Typography variant="body-md">
              Provide Digest Authentication and Basic Authentication as authentication methods, and you can use an API
              key to authenticate your endpoints.
            </Typography>
          ) : (
            <Typography variant="body-md">
              Use API Keys for endpoint authentication through basic and digest mechanisms. Customize request quotas for
              each API Key to prevent HTTP 429 status codes. Discover further about API Keys in our{' '}
              <Anchor
                c="peacock.7"
                fw={400}
                target="_blank"
                href="https://docs.pingcap.com/tidbcloud/data-service-api-key"
              >
                documentation
              </Anchor>
              .
            </Typography>
          )}
        </Box>

        <Box>
          <Button
            size="xs"
            h={28}
            mr={8}
            variant="light"
            color="red"
            disabled={!data?.data?.length || !data?.data?.some((key) => (key.ttl_in_min ?? 0) >= 0)}
            data-mp-event="Expire all api key button clicked"
            onClick={() => setExpireAllModalOpened(true)}
          >
            Expire All
          </Button>
          <Button
            size="xs"
            variant="default"
            h={28}
            data-mp-event="Create api key button clicked"
            data-mp-source="dataapp"
            onClick={() => setOpened(true)}
          >
            Create API Key
          </Button>
        </Box>
      </Flex>

      {(data?.data || []).length > 0 && (
        <ProTable columns={columns} withBorder emptyMessage="No data" data={data?.data || []} />
      )}

      <Modal
        opened={opened}
        centered
        size={600}
        zIndex={10}
        trapFocus={false}
        onClose={() => setOpened(false)}
        closeOnClickOutside={false}
        closeOnEscape={false}
        // zIndex={9999}
        title={
          <Typography variant="title-lg">
            {editKey.current ? 'Update' : 'Create'} API Key
            {editKey.current ? <span className={classes.keyContent}>{editKey.current.access_key}</span> : null}
          </Typography>
        }
      >
        <Form
          withActions={false}
          layout="none"
          formMode="onChange"
          onSubmit={async (values: {
            name: string
            role: string
            rate_limit_rpm: number
            ttl_in_min: number
            unit: string
          }) => {
            setIsGenerating(true)
            const expiryUnit = EXPIRE_TIPS_MAP[(values.unit ?? 'Minutes') as EXPIRE_TIPS_MAP_KEY].unit
            if (editKey.current) {
              await updateDataAppKey(orgId, projectId, `${editApp?.id}`, `${editKey.current.id}`, {
                name: values.name,
                new_role: values.role,
                old_role: editKey.current.role || '',
                rate_limit_rpm: values.rate_limit_rpm || 100,
                old_ttl_in_min: editKey.current.ttl_in_min,
                new_ttl_in_min: values.ttl_in_min * expiryUnit
              })
              setIsGenerating(false)
              setOpened(false)
              refetch()
              return
            }
            const res = await createAPIKey(orgId, projectId, `${editApp?.id}`, {
              name: values.name,
              role: values.role,
              rate_limit_rpm: values.rate_limit_rpm || 100,
              ttl_in_min: values.ttl_in_min * expiryUnit
            })
            setIsGenerating(false)
            if (res.code === 200) {
              setBornKey(res.data?.secret_key || '')
              setPublicKey(res.data?.access_key || '')
            } else {
              notifier.error(res.message)
            }
          }}
        >
          {bornKey ? (
            <ApiKeyInfo />
          ) : (
            <>
              <CreateFormItems value={editKey.current} type={editApp?.app_type} />
              <Group justify="flex-end" mt="md">
                <Button variant="default" onClick={() => setOpened(false)} data-mp-event="mp-cancel-1691461016799">
                  Cancel
                </Button>
                <Button type="submit" loading={isGenerating} data-mp-event="mp--1691461016800">
                  {editKey.current ? 'Update' : 'Next'}
                </Button>
              </Group>
            </>
          )}
        </Form>
      </Modal>

      {deleteKeyModal()}

      {expireApiKeyModal()}

      {expireAllApiKeyModal()}

      <ApiKeyDetail />
    </Card>
  )
}

export default APIKeyList
