package com.engine.organization.service.impl;

import com.engine.common.service.HrmCommonService;
import com.engine.common.service.impl.HrmCommonServiceImpl;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.organization.entity.extend.ExtendInfoOperateType;
import com.engine.organization.entity.extend.bo.ExtendGroupBO;
import com.engine.organization.entity.extend.param.ExtendInfoParams;
import com.engine.organization.entity.extend.po.ExtendGroupPO;
import com.engine.organization.entity.extend.po.ExtendInfoPO;
import com.engine.organization.entity.extend.po.ExtendTitlePO;
import com.engine.organization.entity.personnelcard.*;
import com.engine.organization.entity.personnelcard.po.CardAccessPO;
import com.engine.organization.entity.personnelcard.po.CardButtonPO;
import com.engine.organization.exception.OrganizationRunTimeException;
import com.engine.organization.mapper.extend.ExtMapper;
import com.engine.organization.mapper.extend.ExtendGroupMapper;
import com.engine.organization.mapper.extend.ExtendInfoMapper;
import com.engine.organization.mapper.extend.ExtendTitleMapper;
import com.engine.organization.mapper.hrmresource.HrmResourceMapper;
import com.engine.organization.mapper.personnelcard.CardAccessMapper;
import com.engine.organization.mapper.personnelcard.CardButtonMapper;
import com.engine.organization.mapper.personnelcard.PersonnelCardMapper;
import com.engine.organization.service.HrmPersonnelCardService;
import com.engine.organization.util.OrganizationAssert;
import com.engine.organization.util.db.DBType;
import com.engine.organization.util.db.MapperProxyFactory;
import com.engine.organization.util.field.FieldDefinedValueUtil;
import com.engine.portal.biz.constants.ModuleConstants;
import com.engine.portal.biz.nonstandardfunction.SysModuleInfoBiz;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.blog.BlogShareManager;
import weaver.cowork.CoworkShareManager;
import weaver.crm.CrmShareBase;
import weaver.docs.search.DocSearchComInfo;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;
import weaver.workflow.search.WorkflowRequestUtil;

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

/**
 * @author:dxfeng
 * @createTime: 2022/10/08
 * @version: 1.0
 */
public class HrmPersonnelCardServiceImpl extends Service implements HrmPersonnelCardService {
    private static final String IS_SHOW = "1";

    private PersonnelCardMapper getPersonnelCardMapper() {
        return MapperProxyFactory.getProxy(PersonnelCardMapper.class);
    }

    private ExtendGroupMapper getExtendGroupMapper() {
        return MapperProxyFactory.getProxy(ExtendGroupMapper.class);
    }

    private ExtendTitleMapper getExtendTitleMapper() {
        return MapperProxyFactory.getProxy(ExtendTitleMapper.class);
    }

    private ExtendInfoMapper getExtendInfoMapper() {
        return MapperProxyFactory.getProxy(ExtendInfoMapper.class);
    }

    private ExtMapper getExtMapper() {
        return MapperProxyFactory.getProxy(ExtMapper.class);
    }

    private HrmResourceMapper getHrmResourceMapper() {
        return MapperProxyFactory.getProxy(HrmResourceMapper.class);
    }

    private CardButtonMapper getCardButtonMapper() {
        return MapperProxyFactory.getProxy(CardButtonMapper.class);
    }


    @Override
    public Map<String, Object> getPersonnelCard(Long uId) {
        Map<String, Object> resultMap = new HashMap<>();
        UserCard userInfo;
        if (null == uId) {
            uId = getHrmResourceMapper().getJclResourceId(Util.null2String(user.getUID()));
        }
        String ecResourceId = getHrmResourceMapper().getEcResourceId(uId.toString());
        userInfo = getPersonnelCardMapper().getUserById(uId);
        userInfo.setEcId(ecResourceId);

        OrganizationAssert.notNull(uId, "未找到对应数据");
        // 人员基本信息

        // 统计报表
        Statistical statistical = getStatistical(ecResourceId);
        List<ExtendGroupPO> extendGroupList = getExtendGroupMapper().listByType(4, IS_SHOW);
        // 过滤卡片权限
        extendGroupList.removeIf(item -> !hasGroupAccess(item.getId().intValue(), ecResourceId));

        // 获取所有模块的信息
        List<FormItem> formItemList = new ArrayList<>();
        for (ExtendGroupPO groupPO : extendGroupList) {
            FormItem formItem = getFormItem(groupPO, uId);
            if (CollectionUtils.isEmpty(formItem.getItems())) {
                continue;
            }
            // 处理明细表数据
            List<Map<String, Object>> detailList = ServiceUtil.getService(ExtServiceImpl.class, user).getExtendTables(user, "4", groupPO.getId(), "JCL_ORG_HRMRESOURCEEXT_DT1", uId, 1, false);
            formItem.setTables(detailList);

            formItemList.add(formItem);

        }
        // 所有锚点
        List<Anchor> anchorList = new ArrayList<>();
        // 添加字段分组信息
        for (FormItem formItem : formItemList) {
            anchorList.add(Anchor.builder().id(formItem.getId()).title(formItem.getTitle()).build());
        }
        // 添加拓展页面信息
        List<ResourceBaseTab> resourceBaseTabList = getPersonnelCardMapper().getResourceBaseTabList();
        for (ResourceBaseTab resourceBaseTab : resourceBaseTabList) {
            anchorList.add(Anchor.builder().id("tab" + resourceBaseTab.getId()).title(resourceBaseTab.getGroupName()).build());
        }
        resultMap.put("buttons", getButtonList(ecResourceId));
        resultMap.put("user", userInfo);
        resultMap.put("statistical", statistical);
        resultMap.put("formItems", formItemList);
        resultMap.put("anchorList", anchorList);
        resultMap.put("iframeList", getIframeList());
        return resultMap;
    }

    @Override
    public List<Iframe> getIframeList() {
        List<Iframe> iframeList = new ArrayList<>();
        List<ResourceBaseTab> resourceBaseTabList = getPersonnelCardMapper().getResourceBaseTabList();
        for (ResourceBaseTab resourceBaseTab : resourceBaseTabList) {
            iframeList.add(Iframe.builder().id("tab" + resourceBaseTab.getId()).title(resourceBaseTab.getGroupName()).url(resourceBaseTab.getLinkUrl()).build());
        }
        return iframeList;
    }


    /**
     * 获取报表统计数据
     *
     * @param ecResourceId
     * @return
     */
    private Statistical getStatistical(String ecResourceId) {
        try {
            // 获取Ec用户ID
            Statistical statistical = new Statistical();
            if (SysModuleInfoBiz.checkModuleStatus(ModuleConstants.Workflow)) {
                statistical.setWorkflowCount(new WorkflowRequestUtil().getRequestCount(user, ecResourceId));
            } else {
                statistical.setWorkflowCount(0);
            }
            if (SysModuleInfoBiz.checkModuleStatus(ModuleConstants.Doc)) {
                Object[] docCount4Hrm = new DocSearchComInfo().getDocCount4Hrm(ecResourceId, user);
                statistical.setDocCount(null == docCount4Hrm[1] ? 0 : Integer.parseInt(Util.null2String(docCount4Hrm[1])));
            } else {
                statistical.setDocCount(0);
            }
            if (SysModuleInfoBiz.checkModuleStatus(ModuleConstants.Crm)) {
                String[] crmCount4Hrm = new CrmShareBase().getCrmCount4Hrm(ecResourceId, ecResourceId);
                statistical.setCusCount(null == crmCount4Hrm[1] ? 0 : Integer.parseInt(Util.null2String(crmCount4Hrm[1])));
            } else {
                statistical.setCusCount(0);
            }
            if (SysModuleInfoBiz.checkModuleStatus(ModuleConstants.Cowork)) {
                String[] coworkCount4Hrm = new CoworkShareManager().getCoworkCount4Hrm(ecResourceId, ecResourceId);
                statistical.setCollaborationCount(null == coworkCount4Hrm[1] ? 0 : Integer.parseInt(Util.null2String(coworkCount4Hrm[1])));
            } else {
                statistical.setCollaborationCount(0);
            }
            if (SysModuleInfoBiz.checkModuleStatus(ModuleConstants.Blog)) {
                String[] blogCount4Hrm = new BlogShareManager().getBlogCount4Hrm(ecResourceId);
                statistical.setWeiboCount(null == blogCount4Hrm[1] ? 0 : Integer.parseInt(Util.null2String(blogCount4Hrm[1])));
            } else {
                statistical.setWeiboCount(0);
            }
            return statistical;
        } catch (Exception e) {
            new BaseBean().writeLog(e);
            throw new RuntimeException(e);
        }
    }

    private FormItem getFormItem(ExtendGroupPO extendGroup, Long uId) {
        FormItem formItem = new FormItem();
        formItem.setId("group" + extendGroup.getId());
        formItem.setTitle(extendGroup.getGroupName());
        List<ExtendTitlePO> extendTitleList = getExtendTitleMapper().getTitlesByGroupID(extendGroup.getId(), IS_SHOW);
        List<Item> itemList = new ArrayList<>();
        for (ExtendTitlePO extendTitlePO : extendTitleList) {
            List<ExtendInfoPO> extendInfoList = getExtendInfoMapper().listFields(extendGroup.getExtendType().toString(), extendTitlePO.getId().toString(), ExtendGroupBO.getTableNameByGroupPO(extendGroup), ExtendInfoOperateType.LIST.getValue(), IS_SHOW);
            String fields = extendInfoList.stream().map(ExtendInfoPO::getFieldName).collect(Collectors.joining(","));
            if (StringUtils.isBlank(fields)) {
                continue;
            }
            ExtendInfoParams infoParams = ExtendInfoParams.builder().tableName(ExtendGroupBO.getTableNameByGroupPO(extendGroup)).fields(fields).params(null).id(uId).build();
            Map<String, Object> fieldValueMap = getExtMapper().listExt(infoParams);
            for (ExtendInfoPO extendInfoPO : extendInfoList) {
                String fieldShowName = "";
                if (null != fieldValueMap) {
                    Object fieldValue;
                    if (DBType.isOracle()) {
                        fieldValue = fieldValueMap.get(extendInfoPO.getFieldName().toUpperCase());
                    } else {
                        fieldValue = fieldValueMap.get(extendInfoPO.getFieldName());
                    }
                    fieldShowName = FieldDefinedValueUtil.getFieldValue(user, extendInfoPO, Util.null2String(fieldValue));
                }
                itemList.add(Item.builder().fieldId(extendInfoPO.getFieldNameDesc()).fieldValue(fieldShowName).build());
            }
        }
        formItem.setItems(itemList);
        return formItem;
    }

    /**
     * 判断当前人员、是否有查看当前数据、当前模块的权限
     *
     * @param typeId 人员卡片分组ID
     * @param userId 当前卡片人员EcId
     * @return
     */
    public boolean hasGroupAccess(Integer typeId, String userId) {
        // 人员信息有误,返回false
        OrganizationAssert.notBlank(userId, "未获取到对应人员");

        boolean hasAccess = false;
        CardAccessPO cardAccessPO = MapperProxyFactory.getProxy(CardAccessMapper.class).selectById(typeId);
        if (null == cardAccessPO || 0 == cardAccessPO.getStatus()) {
            // 未配置相应数据、或者未启用返回false
            return false;
        }

        // 系统管理员、查看本人卡片,或者所有人有权限直接返回true
        if (user.isAdmin() || userId.equals(String.valueOf(user.getUID())) || 1 == cardAccessPO.getAllPeople()) {
            return true;
        }

        try {
            ResourceComInfo resourceComInfo = new ResourceComInfo();
            // 上级
            if ("1".equals(Util.null2String(cardAccessPO.getSuperior()))) {
                String managerID = resourceComInfo.getManagerID(userId);
                hasAccess = Arrays.asList(managerID.split(",")).contains(Util.null2String(user.getUID()));
            }

            // 所有上级
            if (!hasAccess && "1".equals(Util.null2String(cardAccessPO.getAllSuperior()))) {
                String managersIDs = resourceComInfo.getManagersIDs(userId);
                hasAccess = Arrays.asList(managersIDs.split(",")).contains(Util.null2String(user.getUID()));
            }
        } catch (Exception e) {
            new BaseBean().writeLog(e);
            throw new OrganizationRunTimeException("人员卡片权限");
        }
        // 角色判断
        if (!hasAccess && StringUtils.isNotBlank(cardAccessPO.getCustom())) {
            HrmCommonService hrmCommonService = new HrmCommonServiceImpl();
            List<String> roleIds = new ArrayList<>(Arrays.asList(hrmCommonService.getRoleIds(user.getUID()).split(",")));
            List<String> accessRoleIds = new ArrayList<>(Arrays.asList(cardAccessPO.getCustom().split(",")));
            roleIds.retainAll(accessRoleIds);
            hasAccess = CollectionUtils.isNotEmpty(roleIds);

        }
        return hasAccess;
    }


    /**
     * 获取当前人员有权限的按钮，系统管理员展示所有，个人卡片展示系统默认按钮、其余按钮依照配置角色展示
     *
     * @param ecResourceId
     * @return
     */
    private List<CardButtonPO> getButtonList(String ecResourceId) {
        boolean isMySelf = ecResourceId.equals(Util.null2String(user.getUID()));
        boolean isAdmin = user.isAdmin();
        List<CardButtonPO> cardButtonPOS = getCardButtonMapper().listEnableButton();
        List<CardButtonPO> buttonList = new ArrayList<>();
        HrmCommonService hrmCommonService = new HrmCommonServiceImpl();
        List<String> roleIds = new ArrayList<>(Arrays.asList(hrmCommonService.getRoleIds(user.getUID()).split(",")));


        for (CardButtonPO cardButton : cardButtonPOS) {
            List<String> accessRoleIds = new ArrayList<>(Arrays.asList(Util.null2String(cardButton.getRoles()).split(",")));
            roleIds.retainAll(accessRoleIds);
            if (isAdmin || (isMySelf && "0".equals(cardButton.getSysDefault())) || CollectionUtils.isNotEmpty(roleIds)) {
                buttonList.add(CardButtonPO.builder().name(cardButton.getName()).url(cardButton.getUrl()).sysDefault(cardButton.getSysDefault()).build());
            }
        }
        return buttonList;
    }

}
