import { Button, message, Popconfirm, Space, Spin } from 'antd';
import type { CSSProperties, Key } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useIntl, useModel } from 'umi';
import AppDetail from '../AppDetail';
import AppInfoDescriptions from '../AppInfoDescriptions';
import AuditCountersign from '../AuditCountersign';
import AuditPassOn from '../AuditPassOn';
import UserInfoDescriptions from '../UserInfoDescriptions';
import { auditWithdraw } from './api';
import BpmTable from './BpmTable';
import { useProTableList } from './hooks';
import Reason from './Reason';
import Reply from './Reply';
import UacTable from './UacTable';
import { emptyRowSelected, isFlatAuditList, isReplay } from './util';

const styles: Record<'topWrapper' | 'botWrapper' | 'optSpace', CSSProperties> = {
  topWrapper: {
    padding: '0 24px 24px 24px',
  },
  botWrapper: {
    padding: '24px 24px 0 24px',
  },
  optSpace: {
    width: '100%',
    justifyContent: 'space-between',
  },
};

export interface AuditListViewProps {
  chainId: string;
  /** 是否只读 */
  readOnly?: boolean;
  /** 简单模式，适应于批量审批界面 */
  simple?: boolean;
}

const AuditListView = (props: AuditListViewProps) => {
  const { chainId, readOnly, simple } = props;
  const { formatMessage } = useIntl();
  const { initialState } = useModel('@@initialState');
  const { currentUser } = initialState || {};
  const {
    auditDetail,
    requestDetail,
    loading,
    setLoading,
    setSelectionKeys,
    rowSelectionKeys,
    approvalHandler,
  } = useProTableList(chainId);

  const withdrawHandler = useCallback(async () => {
    setLoading(true);
    const res = await auditWithdraw({ chainId });
    message.success(formatMessage({ id: 'component.AuditList.withdraw.success' }));
    if (res) requestDetail();
  }, [chainId, formatMessage, requestDetail, setLoading]);

  const auditType = chainId?.includes('-') ? 'bpm' : 'uac';

  const getSelectedAuditId = useCallback(
    (type: string) => {
      const ids = Object.values(rowSelectionKeys ?? {}).flat(Infinity) as Key[];
      if (type === 'bpm') {
        return ids.map((v) => String(v).split('-')[0]);
      }
      return ids;
    },
    [rowSelectionKeys],
  );

  const uacApprovalHandler = useCallback(
    (state: number) => {
      setLoading(true);
      approvalHandler(getSelectedAuditId(auditType), state, auditType);
      setSelectionKeys({});
    },
    [approvalHandler, auditType, getSelectedAuditId, setLoading, setSelectionKeys],
  );

  useEffect(() => {
    setLoading(true);
    requestDetail();
    return () => setSelectionKeys({});
  }, [requestDetail, setLoading, setSelectionKeys]);

  const buttonDisabled = emptyRowSelected(rowSelectionKeys) || readOnly;
  const { appInfo, creator, initiator, auditList } = auditDetail || {};
  const { isWithdraw, isAudit } = useMemo(
    () => isReplay(chainId, auditDetail),
    [auditDetail, chainId],
  );
  const isCreator = creator?.id === currentUser?.id;
  const showWithdraw = Boolean((isCreator || initiator?.id === currentUser?.id) && isWithdraw);

  const showAudit = useCallback(() => {
    if (auditType === 'uac') return isAudit;
    // bpm 必须支持扁平化审批才能批量审批
    return isFlatAuditList(auditList) && isAudit;
  }, [auditList, auditType, isAudit]);

  const [appDetailOpen, setAppDetailOpen] = useState<boolean>(false);
  const [foldReason, setFoldReason] = useState<boolean>(true);

  return (
    <Spin spinning={loading}>
      <Space direction={'vertical'} style={styles.topWrapper}>
        <AppInfoDescriptions column={4} appId={appInfo?.id} simple={simple} />

        {!simple && <UserInfoDescriptions column={4} currentUser={creator} />}

        <Space style={styles.optSpace}>
          <Space>
            <Button type={'primary'} onClick={() => setAppDetailOpen(true)}>
              {formatMessage({ id: 'component.AuditList.view.alreadyPermissions' })}
            </Button>

            {showWithdraw && (
              <Popconfirm
                disabled={readOnly}
                title={formatMessage({ id: 'component.AuditList.view.withdraw.tips' })}
                onConfirm={withdrawHandler}
              >
                <Button danger disabled={readOnly}>
                  {formatMessage({ id: 'base.batch.withdraw' })}
                </Button>
              </Popconfirm>
            )}
          </Space>

          {showAudit() && (
            <Space>
              <Popconfirm
                disabled={buttonDisabled}
                placement={'topRight'}
                title={formatMessage({ id: 'component.AuditList.view.batchAgree.tips' })}
                onConfirm={() => uacApprovalHandler(1)}
              >
                <Button type={'primary'} ghost disabled={buttonDisabled}>
                  {formatMessage({ id: 'base.batch.agree' })}
                </Button>
              </Popconfirm>

              <Popconfirm
                disabled={buttonDisabled}
                placement={'topRight'}
                title={formatMessage({ id: 'component.AuditList.view.batchReject.tips' })}
                onConfirm={() => uacApprovalHandler(3)}
              >
                <Button danger disabled={buttonDisabled}>
                  {formatMessage({ id: 'base.batch.reject' })}
                </Button>
              </Popconfirm>

              <AuditCountersign
                chainId={chainId}
                auditId={getSelectedAuditId}
                type={auditType}
                disable={buttonDisabled}
                batch
                onComplete={requestDetail}
              />

              <AuditPassOn
                chainId={chainId}
                auditId={getSelectedAuditId}
                type={auditType}
                disable={buttonDisabled}
                batch
                onComplete={requestDetail}
                auditDetail={auditDetail}
              />
            </Space>
          )}
        </Space>
      </Space>

      {auditType === 'uac' ? (
        <UacTable
          auditDetail={auditDetail}
          chainId={chainId}
          pageReadOnly={readOnly}
          rowSelectionKeys={rowSelectionKeys}
          setSelectionKeys={setSelectionKeys}
          approvalHandler={approvalHandler}
          requestDetail={requestDetail}
        />
      ) : (
        <BpmTable
          auditDetail={auditDetail}
          chainId={chainId}
          pageReadOnly={readOnly}
          rowSelectionKeys={rowSelectionKeys}
          setSelectionKeys={setSelectionKeys}
          approvalHandler={approvalHandler}
          requestDetail={requestDetail}
        />
      )}

      {!simple && (
        <>
          <Reason
            style={styles.botWrapper}
            fold={foldReason}
            readOnly={readOnly}
            auditDetail={auditDetail}
            onRefresh={requestDetail}
            onFold={setFoldReason}
          />

          <Reply
            style={styles.botWrapper}
            chainId={chainId}
            auditDetail={auditDetail}
            readOnly={readOnly || !Boolean(isAudit || isCreator)}
            onReplied={() => requestDetail().then(() => setFoldReason(false))}
          />
        </>
      )}

      <AppDetail
        title={appInfo?.name}
        open={appDetailOpen}
        appId={appInfo?.id}
        userId={creator?.id}
        isOptShow={false}
        setOpen={setAppDetailOpen}
      />
    </Spin>
  );
};

export default AuditListView;
