<script setup lang="ts">
import type { ApprovalType } from '../type';

import type { User } from '#/api/core/user';
import type { TaskInfo } from '#/api/workflow/task/model';

import { computed, h } from 'vue';
import { useRouter } from 'vue-router';

import { useVbenDrawer } from '@vben/common-ui';
import { cn, getPopupContainer } from '@vben/utils';

import { Check, Edit, ExclamationCircle, Menu as MenuIcon, Rollback, User, UserPlus, UserMinus } from '@element-plus/icons-vue';
import { ElDropdown, ElMenu, ElMenuItem, ElMessageBox, ElSpace } from 'element-plus';

import {
  cancelProcessApply,
  deleteByInstanceIds,
} from '#/api/workflow/instance';
import {
  taskOperation,
  terminationTask,
  updateAssignee,
} from '#/api/workflow/task';

import { approvalModal, approvalRejectionModal, flowInterfereModal } from '..';
import { approveWithReasonModal } from '../helper';
import userSelectModal from '../user-select-modal.vue';

interface Props {
  /**
   * 行数据的taskInfo?
   */
  task?: TaskInfo;
  /**
   * 审批类型 根据不同类型显示按钮
   */
  type: ApprovalType;
  /**
   * 为审批类型时候 显示的按钮(按钮权限)
   */
  buttonPermissions: Record<string, boolean>;
}
const props = defineProps<Props>();

const emit = defineEmits<{
  reload: [];
}>();

// 是否显示 `其他` 按钮
const showButtonOther = computed(() => {
  const moreCollections = new Set(['addSign', 'subSign', 'transfer', 'trust']);
  return Object.keys(props.buttonPermissions).some(
    (key) => moreCollections.has(key) && props.buttonPermissions[key],
  );
});

// 进行中 可以撤销
const revocable = computed(() => props.task?.flowStatus === 'waiting');
async function handleCancel() {
  ElMessageBox.confirm({
    title: '提示',
    message: '确定要撤销该申请吗？',
    center: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    callback: async (action) => {
      if (action === 'confirm') {
        await cancelProcessApply({
          businessId: props.task!.businessId,
          message: '申请人撤销流程！',
        });
        emit('reload');
      }
    },
  });
}

/**
 * 是否可编辑/删除
 */
const editableAndRemoveable = computed(() => {
  if (!props.task) {
    return false;
  }
  return ['back', 'cancel', 'draft'].includes(props.task.flowStatus);
});

const router = useRouter();
function handleEdit() {
  const path = props.task?.formPath;
  if (path) {
    router.push({ path, query: { id: props.task!.businessId } });
  }
}

function handleRemove() {
  ElMessageBox.confirm({
    title: '提示',
    message: '确定删除该申请吗？',
    center: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    callback: async (action) => {
      if (action === 'confirm') {
        await deleteByInstanceIds([props.task!.id]);
        emit('reload');
      }
    },
  });
}

/**
 * 审批驳回
 */
const [RejectionDrawer, rejectionDrawerApi] = useVbenDrawer({
  connectedComponent: approvalRejectionModal,
});
function handleRejection() {
  rejectionDrawerApi.setData({
    taskId: props.task?.id,
    definitionId: props.task?.definitionId,
    nodeCode: props.task?.nodeCode,
  });
  rejectionDrawerApi.open();
}

/**
 * 审批终止
 */
function handleTermination() {
  approveWithReasonModal({
    title: '审批终止',
    description: '确定终止当前审批流程吗？',
    onOk: async (reason) => {
      await terminationTask({ taskId: props.task!.id, comment: reason });
      emit('reload');
    },
  });
}

/**
 * 审批通过
 */
const [ApprovalDrawer, approvalDrawerApi] = useVbenDrawer({
  connectedComponent: approvalModal,
});
function handleApproval() {
  const { buttonPermissions } = props;
  // 是否具有抄送权限
  const copyPermission = buttonPermissions?.copy ?? false;
  // 是否具有选人权限
  const assignPermission = buttonPermissions?.pop ?? false;
  approvalDrawerApi.setData({
    taskId: props.task?.id,
    copyPermission,
    assignPermission,
  });
  approvalDrawerApi.open();
}

/**
 * 委托
 */
const [DelegationDrawer, delegationDrawerApi] = useVbenDrawer({
  connectedComponent: userSelectModal,
});
function handleDelegation(userList: User[]) {
  if (userList.length === 0) return;
  const current = userList[0];
  approveWithReasonModal({
    title: '委托',
    description: `确定委托给[${current?.nickName}]吗?`,
    onOk: async (reason) => {
      await taskOperation(
        { taskId: props.task!.id, userId: current!.userId, message: reason },
        'delegateTask',
      );
      emit('reload');
    },
  });
}

/**
 * 转办
 */
const [TransferDrawer, transferDrawerApi] = useVbenDrawer({
  connectedComponent: userSelectModal,
});
function handleTransfer(userList: User[]) {
  if (userList.length === 0) return;
  const current = userList[0];
  approveWithReasonModal({
    title: '转办',
    description: `确定转办给[${current?.nickName}]吗?`,
    onOk: async (reason) => {
      await taskOperation(
        { taskId: props.task!.id, userId: current!.userId, message: reason },
        'transferTask',
      );
      emit('reload');
    },
  });
}

const [AddSignatureDrawer, addSignatureDrawerApi] = useVbenDrawer({
  connectedComponent: userSelectModal,
});
function handleAddSignature(userList: User[]) {
  if (userList.length === 0) return;
  const userIds = userList.map((user) => user.userId);
  ElMessageBox.confirm({
    title: '提示',
    message: '确认加签吗?',
    center: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    callback: async (action) => {
      if (action === 'confirm') {
        await taskOperation({ taskId: props.task!.id, userIds }, 'addSignature');
        emit('reload');
      }
    },
  });
}

const [ReductionSignatureDrawer, reductionSignatureDrawerApi] = useVbenDrawer({
  connectedComponent: userSelectModal,
});
function handleReductionSignature(userList: User[]) {
  if (userList.length === 0) return;
  const userIds = userList.map((user) => user.userId);
  ElMessageBox.confirm({
    title: '提示',
    message: '确认减签吗?',
    center: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    callback: async (action) => {
      if (action === 'confirm') {
        await taskOperation(
          { taskId: props.task!.id, userIds },
          'reductionSignature',
        );
        emit('reload');
      }
    },
  });
}

// 流程干预
const [FlowInterfereDrawer, flowInterfereDrawerApi] = useVbenDrawer({
  connectedComponent: flowInterfereModal,
});
function handleFlowInterfere() {
  flowInterfereDrawerApi.setData({ taskId: props.task?.id });
  flowInterfereDrawerApi.open();
}

// 修改办理人
const [UpdateAssigneeDrawer, updateAssigneeDrawerApi] = useVbenDrawer({
  connectedComponent: userSelectModal,
});
function handleUpdateAssignee(userList: User[]) {
  if (userList.length === 0) return;
  const current = userList[0];
  if (!current) return;
  ElMessageBox.confirm({
    title: '修改办理人',
    message: `确定修改办理人为${current?.nickName}吗?`,
    center: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    callback: async (action) => {
      if (action === 'confirm') {
        await updateAssignee([props.task!.id], current.userId);
        emit('reload');
      }
    },
  });
}

/**
 * 是否显示 加签/减签操作
 */
const showMultiActions = computed(() => {
  if (!props.task) {
    return false;
  }
  if (Number(props.task.nodeRatio) > 0) {
    return true;
  }
  return false;
});
</script>

<template>
  <div
    :class="
      cn(
        'absolute bottom-0 left-0',
        'border-t-solid border-t-[1px]',
        'bg-background w-full p-3',
      )
    "
  >
    <div class="flex justify-end">
      <ElSpace v-if="type === 'myself'">
        <el-button
          v-if="revocable"
          danger
          text
          type="primary"
          :icon="h(Rollback)"
          @click="handleCancel"
        >
          撤销申请
        </el-button>
        <el-button
          type="primary"
          text
          v-if="editableAndRemoveable"
          :icon="h(Edit)"
          @click="handleEdit"
        >
          重新编辑
        </el-button>
        <el-button
          v-if="editableAndRemoveable"
          danger
          text
          type="primary"
          :icon="h(Edit)"
          @click="handleRemove"
        >
          删除
        </el-button>
      </ElSpace>
      <ElSpace v-if="type === 'approve'">
        <el-button
          type="primary"
          text
          :icon="h(Check)"
          @click="handleApproval"
        >
          通过
        </el-button>
        <el-button
          v-if="buttonPermissions?.termination"
          danger
          text
          type="primary"
          :icon="h(ExclamationCircle)"
          @click="handleTermination"
        >
          终止
        </el-button>
        <el-button
          v-if="buttonPermissions?.back"
          danger
          text
          type="primary"
          @click="handleRejection"
        >
          驳回
        </el-button>
        <ElDropdown
          :teleported="false"
          trigger="click"
          placement="bottom-right"
        >
          <template #dropdown>
            <ElMenu>
              <ElMenuItem
                v-if="buttonPermissions?.trust"
                key="1"
                @click="() => delegationDrawerApi.open()"
              >
                <User class="mr-2" /> 委托
              </ElMenuItem>
              <ElMenuItem
                v-if="buttonPermissions?.transfer"
                key="2"
                @click="() => transferDrawerApi.open()"
              >
                <Rollback class="mr-2" /> 转办
              </ElMenuItem>
              <ElMenuItem
                v-if="showMultiActions && buttonPermissions?.addSign"
                key="3"
                @click="() => addSignatureDrawerApi.open()"
              >
                <UserPlus class="mr-2" /> 加签
              </ElMenuItem>
              <ElMenuItem
                v-if="showMultiActions && buttonPermissions?.subSign"
                key="4"
                @click="() => reductionSignatureDrawerApi.open()"
              >
                <UserMinus class="mr-2" /> 减签
              </ElMenuItem>
            </ElMenu>
          </template>
          <el-button v-if="showButtonOther" :icon="h(MenuIcon)">
            其他
          </el-button>
        </ElDropdown>
        <ApprovalDrawer @complete="$emit('reload')" />
        <RejectionDrawer @complete="$emit('reload')" />
        <DelegationDrawer mode="single" @finish="handleDelegation" />
        <TransferDrawer mode="single" @finish="handleTransfer" />
        <AddSignatureDrawer mode="multiple" @finish="handleAddSignature" />
        <ReductionSignatureDrawer
          mode="multiple"
          @finish="handleReductionSignature"
        />
      </ElSpace>
      <ElSpace v-if="type === 'admin'">
        <el-button @click="handleFlowInterfere"> 流程干预 </el-button>
        <el-button @click="() => updateAssigneeDrawerApi.open()">
          修改办理人
        </el-button>
        <FlowInterfereDrawer @complete="$emit('reload')" />
        <UpdateAssigneeDrawer mode="single" @finish="handleUpdateAssignee" />
      </ElSpace>
    </div>
  </div>
</template>
