package com.yunzhupaas.flowable.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.Pagination;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.DataInterfaceEntity;
import com.yunzhupaas.base.entity.DictionaryDataEntity;
import com.yunzhupaas.base.entity.VisualdevEntity;
import com.yunzhupaas.base.model.VisualDevJsonModel;
import com.yunzhupaas.base.model.flow.DataModel;
import com.yunzhupaas.base.model.flow.FlowFormDataModel;
import com.yunzhupaas.base.model.schedule.ScheduleNewCrForm;
import com.yunzhupaas.base.model.systemconfig.SysConfigModel;
import com.yunzhupaas.base.service.*;
import com.yunzhupaas.base.util.SentMessageUtil;
import com.yunzhupaas.base.vo.DownloadVO;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.emnus.ModuleTypeEnum;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.extend.service.DocumentApi;
import com.yunzhupaas.flowable.entity.TemplateEntity;
import com.yunzhupaas.flowable.model.template.TemplateExportModel;
import com.yunzhupaas.flowable.model.util.FlowContextHolder;
import com.yunzhupaas.flowable.model.util.FlowNature;
import com.yunzhupaas.message.model.SentMessageForm;
import com.yunzhupaas.message.service.SendMessageConfigService;
import com.yunzhupaas.model.document.FlowFileModel;
import com.yunzhupaas.model.login.UserSystemVO;
import com.yunzhupaas.onlinedev.model.PaginationModel;
import com.yunzhupaas.base.model.OnlineImport.VisualdevModelDataInfoVO;
import com.yunzhupaas.onlinedev.model.VisualParamModel;
import com.yunzhupaas.permission.constant.AuthorizeConst;
import com.yunzhupaas.permission.entity.*;
import com.yunzhupaas.permission.model.organizeadministrator.OrganizeAdministratorModel;
import com.yunzhupaas.permission.model.user.UserIdListVo;
import com.yunzhupaas.permission.service.*;
import com.yunzhupaas.util.DataFileExport;
import com.yunzhupaas.util.GeneraterSwapUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.enums.DictionaryDataEnum;
import com.yunzhupaas.visual.service.VisualdevApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static com.yunzhupaas.util.Constants.ADMIN_KEY;

@Component
public class ServiceUtil {
    @Autowired
    private DictionaryDataService dictionaryDataService;
    @Autowired
    private UserRelationService userRelationService;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private OrganizeAdministratorService organizeAdministratorService;
    @Autowired
    private PositionService positionService;
    @Autowired
    private BillRuleService billRuleService;
    @Autowired
    private DataInterfaceService dataInterfaceService;
    @Autowired
    private SentMessageUtil sentMessageUtil;
    @Lazy
    @Autowired
    private FlowAsyncUtil flowAsyncUtil;
    @Autowired
    private SendMessageConfigService sendMessageConfigService;
    @Autowired
    private DataFileExport fileExport;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private CommonWordsService commonWordsService;
    @Autowired
    private SignService signService;

    @Autowired
    private PermissionGroupService permissionGroupService;
    @Autowired
    private AuthorizeService authorizeService;

    @Autowired
    private VisualdevApi visualdevApi;
    @Autowired
    private DocumentApi documentApi;
    @Autowired
    private GeneraterSwapUtil generaterSwapUtil;
    @Autowired
    private SystemConfigApi systemConfigApi;
    @Autowired
    private ScheduleNewApi scheduleNewApi;

    // 创建日程
    public void createSchedule(ScheduleNewCrForm fo) throws WorkFlowException {
        ActionResult result = scheduleNewApi.create(fo);
        if (result.getCode() != 200) {
            throw new WorkFlowException(result.getMsg());
        }
    }

    // 获取系统配置
    public SysConfigModel getSysConfig() {
        ActionResult<SysConfigModel> actionResult = systemConfigApi.list();
        return actionResult.getData();
    }

    // 获取系统配置，流程签收
    public Boolean getFlowSign() {
        ActionResult<SysConfigModel> actionResult = systemConfigApi.list();
        SysConfigModel data = actionResult.getData();
        return data.getFlowSign() == 0;
    }

    // 获取系统配置，流程办理
    public Boolean getFlowTodo() {
        ActionResult<SysConfigModel> actionResult = systemConfigApi.list();
        SysConfigModel data = actionResult.getData();
        return data.getFlowTodo() == 0;
    }

    // 流水号
    public String getBillNumber() {
        return generaterSwapUtil.getBillNumber(FlowNature.REVOKE_BILL_CODE, false);
    }

    // -------------------------------签名-----------------------------
    public void updateSign(String signId, String signImg) {
        SignEntity signEntity = signService.getById(signId);
        if (null != signEntity) {
            signService.updateDefault(signId);
        } else {
            signEntity = new SignEntity();
            signEntity.setIsDefault(1);
            signEntity.setSignImg(signImg);
            signService.create(signEntity);
        }
    }

    // -------------------------------常用语-----------------------------
    public void addCommonWordsNum(String handleOpinion) {
        commonWordsService.addCommonWordsNum(handleOpinion);
    }

    // -------------------------------文件-----------------------------
    // 判断是否存在归档文件，不存在为true
    public Boolean checkFlowFile(String taskId) {
        return documentApi.checkFlowFile(taskId);
    }

    // 获取归档文件
    public List<Map<String, Object>> getFlowFile(FlowFileModel model) {
        return documentApi.getFlowFile(model);
    }

    // -------------------------------发起权限-----------------------------
    public List<String> getLaunchPermission(String userId) {
        List<String> resList = new ArrayList<>();
        List<PermissionGroupEntity> groups = permissionGroupService.getPermissionGroupByUserId(userId, null, false, null);
        if (CollectionUtil.isNotEmpty(groups)) {
            List<String> objectIds = groups.stream().map(PermissionGroupEntity::getId).collect(Collectors.toList());
            resList = authorizeService.getListByObjectId(objectIds)
                    .stream().filter(t -> AuthorizeConst.FLOW.equals(t.getItemType())).map(AuthorizeEntity::getItemId).collect(Collectors.toList());
        }
        return resList;
    }

    // true是普通用户
    public boolean isCommonUser(String userId) {
        List<UserSystemVO> userStanding = authorizeService.getUserStanding(false, userId);
        return userStanding.stream().anyMatch(t -> "3".equals(t.getId()));
    }

    // true是分管
    public boolean isOrgAdmin(String userId) {
        List<UserSystemVO> userStanding = authorizeService.getUserStanding(true, userId);
        return userStanding.stream().anyMatch(t -> "2".equals(t.getId()));
    }

    // 获取流程有发起权限的人员
    public List<UserEntity> getLaunchUserByTemplateId(TemplateEntity template, Pagination pagination) {
        if (ObjectUtil.equals(template.getVisibleType(), 1)) {
            // 公开直接返回用户分页
            return userService.getUserPage(pagination);
        }

        // 根据流程主键、权限为流程类型 获取权限关联
        List<AuthorizeEntity> flowAuthList = authorizeService.getListByObjectAndItemIdAndType(template.getId(), AuthorizeConst.FLOW);
        // 获取权限组
        List<String> groupIds = flowAuthList.stream().map(AuthorizeEntity::getObjectId).collect(Collectors.toList());
        List<PermissionGroupEntity> permissionGroupList = permissionGroupService.list(true, groupIds);
        permissionGroupList = permissionGroupList.stream().filter(e -> ObjectUtil.equals(e.getEnabledMark(), 1)).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(permissionGroupList)) {
            return new ArrayList<>();
        }

        List<String> userIdList = new ArrayList<>();
        for (PermissionGroupEntity permission : permissionGroupList) {
            if (permission.getType() != null && permission.getType().equals(1)) {
                // 自定义
                String permissionMember = permission.getPermissionMember();
                if (StringUtil.isNotEmpty(permissionMember)) {
                    String[] split = permissionMember.split(",");
                    userIdList.addAll(Arrays.stream(split).collect(Collectors.toList()));
                }
            } else {
                // 全部成员，直接分页返回
                List<UserEntity> userPage = userService.getUserPage(pagination);
                return userPage;
            }
        }
        List<String> userListAll = this.getUserListAll(userIdList);
        return this.getUserName(userListAll, pagination);
    }

    //--------------------------------表单------------------------------
    public VisualdevEntity getFormInfo(String id) {
        return visualdevApi.getFormConfig(id);
    }

    public List<VisualdevEntity> getFormList(List<String> formIds) {
        if (formIds.isEmpty()) {
            return new ArrayList<>();
        }
        return visualdevApi.getFormConfigList(formIds);
    }

    public void saveOrUpdateFormData(FlowFormDataModel model) throws WorkFlowException {
        ActionResult actionResult = visualdevApi.saveOrUpdate(model);
        if (actionResult.getCode() != 200) {
            throw new WorkFlowException(actionResult.getMsg());
        }
    }

    public void deleteFormData(String formId, String id) throws Exception {
        if (StringUtil.isBlank(formId) || StringUtil.isBlank(id)) {
            return;
        }
        try {
            visualdevApi.delete(formId, id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Map<String, Object> infoData(String formId, String id) throws WorkFlowException {
        // 流程调用表单接口
        Map<String, Object> dataAll = new HashMap<>();
        if (StringUtil.isNotEmpty(formId) && StringUtil.isNotEmpty(id)) {
            ActionResult result = visualdevApi.info(formId, id);
            if (null != result && null != result.getData()) {
                dataAll = (Map<String, Object>) result.getData();
            }
        }
        return dataAll;
    }

    public void handleFormData(String flowId, Boolean isTransfer) throws WorkFlowException {
        try {
            Map<String, Map<String, Object>> allData = FlowContextHolder.getAllData();
            Map<String, List<Map<String, Object>>> formOperates = FlowContextHolder.getFormOperates();
            List<String> writeIdList = FlowContextHolder.getWriteIdList();
            for (String key : writeIdList) {
                String[] idList = key.split("_yunzhupaas_");
                List<Map<String, Object>> operates = formOperates.get(key);
                Map<String, Object> formData = allData.get(key);
                formData = formData == null ? new HashMap<>() : formData;
                FlowFormDataModel formDataModel = FlowFormDataModel.builder().formId(idList[1]).id(idList[0]).map(formData).formOperates(operates)
                        .flowId(flowId).isTransfer(isTransfer).build();
                this.saveOrUpdateFormData(formDataModel);
            }
        } catch (WorkFlowException e) {
            throw e;
        } finally {
            FlowContextHolder.clearAll();
        }
    }

    public VisualdevModelDataInfoVO getEditDataInfo(String id, VisualdevEntity visualdevEntity) {
        return visualdevApi.getEditDataInfo(id, visualdevEntity);
    }

    public List<Map<String, Object>> getListWithTableList(VisualDevJsonModel visualDevJsonModel, PaginationModel pagination, UserInfo userInfo) {
        return visualdevApi.getListWithTableList(visualDevJsonModel, pagination, userInfo);
    }

    public VisualdevEntity getReleaseInfo(String formId) {
        return visualdevApi.getReleaseInfo(formId);
    }

    public DataModel visualCreate(VisualdevEntity visualdevEntity, Map<String, Object> data) throws Exception {
        VisualParamModel visualParamModel = VisualParamModel.builder().visualdevEntity(visualdevEntity).data(data).build();
        return visualdevApi.visualCreate(visualParamModel);
    }

    public DataModel visualUpdate(VisualdevEntity visualdevEntity, Map<String, Object> data, String id) throws Exception {
        VisualParamModel visualParamModel = VisualParamModel.builder().visualdevEntity(visualdevEntity).data(data).id(id).onlyUpdate(true).build();
        return visualdevApi.visualUpdate(visualParamModel);
    }

    public void visualDelete(VisualdevEntity visualdevEntity, List<Map<String, Object>> dataList) throws Exception {
        VisualParamModel visualParamModel = VisualParamModel.builder().visualdevEntity(visualdevEntity).dataList(dataList).build();
        visualdevApi.visualDelete(visualParamModel);
    }

    public void deleteSubTable(FlowFormDataModel model) throws Exception {
        visualdevApi.deleteByTableName(model);
    }

    //--------------------------------数据字典------------------------------
    public List<DictionaryDataEntity> getDiList() {
        List<DictionaryDataEntity> dictionList = dictionaryDataService.getListByTypeDataCode(DictionaryDataEnum.FLOWWOEK_ENGINE.getDictionaryTypeId());
        return dictionList;
    }

    public List<DictionaryDataEntity> getDictionName(List<String> id) {
        List<DictionaryDataEntity> dictionList = dictionaryDataService.getDictionName(id);
        return dictionList;
    }

    //--------------------------------用户关系表------------------------------
    public List<UserRelationEntity> getListByUserIdAll(List<String> id) {
        List<UserRelationEntity> list = userRelationService.getListByUserIdAll(id).stream().filter(t -> StringUtil.isNotEmpty(t.getObjectId())).collect(Collectors.toList());
        return list;
    }

    public List<UserRelationEntity> getListByObjectIdAll(List<String> id) {
        List<UserRelationEntity> list = userRelationService.getListByObjectIdAll(id);
        return list;
    }

    public String getAdmin() {
        UserEntity admin = userService.getUserByAccount(ADMIN_KEY);
        return admin.getId();
    }

    //--------------------------------用户------------------------------
    public List<UserEntity> getUserByAccount(List<String> accountList) {
        List<UserEntity> list = new ArrayList<>();
        if (CollectionUtil.isEmpty(accountList)) {
            return list;
        }
        for (String account : accountList) {
            UserEntity user = userService.getUserByAccount(account);
            if (null != user) {
                list.add(user);
            }
        }
        return list;
    }

    public List<UserEntity> getUserName(List<String> id) {
        List<UserEntity> list = getUserName(id, false);
        return list;
    }

    public List<UserEntity> getListByManagerId(String managerId) {
        List<UserEntity> list = StringUtil.isNotEmpty(managerId) ? userService.getListByManagerId(managerId, null) : new ArrayList<>();
        return list;
    }

    public List<UserEntity> getUserName(List<String> id, boolean enableMark) {
        List<UserEntity> list = userService.getUserName(id);
        if (enableMark) list = list.stream().filter(t -> t.getEnabledMark() == 1).collect(Collectors.toList());
        return list;
    }

    public List<UserEntity> getUserName(List<String> id, Pagination pagination) {
        List<UserEntity> list = userService.getUserName(id, pagination);
        return list;
    }

    public UserEntity getUserInfo(String id) {
        UserEntity entity = null;
        if (StringUtil.isNotEmpty(id)) {
            entity = id.equalsIgnoreCase(ADMIN_KEY) ? userService.getUserByAccount(id) : userService.getInfo(id);
        }
        return entity;
    }

    public List<String> getUserListAll(List<String> idList) {
        List<String> userIdList = userService.getUserIdList(idList, null);
        return userIdList;
    }

    public List<UserEntity> getAdminList() {
        return userService.getAdminList();
    }

    public List<String> getOrganizeUserList(String type) {
        OrganizeAdministratorModel model = organizeAdministratorService.getOrganizeAdministratorList();
        Map<String, List<String>> map = new HashMap<>();
        map.put("select", model.getSelectList());
        map.put("add", model.getAddList());
        map.put("delete", model.getDeleteList());
        map.put("edit", model.getEditList());
        List<String> list = map.get(type) != null ? map.get(type) : new ArrayList<>();
        List<String> userList = userRelationService.getListByObjectIdAll(list).stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
        return userList;
    }

    public List<UserIdListVo> getUserList(List<String> userIds, Pagination pagination, String type) {
        List<UserIdListVo> list = userService.getObjList(userIds, pagination, type);
        return list;
    }

    //--------------------------------角色------------------------------
    public List<RoleEntity> getListByIds(List<String> id) {
        List<RoleEntity> list = roleService.getListByIds(id, null, false);
        return list;
    }

    public List<RoleEntity> getCurRolesByOrgId(String orgId) {
        List<RoleEntity> curRolesByOrgId = roleService.getCurRolesByOrgId(orgId);
        return curRolesByOrgId;
    }

    //--------------------------------组织------------------------------
    public List<OrganizeEntity> getOrganizeName(List<String> id) {
        List<OrganizeEntity> list = organizeService.getOrganizeName(id);
        return list;
    }

    public OrganizeEntity getOrganizeInfo(String id) {
        OrganizeEntity entity = StringUtil.isNotEmpty(id) ? organizeService.getInfo(id) : null;
        return entity;
    }

    public List<OrganizeEntity> getOrganizeId(String organizeId) {
        List<OrganizeEntity> organizeList = new ArrayList<>();
        organizeService.getOrganizeId(organizeId, organizeList);
        Collections.reverse(organizeList);
        return organizeList;
    }

    public List<OrganizeEntity> getDepartmentAll(String organizeId) {
        List<OrganizeEntity> departmentAll = organizeService.getDepartmentAll(organizeId);
        return departmentAll;
    }

    public List<String> getChildOrg(String id) {
        List<String> res = new ArrayList<>();
        // 获取 id 存在organizeIdTree中的组织
        List<OrganizeEntity> list = organizeService.getAllChild(id);
        if (CollectionUtil.isNotEmpty(list)) {
            for (OrganizeEntity entity : list) {
                res.add(entity.getId() + "--" + entity.getCategory());
            }
        }
        return res;
    }

    public List<String> getUnderOrg(String orgId) {
        return organizeService.getUnderOrganizations(orgId, false);
    }

    public List<String> getOrgUserList(String type) {
        return organizeAdministratorService.getOrganizeUserList(type);
    }

    //--------------------------------岗位------------------------------
    public List<PositionEntity> getPositionName(List<String> id) {
        List<PositionEntity> list = positionService.getPositionName(id, false);
        return list;
    }

    //--------------------------------远端------------------------------
    public ActionResult infoToId(String interId, Map<String, String> parameterMap) {
        return dataInterfaceService.infoToId(interId, null, parameterMap);
    }

    public ActionResult infoToId(String interId, String tenantId, Map<String, String> parameterMap, String token) {
        return dataInterfaceService.infoToId(interId, tenantId, parameterMap, token, null, null, null, null);
    }

    public List<DataInterfaceEntity> getInterfaceList(List<String> id) {
        return dataInterfaceService.getList(id);
    }

    //--------------------------------发送消息------------------------------
    public void sendMessage(List<SentMessageForm> messageListAll) {
        flowAsyncUtil.sendMessage(messageListAll);
    }

    public void updateSendConfigUsed(String id, List<String> idList) {
        sendMessageConfigService.updateUsed(id, idList);
    }

    public List<String> sendDelegateMsg(List<SentMessageForm> messageListAll) {
        List<String> list = new ArrayList<>();
        for (SentMessageForm messageForm : messageListAll) {
            List<String> errList = sentMessageUtil.sendDelegateMsg(messageForm);
            list.addAll(errList);
        }
        return list;
    }

    //------------------------------导出-------------------------------
    public DownloadVO exportData(TemplateExportModel model) {
        DownloadVO downloadVO = fileExport.exportFile(model, configValueUtil.getTemporaryFilePath(), model.getTemplate().getFullName(), ModuleTypeEnum.FLOW_FLOWENGINE.getTableName());
        return downloadVO;
    }
}

