import { ActionIcon, Menu, Modal, Typography } from '@tidbcloud/uikit'
import { Form } from '@tidbcloud/uikit/biz'
import { IconDotsHorizontal } from '@tidbcloud/uikit/icons'
import React, { useState } from 'react'

import { deleteSqlUser, updateSqlUser } from 'dbaas/services/account'
import { CentralSqlUser, UpdateSqlUserBody } from 'dbaas/services/account/interface'
import useStores from 'dbaas/stores/useStores'

import { SQLUserFormModal } from './Edit'

interface DeleteModalProps {
  opened: boolean
  name: string
  onSubmit: () => Promise<void>
  onCancel: () => void
}

const DeleteModal: React.FC<React.PropsWithChildren<DeleteModalProps>> = ({ opened, onSubmit, name, onCancel }) => {
  return (
    <Modal
      opened={opened}
      onClose={onCancel}
      title={<>Delete SQL User</>}
      centered={true}
      size={500}
      styles={(theme) => ({ header: { borderBottom: `1px solid ${theme.colors.carbon[3]}` } })}
    >
      <Form
        onSubmit={onSubmit}
        onCancel={onCancel}
        actionsProps={{
          confirmText: 'I understand, delete the user.',
          confirmProps: { color: 'red', variant: 'light', 'data-mp-event': 'Confirm Delete SQL User' },
          cancelProps: { bg: 'carbon.2', 'data-mp-event': 'Cancel Delete SQL User' }
        }}
      >
        <Typography variant="action-md" c="carbon.9" mt={16} sx={{ wordBreak: 'break-all' }}>
          SQL User Name: {name}
        </Typography>
        <Typography variant="body-lg" mt={8} mb={16}>
          SQL User deletion is unrecoverable, are you sure to delete the user?
        </Typography>
      </Form>
    </Modal>
  )
}

export const SQLUserActions: React.FC<
  React.PropsWithChildren<{
    sqlUser: CentralSqlUser
    clusterId: string
    isServerless?: boolean
    token?: string
    onUpdate?: () => void
    onDelete?: () => void
  }>
> = ({ sqlUser, clusterId, isServerless, token, onDelete, onUpdate }) => {
  const [deletionVisible, setDeletionVisible] = useState(false)
  const [editFormVisible, setEditFormVisible] = useState(false)
  const {
    store: { tenantData, activeProjectId }
  } = useStores()

  const getUserName = (userName: string) => {
    return isServerless && token ? `${token}${userName}` : userName
  }

  const isRootUser = () => {
    return sqlUser.user_name === 'root' || sqlUser.user_name === `${token}root`
  }

  const handleDelete = async () => {
    await deleteSqlUser(tenantData.id, activeProjectId, clusterId, { user_name: sqlUser.user_name || '' })
    setDeletionVisible(false)
    onDelete?.()
  }

  const handleUpdate = async (data: UpdateSqlUserBody) => {
    await updateSqlUser(tenantData.id, activeProjectId, clusterId, {
      ...data,
      user_name: getUserName(data.user_name)
    })
    setEditFormVisible(false)
    onUpdate?.()
  }

  const isRoot = isRootUser()

  return (
    <div>
      <Menu>
        <Menu.Target>
          <ActionIcon
            aria-label={`${sqlUser.user_name} actions`}
            variant="subtle"
            size={32}
            data-testid="sql-users-row-actions"
          >
            <IconDotsHorizontal size={16} />
          </ActionIcon>
        </Menu.Target>
        <Menu.Dropdown>
          <Menu.Item
            data-mp-event="Edit SQL User Clicked"
            data-testid="sql-users-edit"
            onClick={() => {
              setEditFormVisible(true)
            }}
          >
            Edit
          </Menu.Item>
          <Menu.Item
            disabled={isRoot}
            data-mp-event="Delete SQL User Clicked"
            data-testid="sql-users-delete"
            onClick={() => {
              setDeletionVisible(true)
            }}
          >
            Delete
          </Menu.Item>
        </Menu.Dropdown>
      </Menu>
      <DeleteModal
        opened={deletionVisible}
        onCancel={() => setDeletionVisible(false)}
        name={sqlUser.user_name || ''}
        onSubmit={handleDelete}
      />
      <SQLUserFormModal
        title="Edit SQL User"
        type="update"
        namePrefix={isServerless ? token : undefined}
        entityName={isServerless ? 'instance' : 'cluster'}
        opened={editFormVisible}
        isRoot={isRoot}
        onClose={() => setEditFormVisible(false)}
        defaultValues={{
          user_name: sqlUser.user_name?.replace(token || '', '') || '',
          password: '',
          auth_method: sqlUser.auth_method,
          builtin_role: sqlUser.builtin_role || '',
          custom_role: sqlUser.custom_role || []
        }}
        clusterId={clusterId}
        onSubmit={handleUpdate}
      />
    </div>
  )
}
