/*
 * @Author: sunhaolin@hotoa.com 
 * @Date: 2022-03-26 09:40:49 
 * @Last Modified by: sunhaolin@hotoa.com
 * @Last Modified time: 2022-03-26 15:28:27
 */
'use strict';
// @ts-check
const express = require("express");
const router = express.Router();
const { requireAuthentication } = require("@steedos/auth");
const _ = require('lodash');
const { excuteTriggers } = require('../utils/trigger');
const objectql = require('@steedos/objectql');
const WorkflowManager = require('../manager/workflow_manager');
const UUFlowManager = require('../manager/uuflow_manager');
const { t } = require('@steedos/i18n');

const getFieldName = (fields, fieldId)=>{
    const field = _.find(fields, (item)=>{
        return item._id === fieldId
    });
    return field?.code || fieldId
}

const getFieldValue = (values, code)=>{
    return values[code]
}

const getFormFieldValue = (fields, values, fieldId)=>{
    const code = getFieldName(fields, fieldId);
    return getFieldValue(values, code);
}

/**
 * 计算下一步处理人
 * body {
 *   instanceId: 申请单ID
 *   nextStepId: 下一步步骤ID
 *   values: 最新的表单值
 * }
 */
router.post('/api/workflow/v2/nextStepUsers', requireAuthentication, async function (req, res) {
    try {
        let userSession = req.user;
        const userId = userSession.userId;
        const spaceId = userSession.spaceId;
        var error = "";

        if (!spaceId) {
            throw new Error('缺少参数')
        }

        var nextStepUsers = [];
        const {
            instanceId: insId,
            nextStepId,
            values
        } = req.body;

        let instance = await UUFlowManager.getInstance(insId);
        const [flow, form] = await Promise.all([
            UUFlowManager.getFlow(instance.flow),
            UUFlowManager.getForm(instance.form)
        ]);
        const [formVersion, nextStep] = await Promise.all([
            UUFlowManager.getFormVersion(form, instance.form_version),
            UUFlowManager.getStep(instance, flow, nextStepId)
        ]);
        const formFields = formVersion.fields;
        switch (nextStep.step_type) {
            case 'start':
                var applicantId = instance.applicant;
                nextStepUsers = await WorkflowManager.getUsers(spaceId, applicantId);
                break;
            default:
                switch (nextStep.deal_type) {
                    case 'specifyUser':
                        var specifyUserIds = nextStep.approver_users;
                        nextStepUsers = await WorkflowManager.getUsers(spaceId, specifyUserIds);
                        break;
                    case 'applicantRole':
                        var
                            applicantId = instance.applicant,
                            approveRoleIds = nextStep.approver_roles;
                        var applicant = await WorkflowManager.getUser(spaceId, applicantId);

                        if (applicant)
                            nextStepUsers = await WorkflowManager.getRoleUsersByOrgsAndRoles(spaceId, applicant.organizations, approveRoleIds);
                        if(!nextStepUsers || nextStepUsers.length < 1){
                            const roles = await WorkflowManager.getRoles(instance.space, approveRoleIds);
                            error = t('next_step_users_not_found.applicant_role', {role_name: _.join(_.map(roles, 'name'), ', ')}, userSession.language)
                        }
                        break;
                    case 'hrRole':
                        var approveHrRoleIds = nextStep.approver_hr_roles;
                        if (approveHrRoleIds)
                            nextStepUsers = await WorkflowManager.getHrRolesUsers(spaceId, approveHrRoleIds);
                        break;
                    case 'applicantSuperior':
                        var applicantId = instance.applicant;
                        var applicant = await WorkflowManager.getUser(spaceId, applicantId);
                        if (applicant.manager) {
                            nextStepUsers = await WorkflowManager.getUsers(spaceId, applicant.manager);
                        }
                        break;
                    case 'applicant':
                        var applicantId = instance.applicant;
                        nextStepUsers = await WorkflowManager.getUsers(spaceId, applicantId);
                        break;
                    case 'userField':
                        var
                            userField = nextStep.approver_user_field,
                            userFieldValue = getFormFieldValue(formFields, values, userField);
                        if(userFieldValue){
                            if (_.isArray(userFieldValue)) { //如果多选，以userFieldValue值为Array
                                nextStepUsers = await WorkflowManager.getUsers(spaceId, userFieldValue);
                            } else {
                                nextStepUsers.push(await WorkflowManager.getUser(spaceId, userFieldValue));
                            }
                        }else {
                            error = "请先填写表单值";
                        }
                        
                        break;
                    case 'orgField':
                        var
                            orgs,
                            orgChildrens,
                            orgField = nextStep.approver_org_field,
                            orgFieldValue = getFormFieldValue(formFields, values, orgField);
                        if (orgFieldValue) {
                            if (_.isArray(orgFieldValue)) { //如果多选，以orgFieldValue值为Array
                                orgs = await WorkflowManager.getOrganizations(orgFieldValue);
                                orgChildrens = await WorkflowManager.getOrganizationsChildrens(spaceId, orgFieldValue);
                            } else {
                                orgs = [await WorkflowManager.getOrganization(orgFieldValue)];
                                orgChildrens = await WorkflowManager.getOrganizationChildrens(spaceId, orgFieldValue);
                            }
                            nextStepUsers = await WorkflowManager.getOrganizationsUsers(spaceId, orgChildrens);

                            const orgFieldUsers = await WorkflowManager.getOrganizationsUsers(spaceId, orgs);

                            nextStepUsers = nextStepUsers.concat(orgFieldUsers);

                            if (!nextStepUsers || nextStepUsers.length < 1) {
                                error = "ORG_NO_MEMBERS";
                            }
                        } else {
                            error = "请先填写表单值";
                        }

                        break;
                    case 'specifyOrg':
                        var specifyOrgIds = nextStep.approver_orgs;
                        var specifyOrgs = await WorkflowManager.getOrganizations(specifyOrgIds);
                        var specifyOrgChildrens = await WorkflowManager.getOrganizationsChildrens(spaceId, specifyOrgIds);

                        nextStepUsers = await WorkflowManager.getOrganizationsUsers(spaceId, specifyOrgs);
                        nextStepUsers = nextStepUsers.concat(await WorkflowManager.getOrganizationsUsers(spaceId, specifyOrgChildrens));
                        break;
                    case 'userFieldRole':
                        var
                            userField = nextStep.approver_user_field,
                            userFieldValue = getFormFieldValue(formFields, values, userField),
                            approverRoleIds = nextStep.approver_roles;
                        if (userFieldValue) {
                            if (_.isArray(userFieldValue)) { //如果多选，以userFieldValue值为Array
                                nextStepUsers = await WorkflowManager.getRoleUsersByUsersAndRoles(spaceId, userFieldValue, approverRoleIds);
                            } else {
                                nextStepUsers = await WorkflowManager.getRoleUsersByUsersAndRoles(spaceId, [userFieldValue], approverRoleIds);
                            }

                            if (!nextStepUsers || nextStepUsers.length < 1) {
                                const roles = await WorkflowManager.getRoles(instance.space, approverRoleIds);
                                error = t('next_step_users_not_found.applicant_role', {role_name: _.join(_.map(roles, 'name'), ', ')}, userSession.language)
                            }
                        } else {
                            error = "请先填写表单值";
                        }


                        break;
                    case 'orgFieldRole':
                        var
                            orgField = nextStep.approver_org_field,
                            orgFieldValue = getFormFieldValue(formFields, values, orgField),
                            approverRoleIds = nextStep.approver_roles;

                        if (orgFieldValue) {
                            if (_.isArray(orgFieldValue)) { //如果多选，以orgFieldValue值为Array
                                nextStepUsers = await WorkflowManager.getRoleUsersByOrgsAndRoles(spaceId, orgFieldValue, approverRoleIds);
                            } else {
                                nextStepUsers = await WorkflowManager.getRoleUsersByOrgsAndRoles(spaceId, [orgFieldValue], approverRoleIds);
                            }

                            if (!nextStepUsers || nextStepUsers.length < 1) {
                               
                                const roles = await WorkflowManager.getRoles(instance.space, approverRoleIds);
                                 console.log(`approverRoleIds`, approverRoleIds, roles)
                                error = t('next_step_users_not_found.applicant_role', {role_name: _.join(_.map(roles, 'name'), ', ')}, userSession.language)
                            }
                        } else {
                            error = "请先填写表单值";
                        }
                        break;
                    default:
                        break;
                }
                break;
        }


        var result = [];

        nextStepUsers.forEach(function (su) {
            if (su.user_accepted) {
                var o = {
                    id: su.id,
                    name: su.name
                };
                result.push(o);
            }
        });
        let finalNextStepUsers = await WorkflowManager.uniqUsers(result);
        // cacluateNextStepUsers
        
        let nextUserIds = _.map(finalNextStepUsers, 'id');
        await excuteTriggers({ when: 'cacluateNextStepUsers', userId: userId, flowId: instance.flow, insId: insId, nextStep: nextStep, nextUserIds });
        let nextUsersDocs = await objectql.getObject('space_users').find({ filters: [ ['space', '=', spaceId], ['user', 'in', nextUserIds] ], fields: ['name','user'] });
        let newNextUsers = [];
        for(const doc of nextUsersDocs) {
            newNextUsers.push({
                id: doc.user,
                name: doc.name
            });
        }
        res.status(200).send({
            'nextStepUsers': newNextUsers,
            'error': error
        });
        
    } catch (error) {
        console.error(error);
        res.status(200).send({
            error: error.message
        });
    }
});

router.post('/api/workflow/v2/nextStepUsersValue', requireAuthentication, async function (req, res) {
    try {
        let userSession = req.user;
        const userId = userSession.userId;
        const spaceId = userSession.spaceId;
        var error = "";

        if (!spaceId) {
            throw new Error('缺少参数')
        }

        const { instanceId, nextStepId } = req.body;

        let instance = await UUFlowManager.getInstance(instanceId);
        const step_approve = instance.step_approve || {};
        const newNextUsers = step_approve[nextStepId] || []
        res.status(200).send({
            'value': newNextUsers,
            'error': error
        });
    } catch (error) {
        console.error(error);
        res.status(200).send({
            error: error.message
        });
    }
});

exports.default = router;