package com.rongwei.sfcommon.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwe.scentity.domian.AspSafetyProductObjective;
import com.rongwe.scentity.domian.AspSafetyProductObjectiveResult;
import com.rongwe.scentity.domian.AspSafetyProductObjectiveResultScoreDetail;
import com.rongwe.scentity.domian.AspSafetyProductObjectiveScoreDetail;
import com.rongwe.scentity.vo.RoleIdAndUserIdsVo;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.safecommon.utils.CXCommonUtils;
import com.rongwei.sfcommon.sys.dao.AspSafetyProductObjectiveDao;
import com.rongwei.sfcommon.sys.service.AspSafetyProductObjectiveResultScoreDetailService;
import com.rongwei.sfcommon.sys.service.AspSafetyProductObjectiveResultService;
import com.rongwei.sfcommon.sys.service.AspSafetyProductObjectiveScoreDetailService;
import com.rongwei.sfcommon.sys.service.AspSafetyProductObjectiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

import static com.rongwei.safecommon.utils.SaveConstans.NotifyContent.OBSERVATION_CONTENT;
import static com.rongwei.safecommon.utils.SaveConstans.NotifyTitle.OBSERVATION_TITLE;
import static com.rongwei.safecommon.utils.SaveConstans.NotifyType.OBSERVATION_AUDIT;

/**
 * @author ：sc
 * @since ：2023/12/7
 */
@Service
public class AspSafetyProductObjectiveServiceImpl extends ServiceImpl<AspSafetyProductObjectiveDao, AspSafetyProductObjective> implements AspSafetyProductObjectiveService {
    @Autowired
    private AspSafetyProductObjectiveScoreDetailService scoreDetailService;
    @Autowired
    private AspSafetyProductObjectiveResultService objectiveResultService;
    @Autowired
    private AspSafetyProductObjectiveResultScoreDetailService objectiveResultScoreDetailService;

    @Override
    public void safetyResult() {
        //==============查询所有需要生成的目标
        //获取当前季度(1,2,3,4)
        int quarter = DateUtil.quarter(DateUtil.date());
        //查询考核主表今年、当前季度，是否有已经生成的数据
        List<AspSafetyProductObjectiveResult> aspSafetyProductObjectiveResults = objectiveResultService.getBaseMapper().selectList(new QueryWrapper<AspSafetyProductObjectiveResult>().lambda()
                .like(AspSafetyProductObjectiveResult::getYear, DateUtil.thisYear())
                .eq(AspSafetyProductObjectiveResult::getQuerter, quarter));
        //获取mainID
        List<String> hadMainIDList = aspSafetyProductObjectiveResults.stream().map(AspSafetyProductObjectiveResult::getMainid).collect(Collectors.toList());

        //查询今年的所有目标数据
        List<AspSafetyProductObjective> aspSafetyProductObjectiveList = this.baseMapper.selectList(new QueryWrapper<AspSafetyProductObjective>().lambda().like(AspSafetyProductObjective::getYear, DateUtil.thisYear()));
        //过滤掉已经生成考核的数据
        List<AspSafetyProductObjective> aspSafetyProductObjectives = aspSafetyProductObjectiveList.stream().filter(item -> !hadMainIDList.contains(item.getId())).collect(Collectors.toList());

        //遍历目标获取所有目标的ID集合
        List<String> collectIds = aspSafetyProductObjectives.stream().map(AspSafetyProductObjective::getId).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(collectIds)) {
            return;
        }
        //查询出所有目标的子表数据
        List<AspSafetyProductObjectiveScoreDetail> scoreDetails = scoreDetailService.getBaseMapper().selectList(new QueryWrapper<AspSafetyProductObjectiveScoreDetail>().lambda().in(AspSafetyProductObjectiveScoreDetail::getMainid, collectIds));

        //=============遍历目标组装考核模板数据
        //考核主表
        List<AspSafetyProductObjectiveResult> mainResList = new LinkedList<>();
        //考核子表
        List<AspSafetyProductObjectiveResultScoreDetail> childResList = new LinkedList<>();


        aspSafetyProductObjectives.forEach(item -> {
            //目标表主键
            String id = item.getId();
            //获取对应的目标子表
            List<AspSafetyProductObjectiveScoreDetail> collectDetails = scoreDetails.stream().filter(item2 -> id.equals(item2.getMainid())).collect(Collectors.toList());
            //转换目标主表
            AspSafetyProductObjectiveResult aspSafetyProductObjectiveResult = BeanUtil.toBean(item, AspSafetyProductObjectiveResult.class);
            //默认当前季度
            aspSafetyProductObjectiveResult.setQuerter(String.valueOf(quarter));
            //修改uuid
            String newId = SecurityUtil.getUUID();
            aspSafetyProductObjectiveResult.setId(newId);
            //设置考核主表的mainID
            aspSafetyProductObjectiveResult.setMainid(id);


            //放入最终插入字段
            mainResList.add(aspSafetyProductObjectiveResult);

            collectDetails.forEach(item3 -> {
                //转换考核子表
                AspSafetyProductObjectiveResultScoreDetail detail = BeanUtil.toBean(item3, AspSafetyProductObjectiveResultScoreDetail.class);
                //修改考核子表的ID
                detail.setId(SecurityUtil.getUUID());
                //修改考核子表的主表ID
                detail.setMainid(newId);
                //放入最终考核子表插入字段
                childResList.add(detail);
            });

        });


        //==============批量插入考核模板数据
        //插入考核主表
        objectiveResultService.saveBatch(mainResList);
        //插入考核子表
        objectiveResultScoreDetailService.saveBatch(childResList);

        //发送已生成考核的消息,按照工厂、指标级别，分别下发给对应角色的人
        sendMessage(mainResList);

    }

    @Override
    public void reportObservationConfig(List<String> list) {
        if(!list.isEmpty()){
            // {"ad8106741bf547778d01d556e371ac98/34d64aaae0344b109ad8909f3afa4d40/69"}
            for (String str : list) {
                String[] split = str.split("/");
                if(split.length<3){
                    return;
                }
                String value = split[0];
                String userId = split[1];
                String count = split[2];
                //系统通知（移动端和PC端个人工作台）
                CXCommonUtils.sendNotify(OBSERVATION_TITLE,
                        String.format(OBSERVATION_CONTENT, count),
                        null,
                        Collections.singletonList(userId),
                        value,
                        OBSERVATION_AUDIT,
                        false);

            }
        }
    }

    private void sendMessage(List<AspSafetyProductObjectiveResult> mainResList) {
        //维护指标级别对应的角色ID
        //objectivelevel：指标级别。
        // 10：工厂级，生产副总：77a13d95b53e42068e6f0c1d60f07df7
        // 20：部门级，部门长：b104293d47e34df8847d1634c29ab031
        // 30：车间级，车间主任：16963f62b94149d9ae16eabc9248999b
        // 40：工段级，工段主管：104ac71c72704bbd953da6d7c167ed3a
        // 50：班组级，班长：efed8df42bde46c9970c1476e74d6374
        Map<String, String> levelMap = new HashMap<>();
        levelMap.put("10", "77a13d95b53e42068e6f0c1d60f07df7");
        levelMap.put("20", "b104293d47e34df8847d1634c29ab031");
        levelMap.put("30", "16963f62b94149d9ae16eabc9248999b");
        levelMap.put("40", "104ac71c72704bbd953da6d7c167ed3a");
        levelMap.put("50", "efed8df42bde46c9970c1476e74d6374");
        //获取需要发送消息的工厂
        Set<String> tenantIds = mainResList.stream().map(AspSafetyProductObjectiveResult::getTenantid).collect(Collectors.toSet());
        //整理工厂下、各个指标级别、对应的角色（职位）下的员工ID，：<工厂ID，<角色ID，用户IDs（英文逗号隔开）>>
        Map<String, Map<String, String>> tenantManagerMap = new HashMap<>();
        tenantIds.forEach(tenantId -> {
            List<RoleIdAndUserIdsVo> roleIdAndUserIdsVos = this.baseMapper.selectManagerByTenantId(tenantId);
            Map<String, String> map = new HashMap<>();
            roleIdAndUserIdsVos.forEach(item -> {
                if (ObjectUtil.isNotEmpty(item.getId())) {
                    map.put(item.getId(), item.getUserIds());
                }
            });
            tenantManagerMap.put(tenantId, map);
        });
        //处理考核主表，发送消息
        mainResList.forEach(item -> {
            //判断工厂ID是否存在
            if (ObjectUtil.isEmpty(item.getTenantid())) {
                return;
            }
            //判断指标级别是否存在
            if (ObjectUtil.isEmpty(item.getObjectivelevel())) {
                return;
            }
            //获取该工厂下的角色对应的USERIDs
            Map<String, String> map = tenantManagerMap.get(item.getTenantid());
            //获取该数据的指标级别对应的角色ID
            String roleId = levelMap.get(item.getObjectivelevel());
            //获取该消息对应的用户IDs
            if (ObjectUtil.isEmpty(roleId)) {
                return;
            }
            List<String> userIdList = Arrays.asList(map.get(roleId).split(","));
            //发送消息
            CXCommonUtils.sendNotify("目标考核",
                    "目标考核:【" + item.getYear().split("-")[0] + "】年，【" + item.getQuerter() + "】季度，【" + item.getDepartname() + "】单位的考核已生成，请及时完善",
                    null,
                    userIdList,
                    item.getId(),
                    "targetassessment");
        });
    }
}
