/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.permission.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.permission.config.WxConfig;
import com.yifu.cloud.plus.v1.permission.mapper.EkpQiweiWorkovertimeMapper;
import com.yifu.cloud.plus.v1.permission.mapper.EkpQiweiZhaopinMapper;
import com.yifu.cloud.plus.v1.permission.service.EkpQiweiWorkovertimeService;
import com.yifu.cloud.plus.v1.permission.service.EkpQiweiZhaopinService;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.permission.entity.EkpQiwiWorkovertime;
import com.yifu.cloud.plus.v1.yifu.permission.entity.EkpQiwiZhaoPin;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * E人事加班申请
 *
 * @author chenyuxi
 * @since 1.9.6
 */
@Log4j2
@Service
@AllArgsConstructor
public class EkpQiweiWorkovertimeServiceImpl extends ServiceImpl<EkpQiweiWorkovertimeMapper, EkpQiwiWorkovertime> implements EkpQiweiWorkovertimeService {

	private final WxConfig wxConfig;

	private RestTemplate restTemplate = new RestTemplate();

	/**
	 * 已被拉取的90天内的数据Map（定时任务是拉前一天的，手动执行是当面的。所以对90内的查重足够了。查全部数据对IO是浪费的）
	 * 用来： 拉取企E人事加班数据时，不覆盖数据
	 * @return java.util.Map<java.lang.String, java.lang.String>
	 **/
	@Override
	public Map<String, String> getWorkovertimeMapByTimeRange(String queryStartTime,String queryEndTime) {
		List<EkpQiwiWorkovertime> cpHistoryList = baseMapper.getWorkovertimeMapByTimeRange(queryStartTime,queryEndTime);
		Map<String, String> cpMap = new HashMap<>();
		for (EkpQiwiWorkovertime cpHis : cpHistoryList) {
			cpMap.put(cpHis.getFdSpNo(), "0");
		}
		return cpMap;
	}

	/**
	 * 获取HCM审批通过的加班数据并存储到EKP
	 *
	 * @param startTime 开始时间
	 * @param endTime   结束时间
	 * @return R<List < EkpQiwiChuchai>>
	 **/
	@Override
	public List<EkpQiwiWorkovertime> saveWorkovertimeList(String startTime, String endTime) {
		// 拉取E人事昨天的全量数据
		List<EkpQiwiWorkovertime> hcmAllList = new ArrayList<>();
		// 可存储的数据
		List<EkpQiwiWorkovertime> saveCpList = new ArrayList<>();

		// 已被拉取的90天内的数据Map（定时任务是拉前一天的，手动执行是当面的。所以对90内的查重足够了。查全部数据对IO是浪费的）
		String queryStartDay = DateUtil.addDay(-90);
		String queryStartTimes = queryStartDay + " 00:00:00";
		Map<String, String> cpHistoryMap = this.getWorkovertimeMapByTimeRange(queryStartTimes,endTime);

		// 拉取E人事昨天的全量数据
		this.getWorkOvertimeListByHcm(startTime, endTime, hcmAllList);
		log.debug("获取HCM审批通过的加班数据——hcmAllList.size()=" + hcmAllList.size());
		if (!hcmAllList.isEmpty()) {
			for (EkpQiwiWorkovertime cp : hcmAllList) {
				if (cpHistoryMap.get(cp.getFdSpNo()) == null) {
					saveCpList.add(cp);
				}
			}
		}
		log.debug("获取HCM审批通过的加班数据——saveCpList.size()=" + saveCpList.size());

		// 填充基础数据并保存：
		if (Common.isNotNull(saveCpList)) {
			this.saveBatch(saveCpList);
		}
		cpHistoryMap.clear();

		return saveCpList;
	}

	/**
	 * 从HCM-获取审批通过的加班数据
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 **/
	private void getWorkOvertimeListByHcm(String startTime, String endTime, List<EkpQiwiWorkovertime> cpAllList) {

		String sign = wxConfig.getHcmSign();
		if (Common.isEmpty(sign)) {
			log.error("从HCM-获取审批通过的加班数据>>获取HCM的sign失败！");
		}

		String appWorkOvertimeUrl = wxConfig.getAppWorkOvertimeUrl();
		if (Common.isEmpty(appWorkOvertimeUrl)) {
			log.error("从HCM-获取审批通过的加班数据>>获取HCM的appWorkOvertimeUrl失败！");
		}
		log.info("从HCM-获取审批通过的加班数据》》sign=" + sign);
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());
		headers.add("sign", sign);
		HttpEntity<String> formEntity = new HttpEntity<>(headers);

		log.info("从HCM-获取审批通过的加班数据》》appWorkOvertimeUrl=" + appWorkOvertimeUrl);

		// 从HCM-获取审批通过的加班数据
		String dataResultList = restTemplate.postForEntity(appWorkOvertimeUrl, formEntity, String.class, startTime, endTime).getBody();
		log.info("从HCM-获取审批通过的加班数据》》dataResultList=" + dataResultList);
		if (Common.isEmpty(dataResultList)) {
			throw new AuthenticationServiceException("从HCM-获取审批通过的加班数据失败");
		}
		JSONObject jsonObject = JSON.parseObject(dataResultList);
		String code = jsonObject.getString("code");
		if (!"200".equals(code)) {
			log.error("从HCM-获取审批通过的加班数据>>返回code非200");
		}
		// 时间段内的总审批单个数
		String data = jsonObject.getString("data");
		if (Common.isNotNull(data)) {
			List<JSONObject> dataList = JSON.parseArray(data, JSONObject.class);
			log.debug("从HCM-获取审批通过的加班数据》》dataList的数量=" + dataList.size());
			JSONObject formData;
			DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

			EkpQiwiWorkovertime workOvertimeInfo;
			for (JSONObject datas : dataList) {
				workOvertimeInfo = new EkpQiwiWorkovertime();
				// 存原始报文
				workOvertimeInfo.setOrgData(datas.toJSONString());

				if (Common.isNotNull(datas.getString("applyTimeFormat"))) {
					workOvertimeInfo.setFdApplyDate(LocalDateTime.parse(datas.getString("applyTimeFormat"), df));
				}
				if (Common.isNotNull(datas.getString("startTimeFormat"))) {
					workOvertimeInfo.setFdWorkBegin(LocalDateTime.parse(datas.getString("startTimeFormat"), df));
				}
				if (Common.isNotNull(datas.getString("endTimeFormat"))) {
					workOvertimeInfo.setFdWorkEnd(LocalDateTime.parse(datas.getString("endTimeFormat"), df));
				}
				workOvertimeInfo.setCreateTime(LocalDateTime.now());
				workOvertimeInfo.setFdApplyUserName(datas.getString("applyName"));
				workOvertimeInfo.setFdApplyUserDept(datas.getString("applyDeptName"));
				workOvertimeInfo.setFdSpNo(datas.getString("flowId"));
				workOvertimeInfo.setFdReason(datas.getString("initiationReason"));
				workOvertimeInfo.setFdTimeUse(datas.getString("dataType"));
				workOvertimeInfo.setFdWorkDuration(datas.getString("weekdayHour"));
				workOvertimeInfo.setFdHolidayDuration(datas.getString("holidayHour"));
				workOvertimeInfo.setFdRestDuration(datas.getString("restDayHour"));
				workOvertimeInfo.setFdSumDuration(datas.getString("duration"));

				// 关联状态默认为"未关联"
				workOvertimeInfo.setFdOvertimeFoodStatus("未关联");
				workOvertimeInfo.setFdOvertimePayStatus("未关联");

				if (Common.isNotNull(datas.getString("formData"))) {
					formData = JSON.parseObject(datas.getString("formData"));

					workOvertimeInfo.setFdPositionLevel(formData.getString("岗位级别"));
					workOvertimeInfo.setFdProjectName(formData.getString("项目名称"));
					workOvertimeInfo.setFdProjectCode(formData.getString("项目编码"));
					workOvertimeInfo.setFdIsAway(formData.getString("是否是出差加班"));
				}
				cpAllList.add(workOvertimeInfo);
			}
		}
	}

}
