import type { ProColumns } from '@ant-design/pro-table';
import { Button, Card, Popconfirm, Space, Tooltip, Typography } from 'antd';
import _ from 'lodash';
import type { Key } from 'react';
import { useCallback, useMemo } from 'react';
import { FormattedMessage, useIntl } from 'umi';
import AuditCountersign from '../AuditCountersign';
import AuditPassOn from '../AuditPassOn';
import AuditProgress from '../AuditProgress';
import BindAllPermission from '../BindAllPermission';
import CustomTable from '../CustomTable';
import ExpandIcon from '../ExpandIcon';
import Tips from '../Tips';
import publicConst from '../utils/const';
import type { BpmTableProps } from './BpmTable';
import { AduitStatus } from './const';
import type { RowType } from './hooks';
import lessStyle from './index.less';
import { flatAuditDataKey, flatAuditRowKey } from './util';

const { DataSensitiveLevelTips, DataSensitiveTips } = Tips;
const { Text } = Typography;

export interface PermissionTableProps {
  auditDetail: any;
  data: any;
  pageReadOnly?: boolean;
  chainId?: string;
  rowSelectionKeys?: BpmTableProps['rowSelectionKeys'];
  setSelectionKeys?: BpmTableProps['setSelectionKeys'];
  approvalHandler?: BpmTableProps['approvalHandler'];
  requestDetail?: BpmTableProps['requestDetail'];
}

const PermissionTable = (props: PermissionTableProps) => {
  const {
    auditDetail,
    data,
    pageReadOnly,
    chainId,
    rowSelectionKeys,
    setSelectionKeys,
    approvalHandler,
    requestDetail,
  } = props;
  const { formatMessage } = useIntl();
  const { appInfo } = auditDetail || {};

  const columns = useCallback(
    (type: string) => {
      const { DataSensitiveMap, DataSensitiveLevelMap } = publicConst(formatMessage);
      const res: ProColumns<any>[] = [
        {
          title: (
            <FormattedMessage id={`base.common.${type}.permission`} defaultMessage="权限名称" />
          ),
          dataIndex: 'name',
          search: false,
          className: lessStyle.nameColumn,
          render: (__, record) => {
            const { name, id } = record;
            return (
              <>
                <Tooltip title={name}>
                  <span className={lessStyle.text}>{name}</span>
                </Tooltip>
                {type === 'role' && (
                  <BindAllPermission
                    appId={appInfo?.id}
                    roleId={id}
                    roleName={name}
                    iconStyle={{ padding: '0 4px' }}
                  />
                )}
              </>
            );
          },
        },
        {
          title: <FormattedMessage id="pages.funcList.sensitiveLevel" defaultMessage="敏感等级" />,
          dataIndex: 'dataSensitive',
          search: false,
          tooltip: DataSensitiveLevelTips,
          valueType: 'select',
          valueEnum: DataSensitiveLevelMap,
        },
        {
          title: <FormattedMessage id="base.common.sensitiveLevel" defaultMessage="敏感度" />,
          dataIndex: 'sensitiveLevel',
          search: false,
          tooltip: DataSensitiveTips,
          valueType: 'select',
          valueEnum: DataSensitiveMap,
        },
        {
          title: <FormattedMessage id="pages.process.expiration" defaultMessage="有效期" />,
          dataIndex: 'expiredAt',
          search: false,
          ellipsis: true,
          render: (__, record) => {
            const expiredAt = type === 'city' ? 0 : record.expiredAt;
            return (
              _.isNumber(expiredAt) && (
                <Text ellipsis={{ tooltip: true }}>
                  {expiredAt === 0
                    ? formatMessage({ id: 'pages.setting.base.defaultExpirationTime.forever' })
                    : expiredAt / 86400}
                </Text>
              )
            );
          },
        },
      ];

      if (approvalHandler) {
        res.push(
          {
            title: (
              <FormattedMessage id="pages.process.approval.status" defaultMessage="审批状态" />
            ),
            dataIndex: 'bpmAuditNode',
            search: false,
            render: (__: any, record: any) => {
              const auditData = record[flatAuditDataKey];
              if (!auditData) return null;
              const { bpmAuditNode } = auditData;
              if (!Array.isArray(bpmAuditNode) || !bpmAuditNode.length) return null;
              const last = bpmAuditNode[bpmAuditNode.length - 1];
              return (
                <Text ellipsis={{ tooltip: true }}>
                  {formatMessage({ id: AduitStatus[last?.state] })}
                </Text>
              );
            },
          },
          {
            title: <FormattedMessage id="component.audit.detail.title" defaultMessage="审批流" />,
            dataIndex: 'bpmAuditNode',
            search: false,
            render: (__: any, record: any) => {
              const auditData = record[flatAuditDataKey];
              if (!auditData) return null;
              const { bpmAuditNode } = auditData;
              return (
                <AuditProgress bpmAuditNode={bpmAuditNode} detailData={auditDetail}>
                  <Button type={'primary'} size={'small'} ghost>
                    {formatMessage({ id: 'base.button.view' })}
                  </Button>
                </AuditProgress>
              );
            },
          },
          {
            title: <FormattedMessage id="base.common.operation" defaultMessage="操作" />,
            dataIndex: 'permissionOption',
            valueType: 'option',
            fixed: 'right',
            align: 'center',
            search: false,
            width: 240,
            hideInTable: pageReadOnly,
            render: (__: any, record: any) => {
              const auditData = record[flatAuditDataKey];
              if (!auditData) return null;
              const { bpmCanAudit, bpmAuditId } = auditData;
              if (!chainId || !bpmCanAudit) return null;
              return (
                <Space>
                  <Popconfirm
                    title={formatMessage({ id: 'component.AuditList.view.agree.tips' })}
                    placement={'topRight'}
                    onConfirm={() => {
                      approvalHandler([bpmAuditId], 1, 'bpm');
                    }}
                  >
                    <Button size={'small'} type={'primary'} ghost>
                      {formatMessage({ id: 'base.button.agree' })}
                    </Button>
                  </Popconfirm>

                  <Popconfirm
                    title={formatMessage({ id: 'component.AuditList.view.reject.tips' })}
                    placement={'topRight'}
                    onConfirm={() => {
                      approvalHandler([bpmAuditId], 3, 'bpm');
                    }}
                  >
                    <Button size={'small'} danger>
                      {formatMessage({ id: 'base.button.reject' })}
                    </Button>
                  </Popconfirm>

                  <AuditCountersign
                    chainId={chainId}
                    auditId={bpmAuditId}
                    type={'bpm'}
                    onComplete={requestDetail}
                  />

                  <AuditPassOn
                    chainId={chainId}
                    auditId={bpmAuditId}
                    type={'bpm'}
                    onComplete={requestDetail}
                    auditDetail={auditData}
                  />
                </Space>
              );
            },
          },
        );
      }
      return res;
    },
    [
      appInfo?.id,
      approvalHandler,
      auditDetail,
      chainId,
      formatMessage,
      pageReadOnly,
      requestDetail,
    ],
  );

  const dataSource = useMemo(() => {
    const { feature, role, policy, option, city } = data || {};
    // 分类列表
    const res: { type: string; list: any[] }[] = [];
    // 功能
    if (feature?.length) {
      res.push({ type: 'feature', list: feature });
    }
    // 角色
    if (role?.length) {
      res.push({ type: 'role', list: role });
    }
    // 策略
    if (policy?.length) {
      res.push({ type: 'policy', list: policy });
    }
    // 数据
    if (option?.length) {
      res.push({
        type: 'option',
        list: option.map((v: any) => ({ ...v, children: v.optionTree })),
      });
    }
    // 城市
    if (city?.length) {
      res.push({ type: 'city', list: city });
    }
    return res;
  }, [data]);

  const rowSelection = useCallback(
    (type: string) => {
      if (pageReadOnly || !approvalHandler) return false;
      return {
        getCheckboxProps: (record: any) => {
          const auditData = record[flatAuditDataKey];
          if (!auditData) {
            return { disabled: true };
          }
          const { bpmCanAudit } = auditData as any;
          return {
            disabled: !chainId || !bpmCanAudit,
          };
        },
        selectedRowKeys: rowSelectionKeys?.[type],
        onChange: (rowKey: Key[]) => {
          setSelectionKeys?.((oldVal: RowType) => ({ ...oldVal, [type]: rowKey }));
        },
      };
    },
    [approvalHandler, chainId, pageReadOnly, rowSelectionKeys, setSelectionKeys],
  );

  return (
    <Space direction={'vertical'} size={'middle'}>
      {dataSource.map((v) => {
        const { type, list } = v;
        return (
          <Card key={type} bodyStyle={{ padding: 0 }}>
            <CustomTable
              tableClassName={lessStyle.childTable}
              rowKey={approvalHandler ? flatAuditRowKey : 'id'}
              overflow={true}
              headerTitle={false}
              search={false}
              options={false}
              pagination={false}
              columns={columns(type)}
              expandable={{
                expandIcon: (p) => <ExpandIcon {...p} style={{ padding: '0 4px' }} />,
              }}
              rowSelection={rowSelection(type)}
              dataSource={list}
            />
          </Card>
        );
      })}
    </Space>
  );
};

export default PermissionTable;
