import { Drawer, Popconfirm, message, Input, Alert, Tooltip, Space } from 'antd';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import { CustomTable } from '../CustomTable';
import { FormattedMessage, useDispatch, useIntl, useRequest, useSelector } from 'umi';
import { InfoCircleOutlined } from '@ant-design/icons';
import { memo, useEffect, useRef, useState } from 'react';
import { useGetAppId } from '../utils/hooks';
import { fetchUserList, validateUsers, cancelBindUsers, bindUsers } from '../server';
import moment from 'moment';
import AddUser from '../AddUser';
import React from 'react';
import { reloadReactNode } from '../utils/jsxformat';
import { formatUserRender } from '../utils';

interface BindUserProps {
  /**
   * @description feature 绑定的类型，目前支持如下。
   */
  type: 'feature' | 'option' | 'policy' | 'role'; // 选择类型
  /**
   * @description 绑定的类型的id，如type选了feature，就要传入featureId。
   */
  id: number; // 默认参数
  /**
   * @description type选了option，就需要传入flagId。
   */
  flagId?: number;
  /**
   * @description 可以自定义触发内容，默认是<a>用户</a>
   */
  children?: React.ReactNode;
  /**
   * @description 绑定的值发生变化刷新
   */
  refresh?: () => void;
}
const BindUser = ({ id, flagId, type, children, refresh }: BindUserProps) => {
  const [open, setOpen] = useState(false);
  const [pageSize, setPageSize] = useState(10);
  const actionRef = useRef<ActionType>();
  const { formatMessage } = useIntl();
  const dispatch = useDispatch();
  const appId = useGetAppId();
  const { appDetail } = useSelector<{ public: API.StoreState }, API.StoreState>(
    (state) => state.public,
  );
  const { data, run } = useRequest(validateUsers(appId, flagId), { manual: true });
  const { loading: cancelLoading, run: cancelRun } = useRequest(
    cancelBindUsers(type, { appId, [`${type}Id`]: id, flagId }),
    { manual: true },
  );
  // 用户账号 绑定时间 到期时间
  const columns: ProColumns<API.User & API.UserSearch>[] = [
    {
      title: <FormattedMessage id="public.user.id" defaultMessage="用户账号" />,
      dataIndex: 'accounts',
      valueType: 'textarea',
      hideInTable: true,
      fieldProps: {
        placeholder: formatMessage({ id: 'component.user.add.user.id.placeholder' }),
        rows: 4,
        allowClear: true,
      },
      colSize: 3,
      renderFormItem: () => <Input.TextArea />,
    },
    {
      title: <FormattedMessage id="public.user.id" defaultMessage="用户账号" />,
      dataIndex: 'id',
      ellipsis: true,
      search: false,
      hideInSearch: false,
      renderText: (text, record) => formatUserRender(record),
    },
    {
      title: <FormattedMessage id="public.user.bindTime" defaultMessage="绑定时间" />,
      dataIndex: 'bindTime',
      ellipsis: true,
      search: false,
      hideInSearch: false,
      valueType: 'dateTime',
    },
    {
      title: <FormattedMessage id="public.user.expires" defaultMessage="到期时间" />,
      dataIndex: 'expiredAt',
      ellipsis: true,
      search: false,
      hideInSearch: false,
      renderText: (text) =>
        `${
          text
            ? moment(text).format('YYYY-MM-DD HH:mm:ss')
            : formatMessage({ id: 'component.user.bind.expires.always' })
        }`,
    },
    {
      title: <FormattedMessage id="public.user.operation" defaultMessage="操作" />,
      dataIndex: 'id',
      search: false,
      hideInSearch: false,
      render: (text, record, _, action) => [
        <Popconfirm
          key={`del-${record.id}`}
          title={formatMessage({ id: 'component.user.bind.unbind.title' })}
          onConfirm={async () => {
            await cancelRun([record.id]);
            message.success(formatMessage({ id: 'component.user.bind.unbind.success' }));
            // @ts-ignore
            action?.clearSelected();
            action?.reload();
          }}
        >
          <a key="delete">
            <FormattedMessage id="public.user.del" defaultMessage="解绑" />
          </a>
        </Popconfirm>,
      ],
    },
  ];
  const toolbar = {
    title: formatMessage({ id: 'component.user.bind.toolbar.title' }),
    actions: [
      <AddUser
        reload={() => {
          refresh?.();
          actionRef?.current?.reload();
        }}
        key={`adduser${id}`}
        type={type}
        id={id}
        flagId={flagId}
      />,
    ],
  };

  const tableAlert = ({ selectedRowKeys, selectedRows, onCleanSelected }) => [
    {
      label: <FormattedMessage id="public.user.batchDel" defaultMessage="批量解绑" />,
      loading: cancelLoading,
      onClick: async () => {
        await cancelRun(selectedRowKeys);
        message.success(formatMessage({ id: 'component.user.bind.batch.unbind.success' }));
        onCleanSelected();
        refresh?.();
        actionRef?.current?.reload?.();
      },
    },
  ];
  const tableExtraRender = () => (
    <Alert
      type="error"
      showIcon
      closable
      description={
        <Space direction="vertical">
          {data?.notExist?.length > 0 ? (
            <Space align="start">
              <div style={{ minWidth: 120 }}>
                <FormattedMessage id="component.user.bind.notExist.label" />
                <Tooltip title={<FormattedMessage id="component.user.bind.notExist.tips" />}>
                  <a>
                    <InfoCircleOutlined style={{ fontSize: 12 }} />
                  </a>
                </Tooltip>
                ：
              </div>
              <Space wrap>{data?.notExist?.join(',')}</Space>
            </Space>
          ) : null}
          {data?.noManagementPermission?.length > 0 ? (
            <Space align="start">
              <div style={{ minWidth: 120 }}>
                <FormattedMessage id="component.user.bind.noManagementPermission.label" />
                <Tooltip
                  title={<FormattedMessage id="component.user.bind.noManagementPermission.tips" />}
                >
                  <a>
                    <InfoCircleOutlined style={{ fontSize: 12 }} />
                  </a>
                </Tooltip>
                ：
              </div>
              <Space wrap>
                {data?.noManagementPermission?.map((user) => user.account)?.join(',')}
              </Space>
            </Space>
          ) : null}
          {data?.noPermission?.length > 0 ? (
            <Space align="start">
              <div style={{ minWidth: 120 }}>
                <FormattedMessage id="component.user.bind.noPermission.label" />
                <Popconfirm
                  key="permission"
                  title={`${formatMessage({
                    id: 'component.user.bind.noPermission.tips',
                  })}(${data?.noPermission?.map((user) => user.account)?.join(',')})${formatMessage(
                    {
                      id: 'component.user.bind.permission',
                      defaultMessage: '授权',
                    },
                  )}?`}
                  onConfirm={async () => {
                    await bindUsers(
                      type,
                      data?.noPermission?.map((user) => ({
                        appId,
                        flagId,
                        userId: user.id,
                        expiredAt: appDetail.defaultExpirationTime
                          ? appDetail.defaultExpirationTime + Math.round(moment().valueOf() / 1000)
                          : undefined,
                        [`${type}Id`]: id,
                      })),
                    );
                    message.success(
                      formatMessage({
                        id: 'component.user.bind.permission.success',
                        defaultMessage: '授权成功！',
                      }),
                    );
                    refresh?.();
                    actionRef?.current?.reload?.();
                  }}
                >
                  <a>
                    <FormattedMessage id="component.user.bind.permission" />
                  </a>
                </Popconfirm>
                <Tooltip
                  title={<FormattedMessage id="component.user.bind.noPermission.tips.others" />}
                >
                  <a>
                    <InfoCircleOutlined style={{ fontSize: 12 }} />
                  </a>
                </Tooltip>
                ：
              </div>
              <Space>{data?.noPermission?.map((user) => user.account)?.join(',')}</Space>
            </Space>
          ) : null}
        </Space>
      }
    />
  );
  const triggerRender = () =>
    reloadReactNode(
      <a onClick={() => setOpen(true)}>
        <FormattedMessage id="component.bind.user" defaultMessage="用户" />
      </a>,
      setOpen,
      children,
    );
  useEffect(() => {
    if (open) {
      dispatch({
        type: 'public/fetchAppDetail',
        payload: appId,
      });
    }
  }, [open, appId, dispatch]);
  return (
    <>
      <Drawer
        title={<FormattedMessage id="component.bind.user.title" defaultMessage="绑定用户" />}
        width="900px"
        open={open}
        keyboard={false}
        maskClosable={false}
        destroyOnClose
        onClose={() => setOpen(false)}
      >
        <CustomTable
          columns={columns}
          search={{
            labelWidth: 'auto',
            span: 6,
          }}
          toolbar={toolbar}
          actionRef={actionRef}
          tableAlert={tableAlert}
          params={{
            appId,
            flagId,
            isBind: true,
            [`${type === 'option' ? 'flagOption' : type}Id`]: id,
          }}
          pagination={{
            pageSize,
          }}
          // @ts-ignore
          request={async (
            param: { accounts: string } & {
              pageSize: number;
              current?: number | undefined;
              keyword?: string | undefined;
            },
            ...pars
          ) => {
            if (param.accounts) {
              run({ accounts: param.accounts?.trim()?.split(','), [`${type}Id`]: id });
            } else {
              run({ accounts: [], [`${type}Id`]: id });
            }
            setPageSize(param.pageSize);
            return fetchUserList({ ...param, accounts: param?.accounts?.split(',') }, ...pars);
          }}
          rowSelection={{}}
          tableExtraRender={() =>
            data?.notExist?.length > 0 ||
            data?.noManagementPermission?.length > 0 ||
            data?.noPermission?.length > 0
              ? tableExtraRender()
              : null
          }
        />
      </Drawer>
      {triggerRender()}
    </>
  );
};
export default memo(BindUser);
