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

import cc.smtweb.biz.mztb.web.base.*;
import cc.smtweb.biz.mztb.web.tool.UtilPub;
import cc.smtweb.framework.core.common.R;
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.framework.core.util.StringUtil;
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 com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

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

/**
 * 给北京民政端提供接口
 */
@Slf4j
@Controller
@RequestMapping("/api")
public class MztbController {

    private static final String PWD_SALT = "goodpj";

    @PostMapping("/push")
    @ResponseBody
    public R pushWork(@RequestBody SwMap swMap) {
//        addNewPartyAccount();
        DbEngine instance = DbEngine.getInstance();
        List<Map<String, Object>> updatePartyList = swMap.readListMap("data");

        if (updatePartyList == null || updatePartyList.size() < 1) {
            log.info("请求携带需要更新的机构数据为空！");
            return R.success();
        }
        log.debug("获取到数据:"+updatePartyList.size()+"条，准备处理机构数据。。。。。");

        // 批量处理的数据
        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()));
        for (Map<String, Object> map : updatePartyList) {
            PartyInfo partyInfo = new PartyInfo();
            SwMap updatePartySwMap = new SwMap();
            for (String key : map.keySet()) { // 注意民政端推送数据的字段和填报系统字段要一致
                updatePartySwMap.put(key, map.get(key));
            }
            // 将查询到的数据转为 填报系统机构表数据
            partyInfo.getData().putAll(updatePartySwMap);
            if (partyInfoMap.containsKey(map.get("pi_credit_code") + "")) { // 判断该机构是否存在
                long piIdOld = partyInfoMap.get(map.get("pi_credit_code") + "").getId();
                long sysPartyId = partyInfoMap.get(map.get("pi_credit_code") + "").getSysPartyId();
                partyInfo.setId(piIdOld);
                partyInfo.setSysPartyId(sysPartyId);
                partysUpdateList.add(partyInfo);
            } else { // 新增(包括 底层的party 填报系统的 partyInfo 默认的用户)
                boolean existParty = existPartyMap.containsKey(map.get("pi_credit_code") + "");
                if (existParty) {
                    // 包含就更新机构信息 ,系统机构信息没有可更改的内容故不处理
                    int index = existPartyMap.readInt(map.get("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(map.get("pi_credit_code") + "", insertIndex);
                insertIndex++;

                Party party = new Party(); // 底层机构表
                party.init();
                long ptId = Long.parseLong(map.get("pi_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);

        log.debug("数据构建完成，向数据库写入数据");
        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);
            log.debug("数据写入完成-----");

            // 将新增的机构 加入角色组的 机构字段
            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();
            log.debug("机构缓存刷新完成！");
        });
        return R.success();
    }


    @PostMapping("/pull")
    @ResponseBody
    public R pullWork(@RequestBody SwMap swMap) {
        DbEngine instance = DbEngine.getInstance();

        String data = swMap.readString("data");
        boolean rollBack = swMap.readBool("rollBack", false);
        if (rollBack) {
            String fillOutIds = swMap.readString("fillOutIds");
            List<String> collect = Arrays.stream(fillOutIds.split(",")).collect(Collectors.toList());
            if (StringUtil.isEmpty(fillOutIds)) return R.success();
            instance.update("update " + EntityHelper.getSchemaTableName(FillOut.ENTITY_NAME)
                    + " set fo_read_state = 1,fo_state = 1 where fo_id in (" + StringUtil.join(collect, ",") + ")");
            return R.success();
        }

        // 查询已确认还未推送和未成功 并且为指定任务月的填报数据
        List<String> fillOutList = instance.queryStringList(
                "select fo_id from " + EntityHelper.getSchemaTableName(FillOut.ENTITY_NAME)
                        + " where fo_state = 1 and fo_read_state != 0 and fo_task in (" + data + ") ");
        if (fillOutList.size() == 0) {
            log.info("未找到还未推送的数据");
            return R.success();
        }
        String sql = "select pi.pi_sys_party_id,fo.*,fi.*,bi.*,yep.* from " + EntityHelper.getSchemaTableName(FillOut.ENTITY_NAME) + " fo\n" +
                "    inner join " + EntityHelper.getSchemaTableName(FinanceInfo.ENTITY_NAME) + " fi on fo_id = fi_fo_id\n" +
                "    inner join " + EntityHelper.getSchemaTableName(BusinessInfo.ENTITY_NAME) + " bi on fo_id = bi_fo_id\n" +
                "    inner join "+EntityHelper.getSchemaTableName(PartyInfo.ENTITY_NAME)+" pi on fo_party_id = pi_id " +
                "    left join " + EntityHelper.getSchemaTableName(YearEndPersons.ENTITY_NAME) + " yep on fo_id = yep_fo_id " +
                "    where fo_id in (" + StringUtil.join(fillOutList, ",") + ");";

        List<SwMap> query = instance.query(sql, SwMap.class);

        instance.update("update " + EntityHelper.getSchemaTableName(FillOut.ENTITY_NAME)
                + " set fo_read_time = ?, fo_read_state = 0 ,fo_state = 2 where fo_id in (" + StringUtil.join(fillOutList, ",") + ")", DateUtil.nowDateTimeLong());
        return R.success(query);
    }

}