package cc.smtweb.biz.mztb.web.task;

import cc.smtweb.biz.mztb.web.base.DbSourceConfig;
import cc.smtweb.biz.mztb.web.base.PartyInfo;
import cc.smtweb.biz.mztb.web.tool.DbUtil;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityHelper;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.RandomUtil;
import cc.smtweb.system.bpm.web.sys.base.job.BaseJob;
import cc.smtweb.system.bpm.web.sys.user.dept.Dept;
import cc.smtweb.system.bpm.web.sys.user.dept.DeptCache;
import cc.smtweb.system.bpm.web.sys.user.party.Party;
import cc.smtweb.system.bpm.web.sys.user.party.PartyCache;
import cc.smtweb.system.bpm.web.sys.user.role.group.RoleGroup;
import cc.smtweb.system.bpm.web.sys.user.role.group.RoleGroupCache;
import cc.smtweb.system.bpm.web.sys.user.user.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 拉取前置库推送的机构信息 执行新增或修改 操作
 */
public class AddNewPartyAndAccountTask extends BaseJob {
    private static final Logger logger = LoggerFactory.getLogger(AddNewPartyAndAccountTask.class);
    private static final String PWD_SALT = "goodpj";

    @Override
    protected String work() {
        // 查询前置库推送的机构和账号信息
        DbEngine instance = DbEngine.getInstance();
        DbSourceConfig dbSourceConfig = instance.findDao(DbSourceConfig.class).queryEntityWhere("dsc_use_state = 0");
        Connection connection = null;
        ResultSet resultSet = null;
        // 批量处理的数据
        List<PartyInfo> partysUpdateList = new ArrayList<>();
        List<PartyInfo> partysInsertList = new ArrayList<>();
        List<Party> sysPartyList = new ArrayList<>();
        List<User> userList = new ArrayList<>();
        List<UserParty> userPartyList = new ArrayList<>();
        List<Dept> deptList = new ArrayList<>();
        List<UserRole> userRoleList = new ArrayList<>();
        List<UserStatu> userStatuList = new ArrayList<>();

        List<String> ptIdList = new ArrayList<>();

        // 记录重复数据
        List<PartyInfo> partysInsertListExist = new ArrayList<>();
        List<Party> sysPartyListExist = new ArrayList<>();
        List<User> userListExist = new ArrayList<>();
        List<UserParty> userPartyListExist = new ArrayList<>();
        List<Dept> deptListExist = new ArrayList<>();
        List<String> ptIdListExist = new ArrayList<>();
        List<UserRole> userRoleListExist = new ArrayList<>();
        List<UserStatu> userStatuListExist = new ArrayList<>();

        SwMap existPartyMap = new SwMap();
        int insertIndex = 0;
        // 使用社会信用代码 当做key
        Map<String, PartyInfo> partyInfoMap = instance.query(PartyInfo.class).stream().collect(Collectors.toMap(PartyInfo::getCreditCode, Function.identity()));
        try {
            connection = DriverManager.getConnection(dbSourceConfig.getWholeUrl(), dbSourceConfig.getUsername(), dbSourceConfig.getPassword());
            DbUtil dbUtil = new DbUtil(connection);
            // 查询未读取并且是民政端（wr_aspect =0）推送的机构信息,时间升序 先推送的先读取。
            resultSet = dbUtil.dbHandSql("select * from pre_party_info where state = 0 and wr_aspect = 0 order by wr_time", "query");
            if (resultSet == null) return null;
            logger.info("select * from pre_party_info where state = 0 and wr_aspect = 1 order by wr_time; 查询到结果,继续执行......");

            while (resultSet.next()) {
                PartyInfo partyInfo = new PartyInfo();
                SwMap swMap = new SwMap();
                ResultSetMetaData metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    swMap.put(metaData.getColumnName(i), resultSet.getString(i));
                }
                // 将查询到的数据转为 填报系统机构表数据
                partyInfo.getData().putAll(swMap);

                if (partyInfoMap.containsKey(resultSet.getString("pi_credit_code"))) { // 判断该机构是否存在
                    long piIdOld = partyInfoMap.get(resultSet.getString("pi_credit_code")).getId();
                    long sysPartyId = partyInfoMap.get(resultSet.getString("pi_credit_code")).getSysPartyId();
                    partyInfo.setId(piIdOld);
                    partyInfo.setSysPartyId(sysPartyId);
                    partysUpdateList.add(partyInfo);
                } else { // 新增(包括 底层的party 填报系统的 partyInfo 默认的用户)
                    boolean existParty = existPartyMap.containsKey(resultSet.getString("pi_credit_code"));
                    if (existParty) {
                        // 包含就更新机构信息 ,系统机构信息没有可更改的内容故不处理
                        int index = existPartyMap.readInt(resultSet.getString("pi_credit_code"));
                        partysInsertListExist.add(partysInsertList.get(index));
                        userListExist.add(userList.get(index));
                        userPartyListExist.add(userPartyList.get(index));
                        sysPartyListExist.add(sysPartyList.get(index));
                        deptListExist.add(deptList.get(index));
                        userRoleListExist.add(userRoleList.get(index));
                        userStatuListExist.add(userStatuList.get(index));
                        ptIdListExist.add(ptIdList.get(index));
                    }
                    existPartyMap.put(resultSet.getString("pi_credit_code"), insertIndex);
                    insertIndex++;

                    Party party = new Party(); // 底层机构表
                    party.init();
                    long ptId = resultSet.getLong("pi_id"); // 使用前置库的机构id当做 填报系统机构id
                    party.setId(ptId);
                    party.setCode(ptId + "");
                    party.setName(partyInfo.getPartyName());
                    partyInfo.setSysPartyId(ptId);
                    sysPartyList.add(party);
                    partysInsertList.add(partyInfo);
                    // 添加机构id
                    ptIdList.add(ptId + "");

                    User user = new User(); // 底层用户表
                    user.init();
                    long userId = instance.nextId();
                    user.setId(userId);
                    user.setCode(partyInfo.getCreditCode());
                    user.setName(partyInfo.getPartyName() + "-填报人员");
                    user.setNicky(partyInfo.getCreditCode());
                    user.setLevel(100);
                    user.setStatu(1);
//                    user.setPwd("13217b04835b4cbceb55edb54a72deb4"); //默认密码 abc@123456
                    user.setPwd(DigestUtils.md5Hex(PWD_SALT + user.getId() + "abc@123456")); //默认密码 abc@123456
                    user.setPwdLevel(0);
                    userList.add(user);

                    Dept dept = new Dept();// 添加部门
                    dept.init();
                    long deptId = instance.nextId();
                    dept.setId(deptId);
                    dept.setCode(RandomUtil.randomString(8));
                    dept.setName("填报部门");
                    dept.setType("100");
                    dept.setPtId(ptId);
                    dept.setStatu(0);
                    deptList.add(dept);

                    UserParty userParty = new UserParty(); //用户机构关联表
                    long userPartyId = instance.nextId();
                    userParty.setId(userPartyId);
                    userParty.setPartyId(ptId);
                    userParty.setUserId(userId);
                    userParty.setDeptId(deptId); // 关联部门表
                    userPartyList.add(userParty);

                    UserRole userRole = new UserRole(); // 用户角色
                    userRole.setId(instance.nextId());
                    userRole.setSupId(userPartyId);
                    userRole.setRoleGroupId(927515588790587392L); // 角色组id todo 先写死 一般不会变
                    userRoleList.add(userRole);

                    UserStatu userStatu = new UserStatu(); // 用户登录状态
                    userStatu.init();
                    userStatu.setId(userId);
                    userStatuList.add(userStatu);


                }
            }
            // 删除重复新增的元素
            partysInsertList.removeAll(partysInsertListExist);
            sysPartyList.removeAll(sysPartyListExist);
            userList.removeAll(userListExist);
            userPartyList.removeAll(userPartyListExist);
            deptList.removeAll(deptListExist);
            userRoleList.removeAll(userRoleListExist);
            userStatuList.removeAll(userStatuListExist);
            ptIdList.removeAll(ptIdListExist);

            // 读取完成后 修改前置库推送数据的状态，再进行本系统数据入库处理
            int updateNum = dbUtil.update("update pre_party_info set state = 1, rd_time = " + DateUtil.nowDateTimeNumber() + " where state = 0 and wr_aspect = 0");
            logger.info("修改前置库机构读取状态数量：{}",updateNum);
            logger.info("========开始处理新增或者修改的机构信息=========");


            instance.doTrans(() -> {
                // 处理新增或者修改的数据
                instance.findDao(PartyInfo.class).batchInsertEntity(partysInsertList);
                instance.findDao(PartyInfo.class).batchUpdateEntity(partysUpdateList);
                instance.findDao(Party.class).batchInsertEntity(sysPartyList);
                instance.findDao(User.class).batchInsertEntity(userList);
                instance.findDao(UserParty.class).batchInsertEntity(userPartyList);
                instance.findDao(Dept.class).batchInsertEntity(deptList);
                instance.findDao(UserRole.class).batchInsertEntity(userRoleList);
                instance.findDao(UserStatu.class).batchInsertEntity(userStatuList);

                // 将新增的机构 加入角色组的 机构字段
                if (ptIdList.size() > 0) {
                    instance.update("UPDATE " + EntityHelper.getSchemaTableName(RoleGroup.ENTITY_NAME)
                            + " SET srg_party_id = CONCAT(srg_party_id,',' ,'" + String.join(",", ptIdList) + "') where srg_id = ? ", 927515588790587392L); // 角色组填报员
                }
                // 将机构、用户信息放入缓存,或者刷新缓存
                PartyCache.getInstance().putList(sysPartyList);
                UserCache.getInstance().putList(userList);
                UserPartyCache.getInstance().putList(userPartyList);
                DeptCache.getInstance().putList(deptList);
                UserRoleCache.getInstance().putList(userRoleList);
                UserStatuCache.getInstance().putList(userStatuList);
                RoleGroupCache.getInstance().refresh();
            });
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 判断是新增还是修改（如果是修改 将机构信息删除 重新新增，注意维护系统机构表数据）
        // 新增的机构 自动创建一个登录账号
        //读取完成后 修改前置库 推送机构表的状态和读取时间
        // 在当前系统 建立机构和账号数据,将账号信息写入缓存
        return null;
    }
}
