package com.yeejoin.precontrol.common.service.impl;

import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeejoin.precontrol.common.dto.CommonPageableDto;
import com.yeejoin.precontrol.common.dto.StudioPageableDto;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.entity.PersonClock;
import com.yeejoin.precontrol.common.entity.Project;
import com.yeejoin.precontrol.common.entity.ProjectDevice;
import com.yeejoin.precontrol.common.entity.publics.CommonPageable;
import com.yeejoin.precontrol.common.enums.ClockInOutEum;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.mapper.PersonAscriptionMapper;
import com.yeejoin.precontrol.common.mapper.PersonClockMapper;
import com.yeejoin.precontrol.common.mapper.PersonMapper;
import com.yeejoin.precontrol.common.mapper.ProjectDeviceMapper;
import com.yeejoin.precontrol.common.mapper.ProjectMapper;
import com.yeejoin.precontrol.common.service.IPersonClockService;
import com.yeejoin.precontrol.common.utils.CommonResponseUtil;
import com.yeejoin.precontrol.common.utils.RedisUtil;
import com.yeejoin.precontrol.common.vo.HazardousWorkPageVo;
import com.yeejoin.precontrol.common.vo.PersonClockVo;
import com.yeejoin.precontrol.common.vo.ProjectVo;
import com.yeejoin.precontrol.common.vo.RewardOrgCodeVo;

import sun.misc.BASE64Encoder;

/**
 * 人员履历信息(打卡) 服务实现类
 *
 * @author duanwei
 * @date 2020-06-30
 */
@Service
public class PersonClockServiceImpl extends ServiceImpl<PersonClockMapper, PersonClock> implements IPersonClockService {
	@Autowired
	PersonClockMapper clockMapper;
	@Autowired
	PersonMapper personMapper;
	@Autowired
	ProjectDeviceMapper projectDeviceMapper;
	@Autowired
	ProjectMapper projectMapper;
	@Autowired
	PersonAscriptionMapper personAscriptionMapper;
	@Autowired
	RedisUtil redisUtil;

	@Override
	public Page pageInfo(CommonPageable pageable, HashMap<String, Object> param) {
		int count = clockMapper.pageInfoCount(param);
		Page<PersonClockVo> page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
		List<PersonClockVo> pageInfo = clockMapper.pageInfo(param, page);
		pageInfo.forEach(c -> {
			Integer inOrOut = c.getInOrOut();
			if (inOrOut != null) {
				c.setInOrOutLabel(ClockInOutEum.getLabelByValue(inOrOut));
			}
		});
		page.setRecords(pageInfo);
		return page;
	}

	@Override
	public ResponseModel getSignature(String deviceNo) {
		if (StringUtils.isEmpty(deviceNo)) {
			return CommonResponseUtil.failure("设备标识为空", 400);
		}
		ProjectDevice projectDevice = projectDeviceMapper
				.selectOne(new QueryWrapper<ProjectDevice>().eq("number", deviceNo));
		if (projectDevice == null) {
			return CommonResponseUtil.failure("查询不到设备信息", 400);
		}
		String signatureKey = "signature_device";
		String signatureValue = "signature_" + deviceNo + "_" + System.currentTimeMillis();
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			BASE64Encoder base64en = new BASE64Encoder();
			signatureValue = base64en.encode(md5.digest(signatureValue.getBytes("utf-8")));
		} catch (Exception e) {
			e.printStackTrace();
		}
		boolean isOk = redisUtil.set(signatureKey, signatureValue, 300);
		return isOk ? CommonResponseUtil.success(redisUtil.get(signatureKey)) : CommonResponseUtil.failure("获取数字签名失败");
	}

	@Override
	public ResponseModel personClock(PersonClockVo personClockVo) {
		String json = JSONObject.toJSONString(personClockVo);
		if (StringUtils.isEmpty(personClockVo.getSignature())) {
			log.error("数字签名为空:" + json);
			return CommonResponseUtil.failure("数字签名为空", 400);
		}
		String redisValue = (String) redisUtil.get("signature_device");
		if (StringUtils.isEmpty(redisValue)) {
			log.error("数字签名已经失效:" + redisValue);
			return CommonResponseUtil.failure("数字签名已经失效", 400);
		}
		if (!personClockVo.getSignature().equals(redisValue)) {
			log.error("数字签名不正确:" + redisValue);
			return CommonResponseUtil.failure("数字签名不正确", 400);
		}
		if (StringUtils.isEmpty(personClockVo.getDeviceNo())) {
			log.error("设备标识为空:" + json);
			return CommonResponseUtil.failure("设备标识为空", 400);
		}
		if (StringUtils.isEmpty(personClockVo.getIdNumber())) {
			log.error("人员身份证号为空:" + json);
			return CommonResponseUtil.failure("人员身份证号为空", 400);
		}
		Person person = personMapper.selectOne(new QueryWrapper<Person>().eq("ID_number", personClockVo.getIdNumber()));
		if (person == null) {
			log.error("查询不到人员信息:" + json);
			return CommonResponseUtil.failure("查询不到人员信息", 400);
		}
		ProjectDevice projectDevice = projectDeviceMapper
				.selectOne(new QueryWrapper<ProjectDevice>().eq("number", personClockVo.getDeviceNo()));
		if (projectDevice == null) {
			log.error("查询不到设备信息:" + json);
			return CommonResponseUtil.failure("查询不到设备信息", 400);
		}
		Project project = projectMapper.selectById(projectDevice.getProjectId());
		if (project == null) {
			log.error("查询不到项目信息:" + json);
			return CommonResponseUtil.failure("查询不到项目信息", 400);
		}
		PersonAscription personAscription = personAscriptionMapper
				.selectOne(new QueryWrapper<PersonAscription>().eq("person_id", person.getId()));
		if (personAscription == null) {
			log.error("查询不到归属信息:" + json);
			return CommonResponseUtil.failure("查询不到归属信息", 400);
		}
		PersonClock personClock = new PersonClock();
		BeanUtils.copyProperties(personClockVo, personClock);
		personClock.setPersonId(person.getId());
		personClock.setOrgCode(person.getOrgCode());
		personClock.setClockProject(project.getName());
		personClock.setClockProjectId(project.getId().toString());
		personClock.setClockTime(new Date());
		personClock.setCreateDate(new Date());
		personClock.setClockCompanyId(personAscription.getCompanyId());
		personClock.setDeviceNo(personClockVo.getDeviceNo());
		if (personClock.getClockTime() != null) {
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			String clockDateStr = format.format(personClock.getClockTime());
			try {
				Date clockDate = format.parse(clockDateStr);
				personClock.setClockDate(clockDate);
			} catch (ParseException e) {
				throw new BaseException("日期转换错误");
			}
		}
		Boolean isOk = clockMapper.insert(personClock) > 0;
		return isOk ? CommonResponseUtil.success() : CommonResponseUtil.failure("保存信息失败");
	}

	public List<PersonClock> getEveryDayMaxList(Long personId, Date startTime, Date endTime) {
		Map<String, Object> map = new HashMap<>();
		map.put("personId", personId);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		return clockMapper.listEveryDayMaxOut(map);
	}

	public List<PersonClock> getEveryDayMinList(Long personId, Date startTime, Date endTime) {
		Map<String, Object> map = new HashMap<>();
		map.put("personId", personId);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		return clockMapper.listEveryDayMinIn(map);
	}

	@Override
	public IPage<PersonClockVo> listByDevice(StudioPageableDto pageable, PersonClockVo personClockVo) {
		if (pageable.getCurrent() == null || pageable.getSize() == null) {
			pageable.setCurrent(0);
			pageable.setSize(Integer.MAX_VALUE);
		}
		// name,ascend / name,descend
		if (!StringUtils.isEmpty(personClockVo.getSort())) {
			String[] s = personClockVo.getSort().split(",");
			personClockVo.setSortName(s[0]);
			personClockVo.setSortOrder(s[1] != null ? s[1].replace("end", "") : null);
		}
		Page<PersonClockVo> objectPage = new Page<PersonClockVo>(pageable.getCurrent(), pageable.getSize());
		IPage<PersonClockVo> pageInfo = clockMapper.listByDevice(objectPage, personClockVo);
		return pageInfo;
	}

	@Override
	public IPage<PersonClockVo> listNotice(CommonPageableDto pageable, PersonClockVo personClockVo, Date startMonth,
			Date endMonth) {
		if (pageable.getIsAll() == 1) {
			pageable.setPageNumber(0);
			pageable.setPageSize(Integer.MAX_VALUE);
		}
		if(startMonth !=null &&endMonth!=null) 
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startMonth);
			int startMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date startDate = StatisticalHRServiceImpl.addTime(
					StatisticalHRServiceImpl.getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue), "00:00:00");
			calendar.setTime(endMonth);
			int endMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date endDate = StatisticalHRServiceImpl.addTime(StatisticalHRServiceImpl.getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue),
					"23:59:59");
			personClockVo.setClockTimeStart(startDate);
			personClockVo.setClockTimeEnd(endDate);	
		}
		
		Page<PersonClockVo> page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
		IPage<PersonClockVo> pageInfo = clockMapper.listNotice(page, personClockVo);
		return pageInfo;
	}

	@Override
	public IPage<PersonClockVo> enterList(Page<PersonClockVo> page, PersonClockVo personClockVo) {
		return this.baseMapper.enterList(page,personClockVo);
	}
}
