package com.cku.oa.timedtask.service;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.cku.oa.sys.service.WorkdayService;
import com.cku.oa.timedtask.entity.EmployeeLeaveInfo;
import com.cku.oa.timedtask.entity.EmployeeLeaveMarkdown;
import com.cku.oa.timedtask.entity.EmployeeLeaveMsgInfo;
import com.cku.util.DateUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taobao.utils.DDUtils;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.utils.JedisUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Transactional(readOnly = true)
public class EmployeeLeaveNoticeTask extends JobActingService {

	private final static String NOTICE_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4e54ed3f-57d9-4432-a4ce-24d279ee51dd";

	@Value("${dingding.appKey}")
	private String ddAppKey;

	@Value("${dingding.appSecret}")
	private String ddAppSecret;

	private String REDIS_EMPLOYEE_LEAVE_INFO_KEY = "redis_employee_leave_info_key";

	private static final ObjectMapper objectMapper = new ObjectMapper();

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private WorkdayService workdayService;

	@Transactional(readOnly = false)
	int doJob() {
		try {
			log.error("================请假通知任务开始===================");
			this.notice();
		} catch (Exception e) {
			log.error("================请假通知异常===================", e);
		} finally {
			log.error("================请假通知任务结束===================");
		}
		return BigInteger.ONE.intValue();
	}

	@Override
	@Transactional(readOnly = false)
	public int executeOnce() {
		try {
			log.error("============单次====请假通知任务开始===================");
			SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
			this.notice();
		} catch (Exception e) {
			log.error("============单次====请假通知异常===================", e);
		} finally {
			log.error("===========单次=====请假通知任务结束===================");
		}
		return BigInteger.ONE.intValue();
	}

	private void notice() throws Exception {
		// 增加开发环境判定，开发环境不执行
		if (Global.isDevMode()) {
			log.error("================开发环境不通知===================");
			return;
		}
		if (workdayService.validOffday(DateUtils.getNow())) {
			log.error("================请假通知任务节假日不通知===================");
			return;
		}
		LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
		LocalDateTime endTime = startTime.plusDays(1);
		List<Map<String, String>> result = DDUtils.getTechLeaveStatus(ddAppKey, ddAppSecret, startTime, endTime);
		EmployeeLeaveMarkdown markdown = EmployeeLeaveMarkdown.builder().build();
		if (CollectionUtils.isNotEmpty(result)) {
			JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class,
					EmployeeLeaveInfo.class);
			List<EmployeeLeaveInfo> leaveList = objectMapper.readValue(objectMapper.writeValueAsString(result),
					javaType);
			List<String> msgList = new ArrayList<>();
			if (CollectionUtils.isNotEmpty(leaveList)) {
				List<String> cacheMsg = JedisUtils.getList(REDIS_EMPLOYEE_LEAVE_INFO_KEY, false, 0);
				leaveList.forEach(l -> {
					String msg = l.assembleMsg();
					if (CollectionUtils.isEmpty(cacheMsg) || !cacheMsg.contains(msg)) {
						cacheMsg.add(msg);
						msgList.add(msg);
					}
				});
				JedisUtils.setList(REDIS_EMPLOYEE_LEAVE_INFO_KEY, cacheMsg,
						(int) DateUtils.getSeconds(DateUtils.getNow(), DateUtils.getTodayMaxDate()));
			}
			if (CollectionUtils.isNotEmpty(msgList)) {
				msgList.add(0, "近期请假情况，请悉知\n\n");
				markdown.setContent(msgList.stream().collect(Collectors.joining()));
				// 请求头
				EmployeeLeaveMsgInfo msgInfo = new EmployeeLeaveMsgInfo();
				msgInfo.setText(markdown);
				restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
				headers.add("Accept", MediaType.APPLICATION_JSON.toString());
				HttpEntity<EmployeeLeaveMsgInfo> entity = new HttpEntity<>(msgInfo, headers);
				String noticeResult = restTemplate.postForObject(NOTICE_URL, entity, String.class);
				log.error("================请假通知结果：{}===================", noticeResult);
			} else {
				log.error("================排除已通知人员，今日暂无员工请假===================");
			}
		} else {
			log.error("================今日暂无员工请假===================");
		}
	}

}