import { CodeBlock } from '@tidbcloud/uikit/biz'
import { Button, Table, Modal, message } from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { useCallback, useMemo, useState } from 'react'

import {
  iAMServiceGenerateAPIKey,
  iAMServiceListAPIKeys
} from 'apiClient/services/core-server'
import { V1APIKey } from 'apiClient/services/core-server/interface'
import ModalForm from 'components/ModalForm'
import SearchBar from 'components/SearchBar'
import { useTable, ListToolBar } from 'components/Table'
import { showErrorModal, toListDataResponse } from 'pages/IAM/utils'
import { toLocal } from 'utils/time'

import CreateAPIKeyForm, {
  CreateAPIKeyFormType
} from './APIKey/Forms/CreateAPIKeyForm'

export default function APIKeys() {
  const [searchParams, setSearchParams] = useState<{ nameLike?: string }>({
    nameLike: undefined
  })

  const [createAPIKey, setCreateAPIKey] = useState(false)
  const [createdAPIKeyVisible, setCreatedAPIKeyVisible] = useState(false)
  const [createdAPIKey, setCreatedAPIKey] = useState('')

  const getData = (params?: Partial<PageInfo>) =>
    iAMServiceListAPIKeys({
      page: params?.page,
      perPage: params?.pageSize,
      nameLike: searchParams.nameLike
    }).then((response) => toListDataResponse(response, (data) => data.apiKeys))

  const { dataSource, loading, reload, paginationProps, onTableChange } =
    useTable<ListData<V1APIKey>>(getData, [], {
      pagination: true
    })

  const columns: ColumnsType<V1APIKey> = [
    {
      title: 'Name',
      render: (_: any, record) => {
        return <a href={'/iam/entity/apikeys/' + record.name}>{record.name}</a>
      }
    },
    {
      title: 'Comment',
      render: (_: any, record) => {
        return record.comment
      }
    },
    {
      title: 'Created At',
      render: (_: any, record) => {
        return toLocal(record?.createdAt)
      }
    }
  ]

  const onSearch = (query: { email?: string }) => {
    let newQuery: { [key: string]: any } = { ...query }
    newQuery.page = 1
    setSearchParams(newQuery)
    return reload()
  }

  const actions = useMemo(
    () => [
      <SearchBar
        defaultValue={{
          nameLike: ''
        }}
        options={['nameLike']}
        labels={['Name']}
        fetcher={onSearch}
      />,

      <Button
        type="primary"
        onClick={() => {
          setCreateAPIKey(true)
        }}
      >
        Create
      </Button>
    ],
    // eslint-disable-next-line react-hooks/exhaustive-deps
    []
  )

  const renderCreateFormFields = useCallback(() => {
    return <CreateAPIKeyForm />
  }, [createAPIKey])

  const handleCreate = useCallback(
    async (payload: CreateAPIKeyFormType) => {
      const req = {
        ...payload
      }
      try {
        const resp = (await iAMServiceGenerateAPIKey(req)).data
        setCreatedAPIKey(resp.key || '')
        setCreatedAPIKeyVisible(true)
        setCreateAPIKey(false)
        reload()
      } catch (error) {
        showErrorModal(error)
      }
    },
    [reload]
  )

  const handleCancelCreate = useCallback(() => {
    setCreateAPIKey(false)
  }, [])

  return (
    <>
      <ListToolBar reload={reload} actions={actions} />

      <Table<V1APIKey>
        columns={columns}
        rowKey="id"
        dataSource={dataSource}
        loading={loading}
        pagination={paginationProps}
        onChange={onTableChange}
        size="small"
      />

      <ModalForm<CreateAPIKeyFormType>
        visible={!!createAPIKey}
        name="createAPIKey"
        title={'Create a API Key'}
        getFields={renderCreateFormFields}
        onSubmit={handleCreate}
        onCancel={handleCancelCreate}
        width={1000}
      />

      <Modal
        visible={createdAPIKeyVisible}
        title="Info"
        width={500}
        footer={[
          <Button
            key="ok"
            type="primary"
            onClick={() => setCreatedAPIKeyVisible(false)}
          >
            OK
          </Button>
        ]}
        onCancel={() => setCreatedAPIKeyVisible(false)}
      >
        <div>
          <p>
            API Key has been created, Please save the following key, it will not
            appear again!
          </p>
          <CodeBlock
            copyContent={createdAPIKey}
            withCopyButton
            onCopyClick={() => message.info('Copied')}
          >
            {createdAPIKey || ''}
          </CodeBlock>
        </div>
      </Modal>
    </>
  )
}
