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

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.DeflaterOutputStream;
import javax.annotation.Resource;

import cn.hutool.core.date.DateUtil;
import com.jpsoft.shinestar.config.TemperatureConfig;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.jpsoft.shinestar.modules.base.dao.CompanySuperviseDAO;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;

@Transactional
@Component(value = "companySuperviseService")
@Slf4j
public class CompanySuperviseServiceImpl implements CompanySuperviseService {
    @Resource(name = "companySuperviseDAO")
    private CompanySuperviseDAO companySuperviseDAO;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private ValueOperations<String, Object> valueOperations;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private PersonDeviceFilterLogService personDeviceFilterLogService;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Autowired
    private TemperatureConfig temperatureConfig;

    @Override
    public CompanySupervise get(String id) {
        // TODO Auto-generated method stub
        return companySuperviseDAO.get(id);
    }

    @Override
    public int insert(CompanySupervise model) {
        // TODO Auto-generated method stub
        //model.setId(UUID.randomUUID().toString());

        return companySuperviseDAO.insert(model);
    }

    @Override
    public int update(CompanySupervise model) {
        // TODO Auto-generated method stub
        return companySuperviseDAO.update(model);
    }

    @Override
    public void updateAtProvinceNum(PersonHealthLedger personHealthLedger){
        String recordTime = DateUtil.format(new Date(), "yyyy-MM-dd");

        boolean isJingzhou = personHealthLedger.getIsJingzhou();
        boolean isProvince = personHealthLedger.getIsProvince();
        String companyId = personHealthLedger.getPersonInfo().getCompanyId();
        CompanyInfo companyInfo1 = companyInfoService.get(companyId);

        CompanySupervise companySupervise0 = findByCompanyIdAndRecordDate(companyId, recordTime);

        if(companySupervise0!=null){
            if(isJingzhou){
                if(isProvince){
                    int atProvinceNum = companySupervise0.getAtProvinceNum();
                    companySupervise0.setAtProvinceNum(atProvinceNum+1);
                }
                else{
                    int atOutProvinceNum = companySupervise0.getAtOutProvinceNum();
                    companySupervise0.setAtOutProvinceNum(atOutProvinceNum+1);
                }
                update(companySupervise0);
            }
        }
        else{
            List<CompanyInfo> companyInfoList1 = companyInfoService.findAllCompanyByCode(companyInfo1.getCode()+"%");
            Integer personNum = personPopedomService.findNumByCompanyList(companyInfoList1);
            if (personNum >0){
                CompanySupervise companySupervise = new CompanySupervise();
                companySupervise.setId(UUID.randomUUID().toString());
                companySupervise.setCompanyId(companyInfo1.getId());
                companySupervise.setTotalNum(personNum);
                companySupervise.setTotalCheckNum(0);
                companySupervise.setTotalAbnormalNum(0);
                companySupervise.setAtOutProvinceNum(0);
                companySupervise.setAtProvinceNum(0);
                companySupervise.setLeaveNum(0);
                companySupervise.setTestRate("0");
                companySupervise.setRecordTime(DateUtil.format(new Date(), "yyyy-MM-dd"));
                companySupervise.setDelFlag(false);
                companySupervise.setCreateTime(new Date());
                insert(companySupervise);

                companySupervise0 = companySupervise;

                if(isJingzhou){
                    if(isProvince){
                        int atProvinceNum = companySupervise0.getAtProvinceNum();
                        companySupervise0.setAtProvinceNum(atProvinceNum+1);
                    }
                    else{
                        int atOutProvinceNum = companySupervise0.getAtOutProvinceNum();
                        companySupervise0.setAtOutProvinceNum(atOutProvinceNum+1);
                    }
                    update(companySupervise0);
                }
            }
        }
    }

    @Override
    public int delete(String id) {
        // TODO Auto-generated method stub
        return companySuperviseDAO.delete(id);
    }

    @Override
    public boolean exist(String id) {
        // TODO Auto-generated method stub
        int count = companySuperviseDAO.exist(id);

        return count > 0 ? true : false;
    }

    @Override
    public List<CompanySupervise> list() {
        // TODO Auto-generated method stub
        return companySuperviseDAO.list();
    }

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

        return page;
    }

    @Override
    public void insertCompanySupervise(String deviceNo, PersonInfo personInfo, Date recordDate, BigDecimal temperature, String address,PersonHealthLedger personHealthLedger) {
        String recordTime = DateUtil.format(recordDate, "yyyy-MM-dd");
        String companyId = "";
        PersonInfo personInfo1 = personInfoService.get(personInfo.getId());

        if(personInfo1==null){
            log.error(personInfo.getId() + "不存在!");
            return;
        }

        PersonPopedom personPopedom = personPopedomService.get(personInfo1.getPopedom());
        //只有单位属性为公司才做记录
        if (personPopedom == null){
            log.error("对应角色："+ personInfo1.getPopedom()+"不存在");
        }
        CompanyInfo companyInfo = companyInfoService.get(personPopedom.getCompanyId());

        if(companyInfo != null && StringUtils.isNotEmpty(companyInfo.getCode())){
            String[] arr = companyInfo.getCode().split(",");

            //查询上级单位中单位类型为企业的单位编号
            for (int i=arr.length-1;i>=0;i--){
                CompanyInfo parent = companyInfoService.get(arr[i]);

                if (parent!=null && "1".equals(parent.getUnitType())){
                    companyId = parent.getId();
                    break;
                }
            }
        }

        if (StringUtils.isNotBlank(companyId)) {
            CompanyInfo companyInfo2 = companyInfoService.get(companyId);

            //查询监管表中此公司当前时间是否有记录
            CompanySupervise companySupervise = findByCompanyIdAndRecordDate(companyId, recordTime);
            if (companySupervise == null) {
                CompanySupervise companySupervise1 = new CompanySupervise();
                companySupervise1.setId(UUID.randomUUID().toString());
                companySupervise1.setCompanyId(companyId);
                List<CompanyInfo> companyInfoList = companyInfoService.findAllCompanyByCode(companyInfo2.getCode()+"%");
                Integer personNum = personPopedomService.findNumByCompanyList(companyInfoList);
                companySupervise1.setTotalNum(personNum);
                companySupervise1.setTotalCheckNum(0);
                companySupervise1.setTotalAbnormalNum(0);
                companySupervise1.setLeaveNum(0);
                companySupervise1.setTestRate("0");
                companySupervise1.setRecordTime(recordTime);
                companySupervise1.setDelFlag(false);
                companySupervise1.setCreateTime(new Date());
                insert(companySupervise1);
                companySupervise = companySupervise1;
            }else {
                List<CompanyInfo> companyInfoList = companyInfoService.findAllCompanyByCode(companyInfo2.getCode()+"%");
                Integer personNum = personPopedomService.findNumByCompanyList(companyInfoList);
                companySupervise.setTotalNum(personNum);
                update(companySupervise);
            }

            List<Long> personIdList = new ArrayList<>();
            Map<String,Object> redisMap = new HashMap<>();
            redisMap.put(recordTime,personIdList);

            List<Long> tmpList = (List) valueOperations.get(recordTime);

            if (tmpList == null){
                List<Long> idList = new ArrayList<>();
                idList.add(personInfo.getId());
                valueOperations.set(recordTime,idList,24, TimeUnit.HOURS);

                companySupervise.setTotalCheckNum(companySupervise.getTotalCheckNum() + 1);
                if (temperature.compareTo(temperatureConfig.getMax()) > 0) {
                    companySupervise.setTotalAbnormalNum(companySupervise.getTotalAbnormalNum() + 1);
                }
                //判断此人是否在外地打卡
                if (StringUtils.isNotBlank(address) && !address.contains("荆州")){
                    companySupervise.setLeaveNum(companySupervise.getLeaveNum() +1);
                }

            }
            else {
                if (!tmpList.contains(personInfo.getId())){
                    tmpList.add(personInfo.getId());
                    valueOperations.set(recordTime,tmpList,24, TimeUnit.HOURS);
                    companySupervise.setTotalCheckNum(companySupervise.getTotalCheckNum() + 1);
                    if (temperature.compareTo(temperatureConfig.getMax()) > 0) {
                        companySupervise.setTotalAbnormalNum(companySupervise.getTotalAbnormalNum() + 1);
                    }
                    //判断此人是否在外地打卡
                    if (StringUtils.isNotBlank(address) && !address.contains("荆州")){
                        companySupervise.setLeaveNum(companySupervise.getLeaveNum() +1);
                    }

                }
            }


            if (personHealthLedger != null){
                boolean isJingzhou = personHealthLedger.getIsJingzhou();
                boolean isProvince = personHealthLedger.getIsProvince();

                    if (isJingzhou) {
                        if (isProvince) {
                            int atProvinceNum = companySupervise.getAtProvinceNum();
                            companySupervise.setAtProvinceNum(atProvinceNum + 1);
                        } else {
                            int atOutProvinceNum = companySupervise.getAtOutProvinceNum();
                            companySupervise.setAtOutProvinceNum(atOutProvinceNum + 1);
                        }
                        update(companySupervise);
                    }

            }






            if(companySupervise.getTotalNum()!=null && companySupervise.getTotalNum()>0){
                BigDecimal testRate = new BigDecimal(new Double(companySupervise.getTotalCheckNum())/ new Double(companySupervise.getTotalNum())).setScale(4,0);
                companySupervise.setTestRate(testRate.toString());
            }

			update(companySupervise);
        }

    }

    @Override
    public CompanySupervise findByCompanyIdAndRecordDate(String companyId, String recordTime) {
        return companySuperviseDAO.findByCompanyIdAndRecordDate(companyId, recordTime);
    }

    @Override
    public Integer findTotalNumByCompanyIdAndDate(List<PersonSuperviseRelation> list,String date) {
        return companySuperviseDAO.findTotalNumByCompanyIdAndDate(list,date);
    }

    @Override
    public Integer findTotalCheckNumByCompanyIdAndDate(List<PersonSuperviseRelation> personSuperviseRelationList, String date) {
        return companySuperviseDAO.findTotalCheckNumByCompanyIdAndDate(personSuperviseRelationList,date);
    }

    @Override
    public Integer findTotalAbnormalNumByCompanyIdAndDate(List<PersonSuperviseRelation> personSuperviseRelationList, String date) {
        return companySuperviseDAO.findTotalAbnormalNumByCompanyIdAndDate(personSuperviseRelationList,date);
    }

    @Override
    public Integer findLeaveNumByCompanyIdAndDate(List<PersonSuperviseRelation> personSuperviseRelationList, String date) {
        return companySuperviseDAO.findLeaveNumByCompanyIdAndDate(personSuperviseRelationList,date);
    }
}