/*
 * @Author: sunhaolin@hotoa.com
 * @Date: 2022-12-24 14:38:27
 * @LastEditors: 孙浩林 sunhaolin@steedos.com
 * @LastEditTime: 2025-10-08 14:50:07
 * @Description: 
 */
'use strict';
// @ts-check
const express = require('express');
const router = express.Router();
const { requireAuthentication } = require("@steedos/auth");
const _ = require('underscore');
const {
    remove_many_instance_tasks,
    insert_many_instance_tasks,
} = require('../manager/instance_tasks_manager')
const PermissionManager = require('../manager/permission_manager');
const UUFlowManager = require('../manager/uuflow_manager');
const pushManager = require('../manager/push_manager');
const { getCollection, _makeNewID } = require('../utils/collection');
/**
@api {post} /api/workflow/reassign 接口说明
@apiVersion 0.0.0
@apiName /api/workflow/reassign
@apiGroup service-workflow
@apiBody {Object[]} Instances 申请单信息
@apiSuccessExample {json} Success-Response:
    HTTP/1.1 200 OK
    {
    }
@apiErrorExample {json} Error-Response:
    HTTP/1.1 200 OK
    {
      errors: [{ errorMessage: e.message }]
    }
 */
router.post('/api/workflow/reassign', requireAuthentication, async function (req, res) {
    try {
        let userSession = req.user;
        var current_user, current_user_info, hashData;
        current_user_info = Object.assign({}, userSession, { _id: userSession.userId })
        current_user = current_user_info._id;
        const { is_space_admin } = userSession;
        hashData = req.body;

        const instancesCollection = await getCollection('instances');
        const usersCollection = await getCollection('users');
        const spaceUsersCollection = await getCollection('space_users');
        const organizationsCollection = await getCollection('organizations');

        for (const instance_from_client of hashData['Instances']) { 
            var _users, approve_users_handlers, assignee_appr, current_space_user, current_user_organization, i, inbox_users, inbox_users_from_client, ins, instance, instance_id, last_trace, last_trace_from_client, new_inbox_users, not_in_inbox_users, now, permissions, r, reassign_reason, setObj, space, space_id;
            instance_id = instance_from_client['_id'];
            instance = await UUFlowManager.getInstance(instance_id);
            space_id = instance.space;
            // 验证instance为审核中状态
            await UUFlowManager.isInstancePending(instance);
            // 验证当前执行转签核的trace未结束
            last_trace_from_client = _.last(instance["traces"]);
            last_trace = _.find(instance.traces, function (t) {
                return t._id === last_trace_from_client["_id"];
            });
            if (last_trace.is_finished === true) {
                continue;
            }
            // 验证login user_id对该流程有管理申请单的权限
            permissions = await PermissionManager.getFlowPermissions(instance.flow, current_user);
            
            if ((!permissions.includes("admin")) && !is_space_admin) {
                throw new Error("用户没有对当前流程的管理权限");
            }
            inbox_users = instance.inbox_users;
            inbox_users_from_client = instance_from_client["inbox_users"];
            reassign_reason = instance_from_client["reassign_reason"];
            not_in_inbox_users = _.difference(inbox_users, inbox_users_from_client);
            new_inbox_users = _.difference(inbox_users_from_client, inbox_users);
            // 若assignee=原inbox_users，说明不需要执行转签核，系统什么都不做
            if (not_in_inbox_users.length === 0 && new_inbox_users.length === 0) {
                continue;
            }
            setObj = new Object;
            now = new Date;
            const finishedApproveIds = []
            const newApproveIds = []
            i = 0;
            approve_users_handlers = [];
            while (i < last_trace.approves.length) {
                if (not_in_inbox_users.includes(last_trace.approves[i].handler)) {
                    if (last_trace.approves[i].is_finished === false && last_trace.approves[i].type !== "cc" && last_trace.approves[i].type !== "distribute") {
                        last_trace.approves[i].is_finished = true;
                        last_trace.approves[i].finish_date = now;
                        last_trace.approves[i].judge = "terminated";
                        last_trace.approves[i].description = "";
                        last_trace.approves[i].cost_time = last_trace.approves[i].finish_date - last_trace.approves[i].start_date;
                        approve_users_handlers.push(last_trace.approves[i].user);
                        approve_users_handlers.push(last_trace.approves[i].handler);
                        finishedApproveIds.push(last_trace.approves[i]._id)
                    }
                }
                i++;
            }
            // 在同一trace下插入转签核操作者的approve记录
            current_space_user = await UUFlowManager.getSpaceUser(space_id, current_user);

            current_user_organization = await organizationsCollection.findOne({ _id: current_space_user.organization }, {
                projection: {
                    name: 1,
                    fullname: 1
                }
            })

            assignee_appr = new Object;
            assignee_appr._id = _makeNewID();
            assignee_appr.instance = last_trace.instance;
            assignee_appr.trace = last_trace._id;
            assignee_appr.is_finished = true;
            assignee_appr.user = current_user;
            assignee_appr.user_name = current_user_info.name;
            assignee_appr.handler = current_user;
            assignee_appr.handler_name = current_user_info.name;
            assignee_appr.handler_organization = current_space_user.organization;
            assignee_appr.handler_organization_name = current_user_organization.name;
            assignee_appr.handler_organization_fullname = current_user_organization.fullname;
            assignee_appr.start_date = now;
            assignee_appr.finish_date = now;
            assignee_appr.due_date = last_trace.due_date;
            assignee_appr.read_date = now;
            assignee_appr.judge = "reassigned";
            assignee_appr.is_read = true;
            assignee_appr.description = reassign_reason;
            assignee_appr.is_error = false;
            assignee_appr.values = new Object;
            assignee_appr.cost_time = assignee_appr.finish_date - assignee_appr.start_date;
            last_trace.approves.push(assignee_appr);
            // 对新增的每位待审核人，各增加一条新的approve
            for (const user_id of new_inbox_users) {
                var agent, handler_id, handler_info, new_appr, new_user, space_user, user_organization;

                new_user = await usersCollection.findOne({ _id: user_id }, {
                    projection: {
                        name: 1
                    }
                })

                space_user = await UUFlowManager.getSpaceUser(space_id, user_id);

                user_organization = await organizationsCollection.findOne({ _id: space_user.organization }, {
                    projection: {
                        name: 1,
                        fullname: 1
                    }
                })

                new_appr = new Object;
                new_appr._id = _makeNewID();
                new_appr.instance = last_trace.instance;
                new_appr.trace = last_trace._id;
                new_appr.is_finished = false;
                new_appr.user = user_id;
                new_appr.user_name = new_user.name;
                handler_id = user_id;
                handler_info = new_user;
                agent = await UUFlowManager.getAgent(space_id, user_id);
                if (agent) {
                    inbox_users_from_client[inbox_users_from_client.indexOf(user_id)] = agent;
                    handler_id = agent;

                    handler_info = await usersCollection.findOne({ _id: agent }, {
                        projection: {
                            name: 1
                        }
                    })

                    new_appr.agent = agent;
                }
                new_appr.handler = handler_id;
                new_appr.handler_name = handler_info.name;
                new_appr.handler_organization = space_user.organization;
                new_appr.handler_organization_name = user_organization.name;
                new_appr.handler_organization_fullname = user_organization.fullname;
                new_appr.from_user = current_user;
                new_appr.from_user_name = current_user_info.name;
                new_appr.type = "reassign";
                new_appr.start_date = now;
                new_appr.due_date = last_trace.due_date;
                new_appr.is_read = false;
                new_appr.is_error = false;
                new_appr.values = new Object;
                await UUFlowManager.setRemindInfo(instance.values, new_appr);
                last_trace.approves.push(new_appr);
                newApproveIds.push(new_appr._id)
            };
            instance.outbox_users.push(current_user);
            instance.outbox_users = instance.outbox_users.concat(approve_users_handlers);
            setObj.outbox_users = _.uniq(instance.outbox_users);
            setObj.inbox_users = inbox_users_from_client;
            setObj.modified = now;
            setObj.modified_by = current_user;
            setObj["traces.$.approves"] = last_trace.approves;

            r = await instancesCollection.updateOne({
                _id: instance_id,
                "traces._id": last_trace._id
            }, {
                $set: setObj,
            });

            // 删除当前结束的approve
            await remove_many_instance_tasks(finishedApproveIds)
            // 生成新待审核的approve
            await insert_many_instance_tasks(instance_id, last_trace._id, newApproveIds)

            if (r) {
                ins = await UUFlowManager.getInstance(instance_id);
                // 给被删除的inbox_users 和 当前用户 发送push
                await pushManager.send_message_current_user(current_user_info);
                for (const user_id of not_in_inbox_users) {
                    if (user_id !== current_user) {
                        await pushManager.send_message_to_specifyUser("current_user", user_id);
                    }
                };
                // 提取instances.outbox_users数组和填单人、申请人
                _users = new Array;
                _users.push(ins.applicant);
                _users.push(ins.submitter);
                _users = _.uniq(_users.concat(ins.outbox_users));
                for (const user_id of _users) {
                    await pushManager.send_message_to_specifyUser("current_user", user_id);
                };
                // 给新加入的inbox_users发送push message
                await pushManager.send_instance_notification("reassign_new_inbox_users", ins, reassign_reason, current_user_info);
                // 如果已经配置webhook并已激活则触发
                await pushManager.triggerWebhook(ins.flow, ins, {}, 'reassign', current_user, ins.inbox_users);
            }
        };

        res.status(200).send({
            status: 0,
            data: {}
        });
    } catch (e) {
        console.log(e);
        res.status(200).send({
            status: -1,
            msg: e.message,
            data: {}
        });
    }
});
exports.default = router;
