<!-- 审批详情的右侧：审批流 -->
<script lang="ts" setup>
import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';

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

import { IconifyIcon } from '@vben/icons';
import { formatDateTime, isEmpty } from '@vben/utils';

import { Avatar, Button, Image, Tooltip } from 'ant-design-vue';

import { UserSelectModal } from '#/components/user-select-modal';
import { CandidateStrategyEnum, NodeTypeEnum, TaskStatusEnum } from '#/utils';

defineOptions({ name: 'BpmProcessInstanceTimeline' });

withDefaults(
  defineProps<{
    activityNodes: BpmProcessInstanceApi.ApprovalNodeInfo[]; // 审批节点信息
    showStatusIcon?: boolean; // 是否显示头像右下角状态图标
  }>(),
  {
    showStatusIcon: true, // 默认值为 true
  },
);

const emit = defineEmits<{
  selectUserConfirm: [id: string, userList: any[]];
}>();

const { push } = useRouter(); // 路由

// 状态图标映射
const statusIconMap: Record<
  string,
  { animation?: string; color: string; icon: string }
> = {
  // 审批未开始
  '-1': { color: '#909398', icon: 'mdi:clock-outline' },
  // 待审批
  '0': { color: '#00b32a', icon: 'mdi:loading' },
  // 审批中
  '1': { color: '#448ef7', icon: 'mdi:loading', animation: 'animate-spin' },
  // 审批通过
  '2': { color: '#00b32a', icon: 'mdi:check' },
  // 审批不通过
  '3': { color: '#f46b6c', icon: 'mdi:close' },
  // 已取消
  '4': { color: '#cccccc', icon: 'mdi:trash-can-outline' },
  // 退回
  '5': { color: '#f46b6c', icon: 'mdi:arrow-left' },
  // 委派中
  '6': { color: '#448ef7', icon: 'mdi:clock-outline' },
  // 审批通过中
  '7': { color: '#00b32a', icon: 'mdi:check' },
};

// 节点类型图标映射
const nodeTypeSvgMap = {
  // 结束节点
  [NodeTypeEnum.END_EVENT_NODE]: {
    color: '#909398',
    icon: 'mdi:power',
  },
  // 开始节点
  [NodeTypeEnum.START_USER_NODE]: {
    color: '#909398',
    icon: 'mdi:account-outline',
  },
  // 用户任务节点
  [NodeTypeEnum.USER_TASK_NODE]: {
    color: '#ff943e',
    icon: 'tdesign:seal',
  },
  // 事务节点
  [NodeTypeEnum.TRANSACTOR_NODE]: {
    color: '#ff943e',
    icon: 'mdi:file-edit-outline',
  },
  // 复制任务节点
  [NodeTypeEnum.COPY_TASK_NODE]: {
    color: '#3296fb',
    icon: 'mdi:content-copy',
  },
  // 条件分支节点
  [NodeTypeEnum.CONDITION_NODE]: {
    color: '#14bb83',
    icon: 'carbon:flow',
  },
  // 并行分支节点
  [NodeTypeEnum.PARALLEL_BRANCH_NODE]: {
    color: '#14bb83',
    icon: 'si:flow-parallel-line',
  },
  // 子流程节点
  [NodeTypeEnum.CHILD_PROCESS_NODE]: {
    color: '#14bb83',
    icon: 'icon-park-outline:tree-diagram',
  },
};

// 只有状态是 -1、0、1 才展示头像右小角状态小icon
const onlyStatusIconShow = [-1, 0, 1];

// 获取审批节点类型图标
const getApprovalNodeTypeIcon = (nodeType: NodeTypeEnum) => {
  return nodeTypeSvgMap[nodeType]?.icon;
};

// 获取审批节点图标
const getApprovalNodeIcon = (taskStatus: number, nodeType: NodeTypeEnum) => {
  if (taskStatus === TaskStatusEnum.NOT_START) {
    return statusIconMap[taskStatus]?.icon || 'mdi:clock-outline';
  }

  if (
    nodeType === NodeTypeEnum.START_USER_NODE ||
    nodeType === NodeTypeEnum.USER_TASK_NODE ||
    nodeType === NodeTypeEnum.TRANSACTOR_NODE ||
    nodeType === NodeTypeEnum.CHILD_PROCESS_NODE ||
    nodeType === NodeTypeEnum.END_EVENT_NODE
  ) {
    return statusIconMap[taskStatus]?.icon || 'mdi:clock-outline';
  }
  return 'mdi:clock-outline';
};

// 获取审批节点颜色
const getApprovalNodeColor = (taskStatus: number) => {
  return statusIconMap[taskStatus]?.color;
};

// 获取审批节点时间
const getApprovalNodeTime = (node: BpmProcessInstanceApi.ApprovalNodeInfo) => {
  if (node.nodeType === NodeTypeEnum.START_USER_NODE && node.startTime) {
    return formatDateTime(node.startTime);
  }
  if (node.endTime) {
    return formatDateTime(node.endTime);
  }
  if (node.startTime) {
    return formatDateTime(node.startTime);
  }
  return '';
};

// 选择自定义审批人
const userSelectFormRef = ref();
const customApproveUsers = ref<Record<string, any[]>>({}); // key：activityId，value：用户列表

// 打开选择用户弹窗
const handleSelectUser = (activityId: string, selectedList: any[]) => {
  console.log(userSelectFormRef.value);
  userSelectFormRef.value.open(activityId, selectedList);
};

// 选择用户完成
const selectedUsers = ref<number[]>([]);
const handleUserSelectConfirm = (activityId: string, userList: any[]) => {
  customApproveUsers.value[activityId] = userList || [];
  emit('selectUserConfirm', activityId, userList);
};

/** 跳转子流程 */
const handleChildProcess = (activity: any) => {
  push({
    name: 'BpmProcessInstanceDetail',
    query: {
      id: activity.processInstanceId,
    },
  });
};

// 渲染用户头像和昵称
const renderUserAvatar = (user: any) => {
  if (!user) return null;

  return h('div', {}, [
    user.avatar
      ? h(Avatar, {
          class: '!m-[5px]',
          size: 28,
          src: user.avatar,
        })
      : h(
          Avatar,
          {
            class: '!m-[5px]',
            size: 28,
          },
          {
            default: () => user.nickname?.slice(0, 1),
          },
        ),
    h('span', { class: 'text-[13px]' }, user.nickname),
  ]);
};

// 判断是否需要显示自定义选择审批人
const shouldShowCustomUserSelect = (
  activity: BpmProcessInstanceApi.ApprovalNodeInfo,
) => {
  return (
    isEmpty(activity.tasks) &&
    isEmpty(activity.candidateUsers) &&
    (CandidateStrategyEnum.START_USER_SELECT === activity.candidateStrategy ||
      CandidateStrategyEnum.APPROVE_USER_SELECT === activity.candidateStrategy)
  );
};

// 判断是否需要显示审批意见
const shouldShowApprovalReason = (task: any, nodeType: NodeTypeEnum) => {
  return (
    task.reason &&
    [NodeTypeEnum.END_EVENT_NODE, NodeTypeEnum.USER_TASK_NODE].includes(
      nodeType,
    )
  );
};
</script>

<template>
  <a-timeline class="pt-20px">
    <!-- 遍历每个审批节点 -->
    <a-timeline-item
      v-for="(activity, index) in activityNodes"
      :key="index"
      :color="getApprovalNodeColor(activity.status)"
    >
      <template #dot>
        <div class="relative">
          <div
            class="position-absolute left--10px top--6px flex h-[32px] w-[32px] items-center justify-center rounded-full border border-solid border-[#dedede] bg-[#3f73f7] p-[6px]"
          >
            <IconifyIcon
              :icon="getApprovalNodeTypeIcon(activity.nodeType)"
              class="size-[24px] text-white"
            />
          </div>

          <div
            v-if="showStatusIcon"
            class="absolute right-[-10px] top-[18px] flex size-[20px] items-center rounded-full border-[2px] border-solid border-white p-[2px]"
            :style="{ backgroundColor: getApprovalNodeColor(activity.status) }"
          >
            <IconifyIcon
              :icon="getApprovalNodeIcon(activity.status, activity.nodeType)"
              class="text-white"
              :class="[statusIconMap[activity.status]?.animation]"
            />
          </div>
        </div>
      </template>

      <div
        class="ml-2 flex flex-col items-start gap-2"
        :id="`activity-task-${activity.id}-${index}`"
      >
        <!-- 第一行：节点名称、时间 -->
        <div class="flex w-full">
          <div class="font-bold">{{ activity.name }}</div>
          <!-- 信息：时间 -->
          <div
            v-if="activity.status !== TaskStatusEnum.NOT_START"
            class="ml-auto mt-1 text-[13px] text-[#a5a5a5]"
          >
            {{ getApprovalNodeTime(activity) }}
          </div>
        </div>

        <!-- 子流程节点 -->
        <div v-if="activity.nodeType === NodeTypeEnum.CHILD_PROCESS_NODE">
          <Button
            type="primary"
            ghost
            size="small"
            @click="handleChildProcess(activity)"
          >
            查看子流程
          </Button>
        </div>

        <!-- 需要自定义选择审批人 -->
        <div
          v-if="true || shouldShowCustomUserSelect(activity)"
          class="flex flex-wrap items-center gap-2"
        >
          <Tooltip title="添加用户" placement="left">
            <Button
              type="primary"
              size="middle"
              ghost
              @click="
                handleSelectUser(activity.id, customApproveUsers[activity.id])
              "
            >
              <template #icon>
                <IconifyIcon
                  icon="mdi:account-plus-outline"
                  class="size-[18px]"
                />
              </template>
            </Button>
          </Tooltip>
          <div
            v-for="(user, userIndex) in customApproveUsers[activity.id]"
            :key="userIndex"
            class="relative flex h-[36px] items-center gap-2 rounded-3xl bg-gray-100 pr-[8px] dark:bg-gray-600"
          >
            {{ renderUserAvatar(user) }}
          </div>
        </div>

        <div v-else class="mt-1 flex flex-wrap items-center gap-2">
          <!-- 情况一：遍历每个审批节点下的【进行中】task 任务 -->
          <div
            v-for="(task, idx) in activity.tasks"
            :key="idx"
            class="flex flex-col gap-2 pr-[8px]"
          >
            <div
              class="relative flex flex-wrap gap-2"
              v-if="task.assigneeUser || task.ownerUser"
            >
              <!-- 信息：头像昵称 -->
              <div
                class="h-35px relative flex items-center rounded-3xl bg-gray-100 pr-[8px] dark:bg-gray-600"
              >
                <template
                  v-if="
                    task.assigneeUser?.avatar || task.assigneeUser?.nickname
                  "
                >
                  <Avatar
                    class="!m-[5px]"
                    :size="28"
                    v-if="task.assigneeUser?.avatar"
                    :src="task.assigneeUser?.avatar"
                  />
                  <Avatar class="!m-[5px]" :size="28" v-else>
                    {{ task.assigneeUser?.nickname.substring(0, 1) }}
                  </Avatar>
                  {{ task.assigneeUser?.nickname }}
                </template>
                <template
                  v-else-if="task.ownerUser?.avatar || task.ownerUser?.nickname"
                >
                  <Avatar
                    class="!m-[5px]"
                    :size="28"
                    v-if="task.ownerUser?.avatar"
                    :src="task.ownerUser?.avatar"
                  />
                  <Avatar class="!m-[5px]" :size="28" v-else>
                    {{ task.ownerUser?.nickname.substring(0, 1) }}
                  </Avatar>
                  {{ task.ownerUser?.nickname }}
                </template>

                <!-- 信息：任务状态图标 -->
                <div
                  v-if="
                    showStatusIcon && onlyStatusIconShow.includes(task.status)
                  "
                  class="absolute left-[24px] top-[20px] flex items-center rounded-full border-2 border-solid border-white p-[2px]"
                  :style="{
                    backgroundColor: statusIconMap[task.status]?.color,
                  }"
                >
                  <IconifyIcon
                    :icon="
                      statusIconMap[task.status]?.icon || 'mdi:clock-outline'
                    "
                    class="size-[10px] text-white"
                    :class="[statusIconMap[task.status]?.animation]"
                  />
                </div>
              </div>
            </div>

            <!-- 审批意见和签名 -->
            <teleport defer :to="`#activity-task-${activity.id}-${index}`">
              <div
                v-if="shouldShowApprovalReason(task, activity.nodeType)"
                class="mt-1 w-full rounded-md bg-[#f8f8fa] p-2 text-[13px] text-[#a5a5a5]"
              >
                审批意见：{{ task.reason }}
              </div>
              <div
                v-if="
                  task.signPicUrl &&
                  activity.nodeType === NodeTypeEnum.USER_TASK_NODE
                "
                class="mt-1 w-full rounded-md bg-[#f8f8fa] p-2 text-[13px] text-[#a5a5a5]"
              >
                签名：
                <Image
                  class="ml-[5px] h-[40px] w-[90px]"
                  :src="task.signPicUrl"
                  :preview="{ src: task.signPicUrl }"
                />
              </div>
            </teleport>
          </div>

          <!-- 情况二：遍历每个审批节点下的【候选的】task 任务 -->
          <div
            v-for="(user, userIndex) in activity.candidateUsers"
            :key="userIndex"
            class="relative flex h-[35px] items-center rounded-3xl bg-gray-100 pr-[8px] dark:bg-gray-600"
          >
            <Avatar
              class="!m-[5px]"
              :size="28"
              v-if="user.avatar"
              :src="user.avatar"
            />
            <Avatar class="!m-[5px]" :size="28" v-else>
              {{ user.nickname.substring(0, 1) }}
            </Avatar>
            <span class="text-[13px]">
              {{ user.nickname }}
            </span>

            <!-- 候选任务状态图标 -->
            <div
              v-if="showStatusIcon"
              class="absolute left-[24px] top-[20px] flex items-center rounded-full border-2 border-solid border-white p-[1px]"
              :style="{ backgroundColor: statusIconMap['-1']?.color }"
            >
              <IconifyIcon
                class="text-[11px] text-white"
                :icon="statusIconMap['-1']?.icon || 'mdi:clock-outline'"
              />
            </div>
          </div>
        </div>
      </div>
    </a-timeline-item>
  </a-timeline>

  <!-- 用户选择弹窗 -->
  <UserSelectModal
    ref="userSelectFormRef"
    v-model:value="selectedUsers"
    :multiple="true"
    title="选择用户"
    @confirm="handleUserSelectConfirm"
  />
</template>
