package com.jpsoft.shinestar.modules.mobile.controller;

import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.RedisConfig;
import com.jpsoft.shinestar.config.TemperatureConfig;
import com.jpsoft.shinestar.modules.base.dto.PersonDeviceFilterLogDTO;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.business.service.WorkAttendanceService;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.JwtUtil;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/mobile/PersonDeviceFilterLog")
public class PersonDeviceFilterLogController {
    @Value("${jwt.secret}")
    private String jwtSecret;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private PersonDeviceFilterLogService personDeviceFilterLogService;

    @Autowired
    private PersonDeviceLogService personDeviceLogService;

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private AlarmConfigService alarmConfigService;

    @Autowired
    private TemperatureConfig temperatureConfig;

    @Autowired
    private WorkAttendanceService workAttendanceService;

    @Autowired
    private ValueOperations<String, Object> valueOperations;
    
    @ApiOperation(value="体温记录（正常、异常）")
    @RequestMapping(value = "detail",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="token",value = "令牌",required = true,paramType = "form"),
            @ApiImplicitParam(name="id",value = "编号",paramType = "form")
    })
    public MessageResult<PersonDeviceFilterLogDTO> detail(Long id,String token){
        MessageResult<PersonDeviceFilterLogDTO> msgResult = new MessageResult<>();

        try {
            PersonDeviceFilterLog personDeviceFilterLog = personDeviceFilterLogService.get(id);
            PersonDeviceFilterLogDTO personDeviceFilterLogDTO = new PersonDeviceFilterLogDTO();

            if (personDeviceFilterLog != null) {
                PojoUtils.map(personDeviceFilterLog, personDeviceFilterLogDTO);

                DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(personDeviceFilterLog.getDeviceNo());
                PersonInfo personInfo = personInfoService.get(Long.valueOf(personDeviceFilterLog.getPersonId()));

                if(deviceInfo != null) {
                    personDeviceFilterLogDTO.setDeviceName(deviceInfo.getAliasName());
                }
                if(personInfo != null) {
                    personDeviceFilterLogDTO.setPersonName(personInfo.getName());
                }
                if(personDeviceFilterLog.getTemperature().compareTo(temperatureConfig.getMax())>0){
                    personDeviceFilterLogDTO.setFever(true);
                }else {
                    personDeviceFilterLogDTO.setFever(false);
                }

                msgResult.setResult(true);
                msgResult.setData(personDeviceFilterLogDTO);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库不存在该记录!");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="体温记录（个人列表）")
    @RequestMapping(value = "pageList",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="token",value = "令牌",required = true,paramType = "form"),
            @ApiImplicitParam(name="subject",value = "目标(不传)",paramType = "form"),
            @ApiImplicitParam(name="fever",value = "是否异常",required = false,paramType = "form",dataType = "Boolean")
//            @ApiImplicitParam(name = "recordDate",value = "查询日期(yyyy-MM-dd)", required = false, paramType = "form",dataType = "String")
    })
    public MessageResult<Map> pageList(//@RequestParam(value="recordDate",defaultValue="") String recordDate,
                                      @RequestParam(value="fever",defaultValue="") Boolean fever,
                                      @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
                                      @RequestParam(value="pageSize",defaultValue="20") int pageSize,
                                      @RequestAttribute String subject,
                                      String token){
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.record_time","desc"));

            Map<String,Object> searchParams = new HashMap<>();
            searchParams.put("personId",subject);
            if(fever != null){
                searchParams.put("fever", fever);
            }

            Page<PersonDeviceFilterLog> page = personDeviceFilterLogService.pageSearch(searchParams,pageIndex,pageSize,true, sortList);
            Page<PersonDeviceFilterLogDTO> pageDTO = PojoUtils.convertPage(page, PersonDeviceFilterLogDTO.class);
            for(PersonDeviceFilterLogDTO personDeviceFilterLogDTO : pageDTO.getResult()){
                DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(personDeviceFilterLogDTO.getDeviceNo());
                PersonInfo personInfo = personInfoService.get(Long.valueOf(personDeviceFilterLogDTO.getPersonId()));

                if(deviceInfo != null) {
                    personDeviceFilterLogDTO.setDeviceName(deviceInfo.getAliasName());
                }
                if(personInfo != null) {
                    personDeviceFilterLogDTO.setPersonName(personInfo.getName());
                }
                if(personDeviceFilterLogDTO.getTemperature().compareTo(temperatureConfig.getMax())>0){
                    personDeviceFilterLogDTO.setFever(true);
                }else {
                    personDeviceFilterLogDTO.setFever(false);
                }
            }

            msgResult.setResult(true);
            msgResult.setData(PojoUtils.pageWrapper(pageDTO));
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }
    @ApiOperation(value="未测量体温人员列表")
    @RequestMapping(value = "queryUnmeasureGroupList",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="companyId",value = "公司编号",required = false,paramType = "form"),
            @ApiImplicitParam(name = "queryDate",value = "查询日期(yyyy-MM-dd)",required = true, paramType = "form"),
            @ApiImplicitParam(name="alarmConfigId",value = "考勤设置编号",required = false,paramType = "form"),
            @ApiImplicitParam(name="token",value = "令牌",required = false,paramType = "form")
    })
    public MessageResult<Map> queryUnmeasureGroupList(
            String companyId,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date queryDate,
            String alarmConfigId,
            String token){
        MessageResult<Map> msgResult = new MessageResult<>();
        Map<String,Object> dataMap = new HashMap<>();

        try{
            if (StringUtils.isEmpty(companyId)){
                token = URLDecoder.decode(token,"UTF-8");

                String subject = JwtUtil.decodeToken(jwtSecret,token);

                PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));

                Map<String,Object> companyMap = (Map<String,Object>)valueOperations.get(RedisConfig.PERSON_SELECT_COMPANY + personInfo.getId());
                companyId = companyMap.get("id").toString();
            }

            CompanyInfo companyInfo = companyInfoService.get(companyId);

            //查询子单位是否有考勤设置，如果有要排除子单位
            List<String> excludeCompanyList = alarmConfigService.findSubCompanyList(companyInfo.getCode() + "%" , companyInfo.getId());

            dataMap.put("companyName",companyInfo.getName());

            String[] arr = companyInfo.getCode().split(",");

            List<AlarmConfig> configList = null;

            for (int i=arr.length-1;i>=0;i--) {
                configList = alarmConfigService.findByCompanyId(arr[i]);

                if (configList!=null && configList.size()>0){
                    break;
                }
            }

            DateTime queryTime = new DateTime(queryDate);
            String dateStr = queryTime.toString("yyyy-MM-dd");
            int weekday = queryTime.getDayOfWeek();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            List<Map> mapList = new ArrayList<>();

            if(configList!=null && configList.size()>0) {
                for (AlarmConfig alarmConfig : configList) {
                    if (StringUtils.isEmpty(alarmConfigId) || alarmConfig.getId().equals(alarmConfigId)){
                        if (alarmConfig.getWeekdays().indexOf(String.valueOf(weekday)) != -1) {
                            Map<String, Object> map = new HashMap<>();
                            DateTime startTime = new DateTime(sdf.parse(dateStr + " " + alarmConfig.getStartTime()));
                            DateTime endTime = new DateTime(sdf.parse(dateStr + " " + alarmConfig.getEndTime()));

                            //todo 查询考勤表由于是截止时间到后才能算缺卡，不够实时；还是改为查询测温记录
                            //List<PersonInfo> unmeasuredList = workAttendanceService.queryUnAttendanceList(companyInfo.getCode() + "%", startTime.toDate(), endTime.toDate());
                            List<Long> unmeasuredList = personDeviceLogService.queryUnAttendanceList(companyInfo.getCode() + "%", startTime.toDate(), endTime.toDate(),excludeCompanyList);

                            List<Map> personMapList = unmeasuredList.stream().map((personId)->{
                                PersonInfo person = personInfoService.get(personId);

                                Map<String,Object> personMap = new HashMap<>();
                                personMap.put("id",person.getId());
                                personMap.put("name",person.getName());

                                return personMap;

                            }).collect(Collectors.toList());

                            map.put("startTime", alarmConfig.getStartTime());
                            map.put("endTime", alarmConfig.getEndTime());
                            map.put("list", personMapList);

                            mapList.add(map);
                        }
                    }
                }
            }
            else{
                //没有设置考勤时间段，则查全天
                DateTime startTime = new DateTime(sdf.parse(dateStr + " 00:00"));
                DateTime endTime = new DateTime(sdf.parse(dateStr + " 23:59"));

                List<Long> unmeasuredList = personDeviceLogService.queryUnAttendanceList(companyInfo.getCode() + "%", startTime.toDate(), endTime.toDate(),excludeCompanyList);

                List<Map> personMapList = unmeasuredList.stream().map((personId)->{
                    PersonInfo person = personInfoService.get(personId);
                    Map<String,Object> personMap = new HashMap<>();
                    personMap.put("id",person.getId());
                    personMap.put("name",person.getName());

                    return personMap;

                }).collect(Collectors.toList());

                Map<String, Object> map = new HashMap<>();

                map.put("startTime", startTime.toString("HH:mm"));
                map.put("endTime", endTime.toString("HH:mm"));
                map.put("list", personMapList);

                mapList.add(map);
            }

            dataMap.put("list",mapList);

            msgResult.setData(dataMap);
            msgResult.setResult(true);
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }
}
