package com.yx.face.service.impl;

import com.yx.face.boot.uitls.DateUtils;
import com.yx.face.boot.uitls.RedisUtil;
import com.yx.face.dao.AdminDataShowDao;
import com.yx.face.dao.FaceLogDao;
import com.yx.face.model.entity.AdminData;
import com.yx.face.model.entity.FaceDevice;
import com.yx.face.model.entity.FaceLog;
import com.yx.face.model.search.FaceServerLogSearch;
import com.yx.face.model.vo.AdminDataVO;
import com.yx.face.model.vo.AdminDeviceVO;
import com.yx.face.model.vo.AdminVO;
import com.yx.face.model.vo.FaceLogVO;
import com.yx.face.service.AdminDataShowService;
import com.yx.face.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description:
 * @ClassName AdminDataShowServiceImpl
 * @Author WXG
 * @Date 2021/11/12 13:45
 */
@Service
@Slf4j
public class AdminDataShowServiceImpl implements AdminDataShowService {

    @Resource
    private AdminDataShowDao adminDataShowDao;
    @Resource
    private FaceLogDao faceLogDao;
    @Autowired
    private AdminService adminService;
    @Autowired
    private RedisUtil redisUtil;

    private String RName = "adminData" ;

    @Override
    public AdminDeviceVO getDeviceNumber() {
        Integer deviceAllNum =0;
        Integer deviceOnlineNum =0;
        Integer deviceOfflineNum =0;

        AdminVO adminVO = adminService.showDataGetInfo();
        Map<String,Object> maps = new HashMap<>();
        maps.put("adminVO",adminVO);
        List<FaceDevice> list = adminDataShowDao.getDeviceNumber(maps);
        if(!list.isEmpty()){
            deviceAllNum=list.size();
            for (FaceDevice faceDevice : list) {
                if(faceDevice.getOnline()==1)deviceOnlineNum++;
            }
        }
        deviceOfflineNum = deviceAllNum -deviceOnlineNum;
        AdminDeviceVO adminDeviceVO = new AdminDeviceVO();
        adminDeviceVO.setDeviceAllNum(deviceAllNum);
        adminDeviceVO.setDeviceOnlineNum(deviceOnlineNum);
        adminDeviceVO.setDeviceOfflineNum(deviceOfflineNum);

        return adminDeviceVO;
    }

    @Override
    public AdminDataVO getAdminData() {
        AdminDataVO adminDataVO = new AdminDataVO();
        AdminVO adminVO = adminService.showDataGetInfo();
        Integer totalNum = 0;//通行总人数
        Integer todayNum = 0;//今日通行总人数
        Integer redNum = 0;//红码人数
        Integer yellowNum = 0;//黄码人数
        Integer greenNum = 0;//绿码人数
        Integer notKnowNum = 0;//健康码未知人数
        Integer twExceptionNum = 0;//温度异常人数
        Integer twNormal = 0;//温度正常人数
        Integer contactRedNum = 0;//密接红码人员人数
        Integer contactYellowNum = 0;//密接黄码人员人数
        Integer exceptionNum = 0;//异常人员人数
        Integer inoculationNum = 0;//已接种疫苗人数
        Integer noInoculationNum = 0;//未接种疫苗人数
        Integer nucleicNum = 0;//七日内完成核酸检测人数

        /*
         * 1.获取所有属于该账号的adminId(adminList)
         * 2.循环adminList根据每一条的adminId到redis库中查询数据
         * 3.查询到的数据查看有效时间
         *   1.  在有效期内
         *   2.  在有效期外 则重新查询数据，并存入到redis库中
         * 4.累加数据
         * 5.放入数据返回
         *
         * */
        //1.获取adminList
        Map<String,Object> maps = new HashMap<>();
        maps.put("adminVO",adminVO);
        List<Integer> adminList = adminDataShowDao.getAdminList(maps);
        Date date = new Date();
        for (Integer adminId : adminList) {
            AdminData adminData = (AdminData)redisUtil.get(RName + adminId);
            if(adminData==null){
                adminData = getAdminDataByAdminId(adminId,null);
            }else{
                Date effectiveTime = adminData.getEffectiveTime();
                if(effectiveTime.getTime()<date.getTime()){
                    adminData = getAdminDataByAdminId(adminId,adminData);
                }
            }
            totalNum+=adminData.getTotalNum();
            todayNum+=adminData.getTodayNum();
            redNum+=adminData.getRedNum();
            yellowNum+=adminData.getYellowNum();
            greenNum+=adminData.getGreenNum();
            notKnowNum+=adminData.getNotKnowNum();
            twExceptionNum+=adminData.getTwExceptionNum();
            twNormal+=adminData.getTwNormal();
            contactRedNum+=adminData.getContactRedNum();
            contactYellowNum+=adminData.getContactYellowNum();
            exceptionNum+=adminData.getExceptionNum();
            inoculationNum+=adminData.getInoculationNum();
            noInoculationNum+=adminData.getNoInoculationNum();
            nucleicNum+=adminData.getNucleicNum();
        }
        adminDataVO.setTotalNum(totalNum);
        adminDataVO.setTodayNum(todayNum);
        adminDataVO.setRedNum(redNum);
        adminDataVO.setYellowNum(yellowNum);
        adminDataVO.setGreenNum(greenNum);
        adminDataVO.setNotKnowNum(notKnowNum);
        adminDataVO.setTwExceptionNum(twExceptionNum);
        adminDataVO.setTwNormal(twNormal);
        adminDataVO.setContactRedNum(contactRedNum);
        adminDataVO.setContactYellowNum(contactYellowNum);
        adminDataVO.setExceptionNum(exceptionNum);
        adminDataVO.setInoculationNum(inoculationNum);
        adminDataVO.setNoInoculationNum(noInoculationNum);
        adminDataVO.setNucleicNum(nucleicNum);
        return adminDataVO;
    }
    private AdminData getAdminDataByAdminId(Integer adminId,AdminData adminData){
        AdminVO info = adminService.showDataGetInfo(adminId);

        Integer totalNum = 0;//通行总人数
        Integer todayNum = 0;//今日通行总人数
        Integer redNum = 0;//红码人数
        Integer yellowNum = 0;//黄码人数
        Integer greenNum = 0;//绿码人数
        Integer notKnowNum = 0;//健康码未知人数
        Integer twExceptionNum = 0;//温度异常人数
        Integer twNormal = 0;//温度正常人数
        Integer contactRedNum = 0;//密接红码人员人数
        Integer contactYellowNum = 0;//密接黄码人员人数
        Integer exceptionNum = 0;//异常人员人数
        Integer inoculationNum = 0;//已接种疫苗人数
        Integer noInoculationNum = 0;//未接种疫苗人数
        Integer nucleicNum = 0;//七日内完成核酸检测人数
        Integer biggerNum = 0;
        List<FaceLogVO> faceLogs = new ArrayList<>();

        FaceServerLogSearch data =null;
        Map<String, Object> map = new HashMap<>();
        map.put("adminVo", info);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfToday = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        long parse = 0;
        try {
            parse = sdfToday.parse(sdfToday.format(date)).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String todayTime = sdf.format(new Date(parse));//当天0点
        map.put("todayTime", todayTime);

        if(adminData!=null){
            totalNum = adminData.getTotalNum();//通行总人数
            todayNum = adminData.getTodayNum();//今日通行总人数
            redNum = adminData.getRedNum();//红码人数
            yellowNum = adminData.getYellowNum();//黄码人数
            greenNum = adminData.getGreenNum();//绿码人数
            notKnowNum = adminData.getNotKnowNum();//健康码未知人数
            twExceptionNum = adminData.getTwExceptionNum();//温度异常人数
            twNormal = adminData.getTwNormal();//温度正常人数
            contactRedNum = adminData.getContactRedNum();//密接红码人员人数
            contactYellowNum = adminData.getContactYellowNum();//密接黄码人员人数
            exceptionNum = adminData.getExceptionNum();//异常人员人数
            inoculationNum = adminData.getInoculationNum();//已接种疫苗人数
            noInoculationNum = adminData.getNoInoculationNum();//未接种疫苗人数
            nucleicNum = adminData.getNucleicNum();//七日内完成核酸检测人数
            biggerNum = adminData.getBiggerNum();
            map.put("biggerNum", biggerNum);
            data = getFaceServerLogSearch();

        }else {
            totalNum = faceLogDao.getCount(map);
            data = new FaceServerLogSearch();
            adminData = new AdminData();
        }
        map.put("query", data);

        faceLogs = faceLogDao.getFaceLogsShowData(map);
        totalNum+=faceLogs.size();


        for (FaceLogVO faceLog : faceLogs) {
            if(faceLog.getLogId().intValue() > biggerNum){
                biggerNum = faceLog.getLogId().intValue();
            }
            Long parse1 = null;
            try {
                parse1 = sdf.parse(faceLog.getFaceTime()).getTime();
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if(parse1>parse){
                todayNum++;
                //红马及其接触人数
                if (faceLog.getJkmStatus().equals("10")) {
                    redNum++;
//                    //获取前后5分钟内的密切接触红马人员
//                    long createTime = parse1;
//                    String startTime = sdf.format(new Date(createTime - (5 * 60 * 1000)-(8*60*60*1000)));
//                    String endTime = sdf.format(new Date(createTime + (5 * 60 * 1000)-(8*60*60*1000)));
//                    List<Long> cbs = adminDataShowDao.getCountByTimeAndSn(startTime, endTime, faceLog.getDeviceSn(),faceLog.getLogId());
//                    for (Long cb : cbs) {
//                        red.add(cb);
//                    }
                }
                //黄马及其接触人数
                else if (faceLog.getJkmStatus().equals("01")){
                    yellowNum++;
//                    //获取前后5分钟内的密切接触黄马人员
//                    long createTime = parse1;
//                    String startTime = sdf.format(new Date(createTime - (5 * 60 * 1000)-(8*60*60*1000)));
//                    String endTime = sdf.format(new Date(createTime + (5 * 60 * 1000)-(8*60*60*1000)));
//                    List<Long> cbs = adminDataShowDao.getCountByTimeAndSn(startTime, endTime, faceLog.getDeviceSn(),faceLog.getLogId());
//                    for (Long cb : cbs) {
//                        yellow.add(cb);
//                    }
                }
                else if (faceLog.getJkmStatus().equals("00"))greenNum++;
                else {
                    notKnowNum++;
                }
                if (faceLog.getTwStatus().equals("1"))twExceptionNum++;
                else {
                    twNormal++;
                }
                if (faceLog.getYmStatus()!=null && !faceLog.getYmStatus().equals("")){
                    inoculationNum++;
                }else {
                    noInoculationNum++;
                }
                if (faceLog.getHsStatus()!=null && !faceLog.getHsStatus().equals("")){
                    nucleicNum++;
                }
            }

        }

        adminData.setAdminId(adminId);
        adminData.setTotalNum(totalNum);
        adminData.setTodayNum(todayNum);
        adminData.setRedNum(redNum);
        adminData.setYellowNum(yellowNum);
        adminData.setGreenNum(greenNum);
        adminData.setNotKnowNum(notKnowNum);
        adminData.setTwExceptionNum(twExceptionNum);
        adminData.setTwNormal(twNormal);
        adminData.setContactRedNum(contactRedNum);
        adminData.setContactYellowNum(contactYellowNum);
//        adminData.setContactRedNum(contactRedNum+red.size());
//        adminData.setContactYellowNum(contactYellowNum+yellow.size());
        adminData.setExceptionNum(exceptionNum);
        adminData.setInoculationNum(inoculationNum);
        adminData.setNoInoculationNum(noInoculationNum);
        adminData.setNucleicNum(nucleicNum);
        adminData.setEffectiveTime(new Date(date.getTime() + (60 * 1000)));
        adminData.setTime(date);
        adminData.setBiggerNum(biggerNum);

        /*
         * 如果红码和黄码人数不为0则需要重新统计密切接触人数
         * */
        if(yellowNum != 0){
            LinkedHashSet<Long> yellowredContact = new LinkedHashSet<>();
            /*获取黄码*/
            String zero = getZero();//获取当天的0点；
            List<FaceLogVO> faceLogVOList = faceLogDao.getYellow(adminId, zero, "01");
            for (FaceLogVO faceLogVO : faceLogVOList) {
                Long faceTime=null;
                try {
                    faceTime = sdf.parse(faceLogVO.getFaceTime()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                String startTime = sdf.format(new Date(faceTime - (5 * 60 * 1000)));
                String endTime = sdf.format(new Date(faceTime + (5 * 60 * 1000)));
                List<Long> cbs = adminDataShowDao.getCountByTimeAndSn(startTime, endTime, faceLogVO.getDeviceSn(),faceLogVO.getLogId());
                for (Long cb : cbs) {
                    yellowredContact.add(cb);
                }
            }
            adminData.setContactYellowNum(yellowredContact.size());
        }
        if(redNum != 0){
            LinkedHashSet<Long> redContact = new LinkedHashSet<>();
            /*获取黄码*/
            String zero = getZero();//获取当天的0点；
            List<FaceLogVO> faceLogVOList = faceLogDao.getYellow(adminId, zero, "10");
            for (FaceLogVO faceLogVO : faceLogVOList) {
                Long faceTime=null;
                try {
                    faceTime = sdf.parse(faceLogVO.getFaceTime()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                String startTime = sdf.format(new Date(faceTime - (5 * 60 * 1000)));
                String endTime = sdf.format(new Date(faceTime + (5 * 60 * 1000)));
                List<Long> cbs = adminDataShowDao.getCountByTimeAndSn(startTime, endTime, faceLogVO.getDeviceSn(),faceLogVO.getLogId());
                for (Long cb : cbs) {
                    redContact.add(cb);
                }
            }
            adminData.setContactRedNum(redContact.size());
        }

        //将数据存入redis
        redisUtil.set(RName + adminId,adminData);
        return adminData;
    }
    private String getZero(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
        return sdf.format(zero);
    }

    private FaceServerLogSearch getFaceServerLogSearch() {
        FaceServerLogSearch data = new FaceServerLogSearch();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();

        calendar.add(5,1);
        Date one = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        data.setStartTime(sdf.format(zero));
        data.setEndTime(sdf.format(one));

        return data;
    }
}
