package com.yeejoin.amos.boot.module.tcm.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.module.common.api.constant.TZSCommonConstant;
import com.yeejoin.amos.boot.module.common.api.entity.TzsUserPermission;
import com.yeejoin.amos.boot.module.tcm.api.entity.TzBaseEnterpriseInfo;
import com.yeejoin.amos.boot.module.tcm.api.entity.TzsUserInfo;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.*;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class HistoryDataDealServiceImpl {

    private TzsUserInfoServiceImpl userInfoService;

    private TzsUserPermissionServiceImpl userPermissionService;

    private TzBaseEnterpriseInfoServiceImpl baseEnterpriseInfoService;

    public HistoryDataDealServiceImpl(TzsUserInfoServiceImpl userInfoService, TzsUserPermissionServiceImpl userPermissionService, TzBaseEnterpriseInfoServiceImpl baseEnterpriseInfoService) {
        this.userInfoService = userInfoService;
        this.userPermissionService = userPermissionService;
        this.baseEnterpriseInfoService = baseEnterpriseInfoService;
    }

    @Transactional(rollbackFor = Exception.class)
    public int userPermissionUpdate() {
        log.info("刷存量人员资质开始");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<TzsUserInfo> usersOfHavingPermission = userInfoService.list(new LambdaQueryWrapper<TzsUserInfo>().isNotNull(TzsUserInfo::getPermissionData));
        List<TzsUserPermission> allWaitFlushData = new ArrayList<>();
        usersOfHavingPermission.forEach(u -> {
            JSON.parseObject(u.getPermissionData()).forEach((k, v) -> {
                List<TzsUserPermission> userPermissions = JSONArray.parseArray(v.toString(), TzsUserPermission.class);
                userPermissions.forEach(p -> {
                    p.setUserSeq(u.getSequenceNbr());
                    p.setPermissionPost(k);
                    p.setRecDate(new Date());
                    p.setRecUserName(u.getRecUserName());
                    p.setRecUserId(u.getRecUserId());
                    p.setRemark("存量数据刷入");
                });
                allWaitFlushData.addAll(userPermissions);
            });
        });
        if (allWaitFlushData.size() > 0) {
            userPermissionService.saveBatch(allWaitFlushData);
        }
        stopWatch.stop();
        log.info("刷存量人员资质结束,有资质的人员数量:{}, 插入的资质条数：{}，耗时：{}秒", usersOfHavingPermission.size(), allWaitFlushData.size(), stopWatch.getTotalTimeSeconds());
        return allWaitFlushData.size();
    }

    @Transactional(rollbackFor = Exception.class)
    public Integer userPersonTypeUpdate() {
        log.info("刷存量人员类型开始");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        LambdaQueryWrapper<TzsUserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(BaseEntity::getSequenceNbr,TzsUserInfo::getPost,TzsUserInfo::getPostName);
        wrapper.isNotNull(TzsUserInfo::getPost);
        List<TzsUserInfo> users = userInfoService.list(wrapper);
        users.parallelStream().forEach(u->{
            LambdaUpdateWrapper<TzsUserInfo> updateWrapper = new LambdaUpdateWrapper<>();
            // 维保人员人员类型去掉，数据归并到作业人员-枚举处理
            updateWrapper.set(TzsUserInfo::getNewPost, u.getPost().replace("6618","6552"));
            // 由于目前系统作业人员为新增的资质，还没维护资质信息，故与测试沟通去掉post里面的6618维保人员，人员维护后程序会把6618重新冗余到post字段
            updateWrapper.set(TzsUserInfo::getPost, u.getPost().replace("6618",""));
            // 维保人员人员类型去掉，数据归并到作业人员-名称处理保持与new_post一致
            if (u.getPostName() != null) {
                updateWrapper.set(TzsUserInfo::getPostName, u.getPostName().replace("维保人员", "作业人员"));
            }
            updateWrapper.eq(BaseEntity::getSequenceNbr, u.getSequenceNbr());
            userInfoService.update(updateWrapper);
        });

        stopWatch.stop();
        log.info("刷存量人员类型结束，人员数量:{}，耗时：{}秒", users.size(), stopWatch.getTotalTimeSeconds());
        return users.size();
    }

    /**
     * 用企业新orgCode替换各个表缓存orgCode
     * 企业信息
     * 	tz_base_enterprise_info：org_code、
     * 人员信息
     * 	cb_org_usr：amos_org_code
     * 两个规定
     * 	p_static_day、p_static_week、p_static_month：org_code
     * 	p_check、p_check_input、p_check_shot：org_code
     * 	p_plan：user_dept
     * 	p_plan_task：org_code、user_dept
     * 监管业务
     * 	tzs_feedback_suggestions：supervise_org_code
     *
     * @param oldOrgCode 单位旧orgCode
     * @param newOrgCode 单位新orgCode
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean unitOrgCodeUpdate(String oldOrgCode, String newOrgCode) {
        log.info("用企业新orgCode替换各个表缓存orgCode开始");
        String newSuperviseOrgCode = newOrgCode.substring(0, newOrgCode.lastIndexOf("*"));
        HashMap<String, Object> platformCompanyInfo = (HashMap<String, Object>) Privilege.companyClient.queryByOrgcode(newSuperviseOrgCode).getResult();
        // 目前平台返回key为compnay(存在拼写错误)
        CompanyModel parentModel = JSON.parseObject(JSON.toJSONString(platformCompanyInfo.get("compnay")), CompanyModel.class);
        TzBaseEnterpriseInfo baseCompanyInfo = baseEnterpriseInfoService.getBaseMapper().selectOne(new LambdaQueryWrapper<TzBaseEnterpriseInfo>().eq(TzBaseEnterpriseInfo::getOrgCode, oldOrgCode));
        baseEnterpriseInfoService.updateUnitOrgCode(baseCompanyInfo, parentModel, baseCompanyInfo.getSuperviseOrgCode(), newSuperviseOrgCode, oldOrgCode, newOrgCode);
        log.info("用企业新orgCode替换各个表缓存orgCode结束");
        return true;
    }

    /**
     * 监管单位层级调整后，业务表（企业、设备、统计等）冗余的所有旧orgCode替换为新orgCode
     *
     * @param newOrgCode 新orgCode
     * @param oldOrgCode 旧orgCode
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String handleCompanyHisOrgCode(List<Map<String, Object>> orgCodeMap) {
        log.info("用企业新orgCode替换各个表缓存orgCode开始");
        if (ValidationUtil.isEmpty(orgCodeMap)) {
            return "error";
        }
        orgCodeMap.forEach(map -> {
            String newOrgCode = map.get("newOrgCode").toString();
            String oldOrgCode = map.get("oldOrgCode").toString();
            //1. 处理平台旧orgCode本身错误数据
            @SuppressWarnings("unchecked")
            HashMap<String, Object> platformCompanyInfo = (HashMap<String, Object>) Privilege.companyClient.queryByOrgcode(oldOrgCode).getResult();
            CompanyModel parentModel = JSON.parseObject(JSON.toJSONString(platformCompanyInfo.get(TZSCommonConstant.PLATFORM_FEIGN_RESULT_KEY_COMPANY)), CompanyModel.class);
            parentModel.setOrgCode(newOrgCode);
            Privilege.companyClient.update(parentModel, parentModel.getSequenceNbr());
            //2. 处理业务表旧orgCode错误数据
            baseEnterpriseInfoService.refreshCompanyOrgCode(null, newOrgCode, oldOrgCode);
        });
        return "success";
    }
}
