package com.engine.organization.service.impl;

import com.api.browser.bean.SearchConditionItem;
import com.engine.core.impl.Service;
import com.engine.organization.entity.TopTab;
import com.engine.organization.entity.codesetting.po.CodeRulePO;
import com.engine.organization.entity.extend.ExtendInfoOperateType;
import com.engine.organization.entity.extend.bo.ExtendInfoBO;
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.enums.ModuleTypeEnum;
import com.engine.organization.mapper.codesetting.CodeRuleMapper;
import com.engine.organization.mapper.extend.*;
import com.engine.organization.service.ExtService;
import com.engine.organization.util.OrganizationAssert;
import com.engine.organization.util.db.DBType;
import com.engine.organization.util.db.MapperProxyFactory;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.general.Util;
import weaver.hrm.User;

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

/**
 * @description:
 * @author:dxfeng
 * @createTime: 2022/05/24
 * @version: 1.0
 */
public class ExtServiceImpl extends Service implements ExtService {

    private static final Integer BROWSER_TYPE = 3;

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

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

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

    private ExtDTMapper getExtDTMapper() {
        return MapperProxyFactory.getProxy(ExtDTMapper.class);
    }

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


    @Override
    public List<SearchConditionItem> getExtForm(User user, String extendType, String tableName, int viewAttr, long id, String groupId, String... readOnlyFields) {
        List<SearchConditionItem> conditionItems = new ArrayList<>();

        // 2编辑 1查看
        OrganizationAssert.notNull(groupId, "请选择对应的拓展页");
        List<ExtendInfoPO> infoPOList = getExtendInfoMapper().listFields(extendType, groupId, tableName, 1 == viewAttr ? ExtendInfoOperateType.LIST.getValue() : ExtendInfoOperateType.EDIT.getValue(), "1");
        String fields = infoPOList.stream().map(ExtendInfoPO::getFieldName).collect(Collectors.joining(","));
        if (StringUtils.isEmpty(fields)) {
            return conditionItems;
        }
        ExtendInfoParams infoParams = ExtendInfoParams.builder().tableName(tableName).fields(fields).params(null).id(id).build();
        Map<String, Object> compExtMap = getExtMapper().listExt(infoParams);
        List<String> readOnlyFieldList = Arrays.asList(readOnlyFields);
        // 组装拓展页内容
        for (ExtendInfoPO extendInfoPO : infoPOList) {
            SearchConditionItem item = ExtendInfoBO.getSearchConditionItem(user, viewAttr, extendInfoPO, null == compExtMap ? null : compExtMap.get(DBType.isOracle() ? extendInfoPO.getFieldName().toUpperCase() : extendInfoPO.getFieldName()));
            item.setFieldcol(16);
            if (2 == viewAttr) {
                if (CollectionUtils.isNotEmpty(readOnlyFieldList) && readOnlyFieldList.contains(extendInfoPO.getFieldName())) {
                    item.setViewAttr(1);
                } else if (1 == extendInfoPO.getIsrequired()) {
                    item.setViewAttr(3);
                    item.setRules("required");
                }
            }
            // 分部，上级部门添加提示信息
            if (1 != viewAttr && ModuleTypeEnum.departmentfielddefined.getValue().toString().equals(groupId) && "parent_dept".equalsIgnoreCase(extendInfoPO.getFieldName())) {
                item.setHelpfulTip("请先选择所属分部再选择" + extendInfoPO.getFieldNameDesc());
            }
            conditionItems.add(item);
        }
        return conditionItems;
    }

    @Override
    public List<SearchConditionItem> getExtSaveForm(User user, String extendType, String tableName, int viewAttr, String groupId, String autoNoField, String serialType, Map<String, Object> params, String... readOnlyFields) {
        List<SearchConditionItem> conditionItems = new ArrayList<>();
        if (null == params) {
            params = new HashMap<>();
        }
        // 2编辑 1查看
        OrganizationAssert.notNull(groupId, "请选择对应的拓展页");
        List<ExtendInfoPO> infoPOList = getExtendInfoMapper().listFields(extendType, groupId, tableName, ExtendInfoOperateType.ADD.getValue(), "1");
        // 组装拓展页内容
        List<String> readOnlyFieldList = Arrays.asList(readOnlyFields);
        for (ExtendInfoPO extendInfoPO : infoPOList) {
            SearchConditionItem item = ExtendInfoBO.getSearchConditionItem(user, viewAttr, extendInfoPO, params.get(extendInfoPO.getFieldName()));
            item.setFieldcol(16);
            if (CollectionUtils.isNotEmpty(readOnlyFieldList) && readOnlyFieldList.contains(extendInfoPO.getFieldName())) {
                item.setViewAttr(1);
            } else if (1 == extendInfoPO.getIsrequired()) {
                item.setViewAttr(3);
                item.setRules("required");
            }
            if (StringUtils.isNotBlank(autoNoField) && extendInfoPO.getFieldName().equalsIgnoreCase(autoNoField)) {
                // 判断是否开启自动编号
                CodeRulePO codeRuleByType = MapperProxyFactory.getProxy(CodeRuleMapper.class).getCodeRuleByType(serialType);
                if (null != codeRuleByType && "1".equals(codeRuleByType.getSerialEnable())) {
                    item.setViewAttr(2);
                    item.setHelpfulTip("编号为空,则按照指定规则自动生成编号");
                    item.setRules("");
                }
            }
            // 分部，上级部门添加提示信息
            if (ModuleTypeEnum.departmentfielddefined.getValue().toString().equals(groupId) && "parent_dept".equalsIgnoreCase(extendInfoPO.getFieldName())) {
                item.setHelpfulTip("请先选择所属分部再选择" + extendInfoPO.getFieldNameDesc());
            }
            conditionItems.add(item);
        }
        return conditionItems;
    }

    @Override
    public List<Map<String, Object>> getExtendTables(User user, String extendType, Long groupId, String tableName, long id, int viewAttr, boolean showLabel) {
        List<Map<String, Object>> tables = new ArrayList<>();
        List<ExtendInfoPO> infoPOList = new ArrayList<>();
        // 查询明细表
        List<ExtendGroupPO> extendGroupList = getExtendGroupMapper().listGroupByPid(groupId, "1");
        for (ExtendGroupPO extendGroup : extendGroupList) {
            infoPOList.addAll(getExtendInfoMapper().listFields(extendType, extendGroup.getId() + "", tableName, "", "1"));
        }
        // 查询所有分布模块，拓展明细表信息
        Map<Long, List<ExtendInfoPO>> groupMap = infoPOList.stream().collect(Collectors.groupingBy(ExtendInfoPO::getExtendGroupId));
        // 遍历Map,组装数据
        for (Map.Entry<Long, List<ExtendInfoPO>> entry : groupMap.entrySet()) {
            Map<String, Object> tableMap = new HashMap<>();
            tableMap.put("hide", false);
            tableMap.put("tabname", getExtendGroupMapper().getGroupNameById(Util.null2String(entry.getKey())));
            Map<String, Object> tabinfoMap = new HashMap<>();
            tabinfoMap.put("columns", ExtendInfoBO.convertInfoListToTable(user, entry.getValue(), viewAttr, showLabel));
            tabinfoMap.put("rownum", "rownum" + entry.getKey());

            // 浏览按钮添加filespan字段
            String fields = entry.getValue().stream().map(item -> {
                if (BROWSER_TYPE.equals(item.getControlType())) {
                    return item.getFieldName() + "," + item.getFieldName() + "span";
                }
                return item.getFieldName();
            }).collect(Collectors.joining(","));
            // 去除null 元素
            List<Map<String, Object>> maps = getExtDTMapper().listCompExtDT(tableName, id, fields);
            maps.removeIf(Objects::isNull);
            // 兼容Oracle,map的key转换为小写
            List<Map<String, Object>> collect = maps.stream().map(item -> {
                Map<String, Object> resultMap = new HashMap<>();
                Set<String> keys = item.keySet();
                for (String key : keys) {
                    resultMap.put(key.toLowerCase(), item.get(key));
                }
                return resultMap;
            }).collect(Collectors.toList());
            tabinfoMap.put("datas", collect);
            tableMap.put("tabinfo", tabinfoMap);
            tables.add(tableMap);
        }
        return tables;
    }


    /**
     * 拓展页面分组
     *
     * @return
     */
    public List<TopTab> getTabInfo(String extendType, String tableName) {
        List<TopTab> topTabs = new ArrayList<>();
        List<ExtendInfoPO> infoPOList = getExtendInfoMapper().listFields(extendType, "", tableName, ExtendInfoOperateType.EDIT.getValue(), "1");
        List<ExtendInfoPO> infoPOList1 = getExtendInfoMapper().listFields(extendType, "", tableName.toUpperCase().replace("EXT", ""), ExtendInfoOperateType.EDIT.getValue(), "1");
        infoPOList.addAll(infoPOList1);
        List<Long> ids = infoPOList.stream().map(ExtendInfoPO::getExtendGroupId).collect(Collectors.toList());

        List<ExtendTitlePO> extendTitles = getExtendTitleMapper().getTitlesByIds(ids);
        Set<Long> groupIds = extendTitles.stream().map(ExtendTitlePO::getGroupId).collect(Collectors.toSet());
        List<ExtendGroupPO> extendGroupList = getExtendGroupMapper().listByType(Integer.parseInt(extendType), "1");

        // 拓展信息
        if (CollectionUtils.isNotEmpty(extendGroupList) && CollectionUtils.isNotEmpty(groupIds)) {
            for (ExtendGroupPO extendGroup : extendGroupList) {
                if (groupIds.contains(extendGroup.getId())) {
                    topTabs.add(TopTab.builder().color("#000000").groupId(extendGroup.getId().toString()).showcount(false).title(extendGroup.getGroupName()).viewCondition(extendGroup.getId().toString()).build());
                }
            }
        }
        return topTabs;
    }

    @Override
    public Long updateExtForm(User user, String extendType, String tableName, Map<String, Object> params, String groupId, Long id) {
        List<ExtendInfoPO> extInfoPOList = getExtendInfoMapper().listFields(extendType, groupId, tableName, "", "");
        Map<String, Object> map = new HashMap<>();
        // 遍历Map
        Map<String, ExtendInfoPO> collect = extInfoPOList.stream().collect(Collectors.toMap(ExtendInfoPO::getFieldName, item -> item));
        collect.put("uuid", new ExtendInfoPO());
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            if (collect.containsKey(key)) {
                Object value = entry.getValue();
                if (null != value && StringUtils.isBlank(value.toString())) {
                    value = null;
                }
                if (null == value) {
                    if ("int".equals(collect.get(key).getFieldType())) {
                        value = null;
                    }
                    // 兼容sqlServer数据库text字段类型
                    if ("text".equals(collect.get(key).getFieldType())) {
                        value = "";
                    }
                }
                map.put(key, value);
            }
        }
        ExtendInfoParams infoParams = ExtendInfoParams.builder().tableName(tableName).params(map).id(id).build();
        if (null != id) {
            // 判断更新还是插入
            int count = getExtMapper().countExtById(infoParams);
            if (count > 0) {
                map.put("update_time", new Date());
                getExtMapper().updateTable(infoParams);
            } else {
                map.put("creator", user.getUID());
                map.put("delete_type", 0);
                map.put("create_time", new Date());
                map.put("update_time", new Date());
                map.put("id", id);
                getExtMapper().insertExtTable(infoParams);
            }
        } else {
            if (!tableName.equals("JCL_ORG_HRMRESOURCE")) {
                map.put("forbidden_tag", 0);
            }
            map.put("creator", user.getUID());
            map.put("delete_type", 0);
            map.put("create_time", new Date());
            map.put("update_time", new Date());
            getExtMapper().insertTable(infoParams);
        }
        return infoParams.getId();
    }

    @Override
    public void updateExtDT(User user, String extendType, String tableName, Map<String, Object> params, Long id) {
        List<ExtendInfoPO> dtInfoPOList = getExtendInfoMapper().listFields(extendType, "", tableName, "", "");
        List<Long> groupIds = dtInfoPOList.stream().map(ExtendInfoPO::getExtendGroupId).distinct().collect(Collectors.toList());
        Map<Long, List<ExtendInfoPO>> poMaps = dtInfoPOList.stream().collect(Collectors.groupingBy(ExtendInfoPO::getExtendGroupId));
        // 删除原有明细表数据
        getExtDTMapper().deleteByMainID(tableName, id);

        for (Long groupId : groupIds) {
            int rowNum = Util.getIntValue((String) params.get("rownum" + groupId));
            List<ExtendInfoPO> filterS = poMaps.get(groupId);
            for (int i = 0; i < rowNum; i++) {
                Map<String, Object> map = new HashMap<>();
                for (ExtendInfoPO extendInfoPO : filterS) {
                    if (BROWSER_TYPE.equals(extendInfoPO.getControlType())) {
                        map.put(extendInfoPO.getFieldName() + "span", params.get(extendInfoPO.getFieldName() + "span_" + i));
                    }
                    map.put(extendInfoPO.getFieldName(), params.get(extendInfoPO.getFieldName() + "_" + i));
                }
                map.put("mainid", id);
                map.put("creator", user.getUID());
                map.put("delete_type", 0);
                map.put("create_time", new Date());
                map.put("update_time", new Date());
                getExtDTMapper().insertCompExtDT(tableName, map);
            }
        }
    }
}
