import { Button, Modal, Table } from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { useCallback, useMemo, useState } from 'react'

import {
  iAMServiceCreateRole,
  iAMServiceListRoles
} from 'apiClient/services/core-server'
import { V1Role } 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 CreateRoleForm, { CreateRoleFormType } from './Role/Forms/CreateRoleForm'

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

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

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

  const columns: ColumnsType<V1Role> = [
    {
      title: 'Name',
      render: (_: any, record) => {
        return <a href={'/iam/role/roles/' + record.name}>{record.name}</a>
      }
    },
    {
      title: 'Description',
      render: (_: any, record) => {
        return record.description
      }
    },
    {
      title: 'Allowed Tenants',
      render: (_: any, record) => {
        if (!record.allowedTenantIds || record.allowedTenantIds.length === 0) {
          return '-'
        }
        return record.allowedTenantIds.join(', ')
      }
    },
    {
      title: 'Created At',
      render: (_: any, record) => {
        return toLocal(record?.createdAt)
      }
    }
  ]

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

  const actions = useMemo(
    () => [
      <SearchBar
        defaultValue={searchParams}
        options={['nameLike']}
        labels={['Name']}
        fetcher={onSearch}
      />,
      <Button
        type="primary"
        onClick={() => {
          setCreateRole(true)
        }}
      >
        Create
      </Button>
    ],
    [searchParams]
  )

  const renderCreateFormFields = useCallback(() => {
    return <CreateRoleForm />
  }, [createRole])

  const handleCreate = useCallback(
    async (payload: CreateRoleFormType) => {
      const req = {
        ...payload,
        allowedTenantIds:
          payload.allowedTenantIds && payload.allowedTenantIds.length > 0
            ? payload.allowedTenantIds
            : undefined
      }
      try {
        await iAMServiceCreateRole(req)
        Modal.success({
          title: 'Info',
          content: (
            <div>
              <p>Role has been created</p>
            </div>
          ),
          onOk() {}
        })
        setCreateRole(false)
        reload()
      } catch (error) {
        showErrorModal(error)
      }
    },
    [reload]
  )

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

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

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

      <ModalForm<CreateRoleFormType>
        visible={!!createRole}
        name="createRole"
        title={'Create a Role'}
        getFields={renderCreateFormFields}
        onSubmit={handleCreate}
        onCancel={handleCancelCreate}
        width={600}
      />
    </div>
  )
}
