package com.jpsoft.shinestar.modules.base.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.config.TemperatureConfig;
import com.jpsoft.shinestar.modules.base.dao.PersonDeviceFilterLogDAO;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.LApiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 墨鱼_mo
 * @date 2020-3-20 9:14
 */
@Slf4j
@Transactional
@Component(value = "personDeviceFilterLogService")
public class PersonDeviceFilterLogServiceImpl implements PersonDeviceFilterLogService {
    @Autowired
    private OSSConfig ossConfig;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private CompanySuperviseService companySuperviseService;

    @Autowired
    private CheckNumCompanyService checkNumCompanyService;

    @Resource(name = "personDeviceFilterLogDAO")
    private PersonDeviceFilterLogDAO personDeviceFilterLogDAO;

    @Autowired
    private TemperatureConfig temperatureConfig;

    @Override
    public PersonDeviceFilterLog get(Long id) {
        // TODO Auto-generated method stub
        return personDeviceFilterLogDAO.get(id);
    }

    @Override
    public void insertFilterLog(String deviceNo, PersonInfo personInfo, BigDecimal temperature, String faceImageUrl, Date recordDate,
                                int matchStatus,String matchMsg,int matchFaceId,String address,PersonHealthLedger personHealthLedger) {
        try {
            //记录的时间段
            DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(deviceNo);

            Long personId = personInfo.getId();

            if (personId!=0) {
                DateTime now = DateTime.now();

                log.warn("查询{}最近5分钟测温记录",personId);
                List<PersonDeviceFilterLog> personDeviceFilterLogs = personDeviceFilterLogDAO.findByPersonAndDeviceNoAndTime(personId,
                        deviceNo,
                        now.minusMinutes(5).toString("yyyy-MM-dd HH:mm"),
                        now.toString("yyyy-MM-dd HH:mm"));

                PersonDeviceFilterLog personDeviceFilterLog = null;

                boolean exist = false;

                if (personDeviceFilterLogs.size()>0){
                    personDeviceFilterLog = personDeviceFilterLogs.get(0);
                    exist = true;
                }
                else{
                    personDeviceFilterLog = new PersonDeviceFilterLog();
                }

                personDeviceFilterLog.setDeviceNo(deviceNo);
                personDeviceFilterLog.setPersonId(personId);
                personDeviceFilterLog.setRecordTime(recordDate);
                personDeviceFilterLog.setFaceImage(faceImageUrl);
                personDeviceFilterLog.setMatchStatus(matchStatus);
                personDeviceFilterLog.setMatchFaceId(matchFaceId);
                personDeviceFilterLog.setMatchMsg(matchMsg);
                personDeviceFilterLog.setDelFlag(false);

                log.warn("{}最近5分钟测温记录是否存在:{}",personId,exist);

                if (exist) {
                    BigDecimal oldTemper = personDeviceFilterLog.getTemperature();
                    personDeviceFilterLog.setTemperature(temperature);
                    personDeviceFilterLog.setUpdateTime(new Date());

                    if (!LApiUtil.compareToInterval(oldTemper, temperatureConfig.getMin(), temperatureConfig.getMax())) {
                        if (LApiUtil.compareToInterval(temperature, temperatureConfig.getMin(), temperatureConfig.getMax())) {
                            personDeviceFilterLogDAO.update(personDeviceFilterLog);
                        } else {
                            if (temperature.compareTo(oldTemper) == -1) {
                                personDeviceFilterLogDAO.update(personDeviceFilterLog);
                            }
                        }
                    }
                } else {
                    personDeviceFilterLog.setTemperature(temperature);
                    personDeviceFilterLog.setCreateTime(new Date());
                    personDeviceFilterLogDAO.insert(personDeviceFilterLog);
                }

                new Thread(() -> {
                    try {
                        addCheckNumForCompany(personId, recordDate);
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }).start();


                 try{

                     Map<String,Object> map = new HashMap<>();
                     map.put("deviceNo",deviceNo);
                     map.put("personInfo",personInfo);
                     map.put("recordDate",recordDate);
                     map.put("temperature",temperature);
                     map.put("address",address);
                     map.put("personHealthLedger",personHealthLedger);
                     rabbitTemplate.convertAndSend("companySuperviseQueue",map);
                    }catch (Exception ex){
                        log.error(ex.getMessage(),ex);
                    }



            }
            if (personId == 0L && temperature.compareTo(temperatureConfig.getMax()) == 1){
                addVisitorCheckNumForCompany(deviceInfo.getCompanyId(), temperature, recordDate);
            }
        } catch (Exception ex) {
            log.error(ex.getMessage(),ex);
        }
    }

    @Override
    public void deviceInsertFilterLog(String deviceNo, BigDecimal temperature, JSONObject faceImageJson, JSONObject libMatInfoListJson, JSONObject matchPersonInfo, Date date, Integer maskFlag, String faceImageUrl,String address,PersonHealthLedger personHealthLedger) {
        PersonInfo personInfo = LApiUtil.getPersonCode(libMatInfoListJson, matchPersonInfo);

        LApiUtil lApiUtil = new LApiUtil();

        int matchStatus = 0;
        String matchMsg = "";
        int matchFaceId = 0;

        if (StringUtils.isNotBlank(libMatInfoListJson.getStr("MatchStatus"))) {
            matchStatus = libMatInfoListJson.getInt("MatchStatus");
            matchMsg = lApiUtil.getMatchMsg(libMatInfoListJson.getInt("MatchStatus"),maskFlag,temperature,temperatureConfig);
          //  matchFaceId = libMatInfoListJson.getInt("MatchFaceID");
            if(libMatInfoListJson.containsKey("MatchFaceID")){
                matchFaceId = libMatInfoListJson.getInt("MatchFaceID");
            }

        }

        insertFilterLog(deviceNo,personInfo,temperature,faceImageUrl,date,matchStatus,matchMsg,matchFaceId,address,personHealthLedger);
    }

    public void addCheckNumForCompany(Long personId, Date date) {

        String recordTime = DateUtil.format(date, "yyyy-MM-dd");
        PersonInfo personInfo = personInfoService.get(personId);
        if (personInfo!=null && StringUtils.isNotBlank(personInfo.getCompanyId())) {
            CheckNumCompany checkNumCompany = checkNumCompanyService.findByCompanyIdAndRecordTime(personInfo.getCompanyId(), recordTime);
            if (checkNumCompany != null) {
                Integer checkNum = checkNumCompany.getCheckNum().intValue() + 1;
                checkNumCompany.setCheckNum(checkNum.longValue());
                checkNumCompanyService.update(checkNumCompany);
            } else {
                CheckNumCompany checkNumCompany1 = new CheckNumCompany();
                checkNumCompany1.setCompanyId(personInfo.getCompanyId());
                checkNumCompany1.setCheckNum(1L);
                checkNumCompany1.setDelFlag(false);
                checkNumCompany1.setRecordTime(recordTime);
                checkNumCompany1.setCreateTime(new Date());
                checkNumCompanyService.insert(checkNumCompany1);
            }
        }
    }

    public void addVisitorCheckNumForCompany(String companyId, BigDecimal temperature, Date date) {

        String recordTime = DateUtil.format(date, "yyyy-MM-dd");

        if (StringUtils.isNotBlank(companyId)) {
            CheckNumCompany checkNumCompany = checkNumCompanyService.findByCompanyIdAndRecordTime(companyId, recordTime);
            if (checkNumCompany != null) {
                Integer checkNum = checkNumCompany.getCheckNum().intValue() + 1;
                checkNumCompany.setCheckNum(checkNum.longValue());
                checkNumCompanyService.update(checkNumCompany);
            } else {
                CheckNumCompany checkNumCompany1 = new CheckNumCompany();
                checkNumCompany1.setCompanyId(companyId);
                checkNumCompany1.setCheckNum(1L);
                checkNumCompany1.setDelFlag(false);
                checkNumCompany1.setRecordTime(recordTime);
                checkNumCompany1.setCreateTime(new Date());
                checkNumCompanyService.insert(checkNumCompany1);
            }
        }
    }

    @Override
    public Page<PersonDeviceFilterLog> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<PersonDeviceFilterLog> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            personDeviceFilterLogDAO.search(searchParams, sortList);
        });

        return page;
    }

    @Override
    public List<PersonDeviceFilterLog> findByPersonAndDate(Long personId, String startDate, String endDate) {
        return personDeviceFilterLogDAO.findByPersonAndDate(personId, startDate, endDate);
    }

    @Override
    public PersonDeviceFilterLog findByPersonOrderTemperature(Long personId, String startDate, String endDate) {
        return personDeviceFilterLogDAO.findByPersonOrderTemperature(personId, startDate, endDate);
    }

    @Override
    public PersonDeviceFilterLog lastPersonLog(Long personId) {
        return personDeviceFilterLogDAO.lastPersonLog(personId);
    }

    @Override
    public PersonDeviceFilterLog getByPersonIdAndDate(Long personId, String startDate, String endDate) {
        return personDeviceFilterLogDAO.getByPersonIdAndDate(personId, startDate, endDate);
    }


    @Override
    public List<PersonDeviceFilterLog> list() {
        return personDeviceFilterLogDAO.list();
    }

    @Override
    public long countByTimeRangeAndCompanyCode(String companyCode, Long personId, int status,BigDecimal temperatureMax, Date startDate, Date endDate) {
        return personDeviceFilterLogDAO.countByTimeRangeAndCompanyCode(companyCode, personId, status,temperatureMax, startDate, endDate);
    }

    @Override
    public List<PersonDeviceFilterLog> temperatureNormalStatistics(String companyCode, BigDecimal temperature, Date startDate, Date endDate) {

        return personDeviceFilterLogDAO.temperatureNormalStatistics(companyCode, temperature, startDate, endDate);
    }

    @Override
    public List<PersonDeviceFilterLog> temperatureUnusualStatistics(String companyCode, BigDecimal temperature, Date startDate, Date endDate) {
        return personDeviceFilterLogDAO.temperatureUnusualStatistics(companyCode, temperature, startDate, endDate);
    }

    @Override
    public List<Map<String, Object>> unusualStatistics(String companyCode, Long personId, BigDecimal temperature, Date startDate, Date endDate) {
        return personDeviceFilterLogDAO.unusualStatistics(companyCode, personId, temperature, startDate, endDate);
    }

    @Override
    public long countUndetectedByCompanyCode(String companyCode, List<PersonCompany> personCompanyList, Date startTime, Date endTime) {
        return personDeviceFilterLogDAO.countUndetectedByCompanyCode(companyCode, personCompanyList, startTime, endTime);
    }

    @Override
    public Page<PersonInfo> findUndetectedPersonList(Map<String,Object> searchParams,int pageNumber,int pageSize,boolean count) {
        Page<PersonInfo> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            personDeviceFilterLogDAO.findUndetectedByCompanyCode(searchParams);
        });

        return page;
    }

    @Override
    public Integer getDayCheckedPersonNumByCompanyList(Date startTime, Date endTime, List<CompanyInfo> list,String popedom) {
        return personDeviceFilterLogDAO.getDayCheckedPersonNumByCompanyList(startTime,endTime,list,popedom);
    }

    @Override
    public Integer getDayAbnormalNum(Date startTime, Date endTime) {
        return personDeviceFilterLogDAO.getDayAbnormalNum(startTime,endTime,temperatureConfig.getMax());
    }

    @Override
    public Integer getDayAbnormalNumByCompanyList(Date startTime, Date endTime, List<CompanyInfo> list) {
        Integer total = personDeviceFilterLogDAO.getDayAbnormalNumByCompanyList(startTime,endTime,list,temperatureConfig.getMax());
       if (total == null){
           return 0;
       }else {
           return total;
       }

    }

    @Override
    public Integer getDayNormalNumByCompanyId(Date startTime,Date endTime, String companyId) {
        return personDeviceFilterLogDAO.getDayNormalNumByCompanyId(startTime,endTime,companyId,temperatureConfig.getMax());
    }

    @Override
    public Integer countDayByPersonIdAndDate(Long personId, Date startDate, Date endDate) {
        return personDeviceFilterLogDAO.countDayByPersonIdAndDate(personId,startDate,endDate);
    }

    @Override
    public Integer countDetectedByCompanyId(String companyId, Date startDate, Date endDate) {
        return personDeviceFilterLogDAO.countDetectedByCompanyId(companyId,startDate,endDate);
    }

    @Override
    public int deleteExpiredVisitorRecord(int limit) {
        return personDeviceFilterLogDAO.deleteExpiredVisitorRecord(limit);
    }

    @Override
    public List<PersonDeviceFilterLog> getDayCheckedPersonByCompanyList(Date beginTime, Date endTime, CompanyInfo companyInfo) {
        return personDeviceFilterLogDAO.getDayCheckedPersonByCompanyList(beginTime,endTime,companyInfo);
    }

    @Override
    public long countDetectedByCompanyIds(List<String> companyIds, Date startTime, Date endTime) {
        return personDeviceFilterLogDAO.countDetectedByCompanyIds(companyIds,  startTime, endTime);
    }

    @Override
    public long countDetectedByCompanyCode(String companyCode, Date startTime, Date endTime) {
        return personDeviceFilterLogDAO.countDetectedByCompanyCode(companyCode,  startTime, endTime);
    }

    @Override
    public Page<PersonInfo> findUndetectedPersonListByCompanyIds(Map<String, Object> searchParams, int pageIndex, int pageSize, boolean count) {
        Page<PersonInfo> page = PageHelper.startPage(pageIndex,pageSize,count).doSelectPage(()->{
            personDeviceFilterLogDAO.findUndetectedPersonListByCompanyIds(searchParams);
        });

        return page;
    }

    @Override
    public List<PersonDeviceFilterLog> findByTimeAndPersonId(String queryTime,Long personId){
        return personDeviceFilterLogDAO.findByTimeAndPersonId(queryTime,personId);
    }
}
