package com.zehong.system.service.impl;

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

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zehong.common.utils.DateUtils;
import com.zehong.common.utils.SecurityUtils;
import com.zehong.common.utils.bean.BeanUtils;
import com.zehong.system.domain.TTask;
import com.zehong.system.domain.TUserInspect;
import com.zehong.system.domain.vo.InspectNumStatisticByInspectorExportVo;
import com.zehong.system.domain.vo.InspectNumStatisticByVillageVo;
import com.zehong.system.domain.vo.UserTaskInspect;
import com.zehong.system.domain.vo.Userinstpect;
import com.zehong.system.mapper.TDangerMapper;
import com.zehong.system.mapper.TTaskMapper;
import com.zehong.system.mapper.TUserInspectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zehong.system.mapper.TTaskInspectMapper;
import com.zehong.system.domain.TTaskInspect;
import com.zehong.system.service.ITTaskInspectService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 安检任务执行Service业务层处理
 * 
 * @author zehong
 * @date 2023-11-07
 */
@Service
public class TTaskInspectServiceImpl implements ITTaskInspectService 
{
    @Autowired
    private TTaskInspectMapper tTaskInspectMapper;
    @Autowired
    private TUserInspectMapper tUserInspectMapper;
    @Autowired
    private TDangerMapper tDangerMapper;
    @Autowired
    private TTaskMapper tTaskMapper;
    /**
     * 查询安检任务执行
     * 
     * @param id 安检任务执行ID
     * @return 安检任务执行
     */
    @Override
    public TTaskInspect selectTTaskInspectById(Long id)
    {
        return tTaskInspectMapper.selectTTaskInspectById(id);
    }

    /**
     * 查询安检任务执行列表
     * 
     * @param tTaskInspect 安检任务执行
     * @return 安检任务执行
     */
    @Override
    public List<TTaskInspect> selectTTaskInspectList(TTaskInspect tTaskInspect)
    {
        return tTaskInspectMapper.selectTTaskInspectList(tTaskInspect);
    }

    @Override
    public List<TTaskInspect> selectJuminInspectList(TTaskInspect tTaskInspect)
    {
        return tTaskInspectMapper.selectJuminInspectList(tTaskInspect);
    }

    /**
     * 居民用户安检任务执行
     * @param userTaskInspect
     * @return
     */
    @Override
    public List<UserTaskInspect> selectJMinspect(UserTaskInspect userTaskInspect)
    {
        return tTaskInspectMapper.selectJMinspect(userTaskInspect);
    }
    @Override
    public List<UserTaskInspect> selectCYinspect(UserTaskInspect userTaskInspect)
    {
        return tTaskInspectMapper.selectCYinspect(userTaskInspect);
    }
    /**
     * 查询未完成的安检单
     */
    public TTaskInspect selectBytaskIduserId(TTaskInspect tTaskInspect){
        return tTaskInspectMapper.selectBytaskIduserId(tTaskInspect);
    }
    /**
     * 新增安检任务执行
     * 
     * @param tTaskInspect 安检任务执行
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertTTaskInspect(TTaskInspect tTaskInspect)
    {
        tTaskInspect.setCreateTime(DateUtils.getNowDate());
        int a = tTaskInspectMapper.insertTTaskInspect(tTaskInspect);
        TUserInspect u = tUserInspectMapper.selectBytaskIdReceiveId(tTaskInspect.getTaskId(),
                tTaskInspect.getReceiveId());
                if(tTaskInspect.getStatus()!=-1){
                    if(u==null){
                        u = new TUserInspect();
                        u.setTaskId(tTaskInspect.getTaskId());
                        u.setInspectId(tTaskInspect.getId());
                        u.setUserType(tTaskInspect.getType().intValue());
                        u.setUserId(tTaskInspect.getReceiveId());
                        u.setUpdateTime(new Date());
                        tUserInspectMapper.insertTUserInspect(u);
                    }else{
                        u.setInspectId(tTaskInspect.getId());
                        u.setUpdateTime(new Date());
                        tUserInspectMapper.updateTUserInspect(u);
                    }
                }
        return a;
    }

    /**
     * 修改安检任务执行
     * 
     * @param tTaskInspect 安检任务执行
     * @return 结果
     */
    @Override
    public int updateTTaskInspect(TTaskInspect tTaskInspect)
    {
        TUserInspect u = tUserInspectMapper.selectBytaskIdReceiveId(tTaskInspect.getTaskId(),
                tTaskInspect.getReceiveId());
        if(tTaskInspect.getStatus()!=-1){
            tDangerMapper.updateByInspect(tTaskInspect.getId(),1);
            if(u==null){
                u = new TUserInspect();
                u.setTaskId(tTaskInspect.getTaskId());
                u.setInspectId(tTaskInspect.getId());
                u.setUserType(tTaskInspect.getType().intValue());
                u.setUserId(tTaskInspect.getReceiveId());
                u.setUpdateTime(new Date());
                tUserInspectMapper.insertTUserInspect(u);
            }else{
                u.setInspectId(tTaskInspect.getId());
                u.setUpdateTime(new Date());
                tUserInspectMapper.updateTUserInspect(u);
            }
        }
        return tTaskInspectMapper.updateTTaskInspect(tTaskInspect);
    }

    /**
     * 批量删除安检任务执行
     * 
     * @param ids 需要删除的安检任务执行ID
     * @return 结果
     */
    @Override
    public int deleteTTaskInspectByIds(Long[] ids)
    {
        for(Long id :ids){
            tDangerMapper.deleteTDangerByInspectt(id,1);
        }
        return tTaskInspectMapper.deleteTTaskInspectByIds(ids);
    }

    /**
     * 删除安检任务执行信息
     * 
     * @param id 安检任务执行ID
     * @return 结果
     */
    @Override
    public int deleteTTaskInspectById(Long id)
    {
        return tTaskInspectMapper.deleteTTaskInspectById(id);
    }

    /**
     * 安检任务统计
     * @param tTaskInspect 安检实体
     * @return
     */
    @Override
    public List<Map<String,Object>> taskInspectStatistics(TTaskInspect tTaskInspect){
        return tTaskInspectMapper.taskInspectStatistics(tTaskInspect);
    }

    /**
     * 小程序居民安检列表 详情
     * @return
     */
    @Override
    public List<Userinstpect> anjiandetaillist(Userinstpect userinstpect){
        //安检数改为当前登录人只查看自己的安检信息 2024-05-28需求要求
        if(1 != userinstpect.getStatus() && 1 != userinstpect.getType()){
            userinstpect.setMemberId(SecurityUtils.getLoginUser().getUser().getUserId());
        }
        if(userinstpect.getType()==1){
            return tTaskInspectMapper.jmAnjianDetail(userinstpect);
        }else if(userinstpect.getType()==2){
            return tTaskInspectMapper.cyAnjianDetail(userinstpect);
        }else {
            return tTaskInspectMapper.gyAnjianDetail(userinstpect);
        }
    }

    /**
     * 到访不遇查询
     * @param userTaskInspect
     * @return
     */
    @Override
    public List<UserTaskInspect> selectVisitorMissInfo (UserTaskInspect userTaskInspect){
        return tTaskInspectMapper.selectVisitorMissInfo(userTaskInspect);
    }

    /**
     * 安检量统计
     * @param param 入参
     * @return
     */
    @Override
    public List<Map<String,Object>> inspectNumStatisticByInspector(Map<String,String> param){
        //根据安检人和安检任务汇总
        List<Map<String,Object>> statisticResult = tTaskInspectMapper.inspectNumStatisticByInspector(param);
        //根据任务汇总同一个任务下的安检数量汇总并计算未安检量(2026-03-10 pc端去掉未安检数)
        //statisticNoInspectNum(statisticResult,param);
        //根据安检人汇总安检量
        return statisticInspectByInspector(statisticResult);
    }

    /**
     * 根据任务汇总未安检量
     * @param statisticResult 统计结果
     * @param
     */
    private void statisticNoInspectNum(List<Map<String,Object>> statisticResult,Map<String,String> param){
        Map<Object, List<Map<String, Object>>> groupByTask;
        //筛选时间时重新计算未安检量
        if(null != param.get("beginTime") || null != param.get("memberId")){
            Map<String,String> newParam = new HashMap<>();
            newParam.put("village",param.get("village"));
            newParam.put("street",param.get("street"));
            List<Map<String,Object>> statisticResultNew = tTaskInspectMapper.inspectNumStatisticByInspector(newParam);
            groupByTask = statisticResultNew.stream().collect(Collectors.groupingBy(e ->e.get("taskId")));
        }else{
            groupByTask = statisticResult.stream().collect(Collectors.groupingBy(e ->e.get("taskId")));
        }
        for(Object key : groupByTask.keySet()){
            List<Map<String, Object>> inspectInfoList = groupByTask.get(key);
            //汇总任务安检量
            int totalInspectNum = 0;
            for(Map<String, Object> inspectInfo : inspectInfoList){
                if(null != inspectInfo.get("totalInspectNum")){
                    totalInspectNum += ((Long)inspectInfo.get("totalInspectNum")).intValue();
                }
            }
            //计算任务未安检量并写入数据
            for(Map<String,Object> taskInspectInfo : statisticResult){
                if(taskInspectInfo.get("taskId").equals(key) && null != taskInspectInfo.get("totalUserNum")){
                    taskInspectInfo.put("noInspectNum",((Long)taskInspectInfo.get("totalUserNum")).intValue() - totalInspectNum);
                }
            }
        }
    }

    /**
     * 根据安检人汇总安检量
     * @param statisticResult 统计结果
     * @return
     */
    private List<Map<String,Object>> statisticInspectByInspector(List<Map<String,Object>> statisticResult){
        List<Map<String,Object>> result = new ArrayList<>();
        Map<Object, List<Map<String, Object>>> groupByInspector = statisticResult.stream().collect(Collectors.groupingBy(e ->e.get("memberId")));
        for(Map.Entry<Object, List<Map<String, Object>>> entry : groupByInspector.entrySet()){
            List<Map<String, Object>> inspectInfoList = entry.getValue();
            Map<String, Object> statisticResultByInspector = new HashMap<>();
            for(Map<String, Object> inspectInfo : inspectInfoList){
                for(String key : inspectInfo.keySet()){
                    if(!key.equals("totalUserNum") && !key.equals("totalInspectNum") && !key.equals("memberId") && !key.equals("taskId") && !key.equals("inspector")){
                        Object item = statisticResultByInspector.get(key);
                        //结果中不存在新增
                        if(null == item){
                            statisticResultByInspector.put(key,key.equals("noInspectNum") ? (int)inspectInfo.get(key) :((BigDecimal)inspectInfo.get(key)).intValue());
                        }else{
                            Object info = inspectInfo.get(key);
                            if(null != info){
                                statisticResultByInspector.put(key,(int)statisticResultByInspector.get(key) + (key.equals("noInspectNum") ? (int)inspectInfo.get(key) :((BigDecimal)inspectInfo.get(key)).intValue()));
                            }
                        }
                    }
                }

            }
            statisticResultByInspector.put("inspector",inspectInfoList.get(0).get("inspector"));
            result.add(statisticResultByInspector);
        }
        return result;
    }


    /**
     * 安检量统计导出
     * @param param 入参
     * @return
     */
    @Override
    public List<InspectNumStatisticByInspectorExportVo> inspectNumStatisticByInspectorExport(Map<String,String> param){
        List<InspectNumStatisticByInspectorExportVo> export = new ArrayList<>();
        //获取汇总信息
        List<Map<String,Object>> result = inspectNumStatisticByInspector(param);
        InspectNumStatisticByInspectorExportVo statisticInfo = new InspectNumStatisticByInspectorExportVo();
        statisticInfo.setInspector("汇总");
        statisticInfo.setNoInspectNum("-");
        export.add(statisticInfo);
        for(Map info : result){
            ObjectMapper objectMapper = new ObjectMapper();
            InspectNumStatisticByInspectorExportVo exportInfo = objectMapper.convertValue(info,InspectNumStatisticByInspectorExportVo.class);
            int total = (int)info.get("normalInspectNum") + (int)info.get("refuseInspectNum") + (int)info.get("stopInspectNum") + (int)info.get("missInspectNum");
            exportInfo.setTotal(total);
            //statisticInfo.setNoInspectNum(statisticInfo.getNoInspectNum() + (int) info.get("noInspectNum"));
            statisticInfo.setNormalInspectNum(statisticInfo.getNormalInspectNum() + (int) info.get("normalInspectNum"));
            statisticInfo.setRefuseInspectNum(statisticInfo.getRefuseInspectNum() + (int) info.get("refuseInspectNum"));
            statisticInfo.setStopInspectNum(statisticInfo.getStopInspectNum() + (int) info.get("stopInspectNum"));
            statisticInfo.setMissInspectNum(statisticInfo.getMissInspectNum() + (int) info.get("missInspectNum"));
            statisticInfo.setDangerNum(statisticInfo.getDangerNum() + (int) info.get("dangerNum"));
            statisticInfo.setNoDangerNum(statisticInfo.getNoDangerNum() + (int) info.get("noDangerNum"));
            statisticInfo.setTotal(statisticInfo.getTotal() + total);
            export.add(exportInfo);
        }
        return export;
    }


    /**
     * 安检量统计
     * @param param 入参
     * @return
     */
    @Override
    public Map<String,Object> inspectNumStatisticByInspectorForWeiXin(Map<String,String> param){
        Map<String,Object> result = new HashMap<>();
        //根据安检人和安检任务汇总
        List<Map<String,Object>> statisticResult = tTaskInspectMapper.inspectNumStatisticByInspector(param);
        //根据任务汇总同一个任务下的安检数量汇总并计算未安检量(2026-03-10 pc端去掉未安检数)
        //statisticNoInspectNum(statisticResult,param);
        //根据安检人汇总安检量
        List<Map<String,Object>> inspectorList =  statisticInspectByInspector(statisticResult);
        result.put("inspectStatisticInfo", CollectionUtils.isEmpty(inspectorList) ? new HashMap<>()  : inspectorList.get(0));
        result.put("taskStatisticInfo",tTaskInspectMapper.inspectNumStatisticByTask(param));
        return result;
    }


    /**
     * 居民村庄安检量统计
     * @param param 入参
     * @return
     */
    @Override
    public List<InspectNumStatisticByVillageVo> inspectNumStatisticByVillage(Map<String,String> param){
        return tTaskInspectMapper.inspectNumStatisticByVillage(param);
    }



    /**
     * 工商业安检量统计
     * @param param 入参
     * @return
     */
    @Override
    public List<Map<String,Object>> inspectNumStatisticByInspectorAndType(Map<String,String> param){
        return tTaskInspectMapper.inspectNumStatisticByInspectorAndType(param);
    }


    /**
     * 安检量统计导出
     * @param param 入参
     * @return
     */
    @Override
    public List<InspectNumStatisticByInspectorExportVo> inspectNumStatisticByInspectorAndTypeExport(Map<String,String> param){
        List<InspectNumStatisticByInspectorExportVo> export = new ArrayList<>();
        //获取汇总信息
        List<Map<String,Object>> result = inspectNumStatisticByInspectorAndType(param);
        InspectNumStatisticByInspectorExportVo statisticInfo = new InspectNumStatisticByInspectorExportVo();
        statisticInfo.setInspector("汇总");
        statisticInfo.setNoInspectNum("-");
        export.add(statisticInfo);
        for(Map info : result){
            ObjectMapper objectMapper = new ObjectMapper();
            InspectNumStatisticByInspectorExportVo exportInfo = objectMapper.convertValue(info,InspectNumStatisticByInspectorExportVo.class);
            int total = (int)info.get("normalInspectNum") + (int)info.get("refuseInspectNum") + (int)info.get("stopInspectNum") + (int)info.get("missInspectNum");
            exportInfo.setTotal(total);
            //statisticInfo.setNoInspectNum(statisticInfo.getNoInspectNum() + (int) info.get("noInspectNum"));
            statisticInfo.setNormalInspectNum(statisticInfo.getNormalInspectNum() + (int) info.get("normalInspectNum"));
            statisticInfo.setRefuseInspectNum(statisticInfo.getRefuseInspectNum() + (int) info.get("refuseInspectNum"));
            statisticInfo.setStopInspectNum(statisticInfo.getStopInspectNum() + (int) info.get("stopInspectNum"));
            statisticInfo.setMissInspectNum(statisticInfo.getMissInspectNum() + (int) info.get("missInspectNum"));
            statisticInfo.setDangerNum(statisticInfo.getDangerNum() + (int) info.get("dangerNum"));
            statisticInfo.setNoDangerNum(statisticInfo.getNoDangerNum() + (int) info.get("noDangerNum"));
            statisticInfo.setTotal(statisticInfo.getTotal() + total);
            export.add(exportInfo);
        }
        return export;
    }
}
