import { SyncOutlined } from '@ant-design/icons'
import { Button, Checkbox, Input, Modal, Table } from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { useCallback, useMemo, useState } from 'react'

import {
  userServiceCreateGroup,
  userServiceListGroups,
  userServiceSyncUserGroupsAsync
} from 'apiClient/services/core-server'
import {
  UserServiceListGroupsSourceIs,
  V1UserGroup,
  V1UserGroupSource
} from 'apiClient/services/core-server/interface'
import ModalForm from 'components/ModalForm'
import { ListToolBar, useTable } from 'components/Table'
import {
  formatUserGroupSource,
  showErrorModal,
  toListDataResponse
} from 'pages/IAM/utils'
import { toLocal } from 'utils/time'

import CreateUserGroupForm, {
  CreateUserGroupFormType
} from './UserGroup/Forms/CreateUserGroupForm'

export default function UserGroups() {
  const [searchParams, setSearchParams] = useState<{
    groupKeyword?: string
  }>({})
  const [onlyShowCustom, setOnlyShowCustom] = useState(true)

  const [createUserGroup, setCreateUserGroup] = useState(false)

  const getData = (params?: Partial<PageInfo>) => {
    return userServiceListGroups({
      groupKeyword: searchParams.groupKeyword,
      sourceIs: onlyShowCustom
        ? UserServiceListGroupsSourceIs.USER_GROUP_SOURCE_CUSTOM
        : undefined,
      page: params?.page,
      perPage: params?.pageSize,
      withTag: true
    }).then((response) => toListDataResponse(response, (data) => data.groups))
  }

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

  const columns: ColumnsType<V1UserGroup> = [
    {
      title: 'Name',
      render: (_: any, record) => {
        if (!record.base?.name) {
          return '-'
        }

        const tagName = record.tags?.find((tag) => tag.key === 'Name')?.value
        const displayName =
          record.base.source === V1UserGroupSource.USER_GROUP_SOURCE_LARK
            ? `${tagName || '-'} (${record.base.name})`
            : record.base.name

        return (
          <a href={'/iam/entity/usergroups/' + record.base.name}>
            {displayName}
          </a>
        )
      }
    },
    {
      title: 'Description',
      render: (_: any, record) => {
        return record.base?.description
      }
    },
    {
      title: 'Parent Group',
      render: (_: any, record) => {
        if (!record.base?.parentName) {
          return '-'
        }
        return (
          <a href={'/iam/entity/usergroups/' + record.base.parentName}>
            {record.base.parentName}
          </a>
        )
      }
    },
    {
      title: 'Source',
      render: (_: any, record) => {
        return formatUserGroupSource(record.base?.source)
      }
    },
    {
      title: 'Created At',
      render: (_: any, record) => {
        return toLocal(record.base?.createdAt)
      }
    }
  ]

  const onSearch = useCallback(
    (keyword: string) => {
      setSearchParams({
        groupKeyword: keyword || undefined
      })
      resetPageIndex()
      return reload()
    },
    [reload, resetPageIndex]
  )

  const handleSync = useCallback(async () => {
    try {
      await userServiceSyncUserGroupsAsync({})
      Modal.success({
        title: 'Info',
        content: (
          <div>
            <p>User Group sync has been triggered successfully.</p>
          </div>
        ),
        onOk() {}
      })
      reload()
    } catch (error) {
      showErrorModal(error)
    }
  }, [reload])

  const actions = useMemo(
    () => [
      <Checkbox
        checked={onlyShowCustom}
        onChange={(event) => {
          setOnlyShowCustom(event.target.checked)
          resetPageIndex()
          reload()
        }}
      >
        only show custom group
      </Checkbox>,
      <Input.Search
        style={{ width: '24rem' }}
        placeholder="Search by user group name"
        onSearch={onSearch}
        onChange={(event) => {
          if (!event.target.value) {
            onSearch('')
          }
        }}
        allowClear
      />,
      <Button
        type="primary"
        onClick={() => {
          setCreateUserGroup(true)
        }}
      >
        Create
      </Button>,
      <Button name="sync" icon={<SyncOutlined />} onClick={handleSync}>
        Sync
      </Button>
    ],
    [handleSync, onSearch, onlyShowCustom, reload, resetPageIndex]
  )

  const renderCreateFormFields = useCallback(() => {
    return <CreateUserGroupForm />
  }, [createUserGroup])

  const handleCreate = useCallback(
    async (payload: CreateUserGroupFormType) => {
      const req = {
        ...payload
      }
      try {
        await userServiceCreateGroup(req)
        Modal.success({
          title: 'Info',
          content: (
            <div>
              <p>User Group has been added</p>
            </div>
          ),
          onOk() {}
        })
        setCreateUserGroup(false)
        reload()
      } catch (error) {
        showErrorModal(error)
      }
    },
    [reload]
  )

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

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

      <Table<V1UserGroup>
        rowKey={(record) => record.base?.name || ''}
        columns={columns}
        dataSource={dataSource}
        loading={loading}
        pagination={paginationProps}
        size="small"
        onChange={onTableChange}
      ></Table>

      <ModalForm<CreateUserGroupFormType>
        visible={!!createUserGroup}
        name="createUserGroup"
        title={'Create a User Group'}
        getFields={renderCreateFormFields}
        onSubmit={handleCreate}
        onCancel={handleCancelCreate}
        width={1000}
      />
    </div>
  )
}
