/*
 *    Copyright (c) 2018-2025, hnqz 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 pig4cloud.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: hnqz
 */

package com.qunzhixinxi.hnqz.daemon.quartz.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qunzhixinxi.hnqz.daemon.quartz.constants.HnqzQuartzEnum;
import com.qunzhixinxi.hnqz.daemon.quartz.entity.SingleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth;
import com.qunzhixinxi.hnqz.daemon.quartz.entity.SingleMemberSettleAmountOverrunInSeveralMonths;
import com.qunzhixinxi.hnqz.daemon.quartz.entity.SingleMemberSettleSameAmountInSeveralMonths;
import com.qunzhixinxi.hnqz.daemon.quartz.entity.SingleMemberWithoutSuchTaskTypesInSeveralMonths;
import com.qunzhixinxi.hnqz.daemon.quartz.entity.WmTask;
import com.qunzhixinxi.hnqz.daemon.quartz.mapper.SingleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonthMapper;
import com.qunzhixinxi.hnqz.daemon.quartz.mapper.SingleMemberSettleAmountOverrunInSeveralMonthsMapper;
import com.qunzhixinxi.hnqz.daemon.quartz.mapper.SingleMemberSettleSameAmountInSeveralMonthsMapper;
import com.qunzhixinxi.hnqz.daemon.quartz.mapper.SingleMemberWithoutSuchTaskTypesInSeveralMonthsMapper;
import com.qunzhixinxi.hnqz.daemon.quartz.mapper.SysUserMapper;
import com.qunzhixinxi.hnqz.daemon.quartz.service.*;
import com.qunzhixinxi.hnqz.daemon.quartz.zhuqu.ZhuaquTest;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 郑健楠
 */
@Slf4j
@Component("demo")
@AllArgsConstructor
public class SpringBeanTaskDemo {
	private final WmScorePackageStatusService wmScorePackageStatusService;
	private final WmScorePackageSettleNoteService scorePackageSettleNoteService;
	private final WmScorePackageService wmScorePackageService;
	private final SysUserMapper sysUserMapper;
	private final JavaMailSender sender;
	private final ZhuaquTest zhuaquTest;
	private final WmTaskTypeService wmTaskTypeService;
	private final WmTaskService wmTaskService;
	private final WmWkArticleService wmWkArticleService;
	private final WmStatisticsService wmStatisticsService;
	private final SingleMemberSettleSameAmountInSeveralMonthsMapper singleMemberSettleSameAmountInSeveralMonthsMapper;
	private final SingleMemberSettleAmountOverrunInSeveralMonthsMapper singleMemberSettleAmountOverrunInSeveralMonthsMapper;
	private final SingleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonthMapper singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonthMapper;
	private final SingleMemberWithoutSuchTaskTypesInSeveralMonthsMapper singleMemberWithoutSuchTaskTypesInSeveralMonthsMapper;

//	/**
//	 * 测试Spring Bean的演示方法
//	 */
//	@SneakyThrows
//	public String demoMethod(String para) {
//		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
//		wmScorePackageStatusService.changePackageStatus();
//		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
//	}

	@SneakyThrows
	public String changePackageStatusTask(String para) {
		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
		wmScorePackageStatusService.changePackageStatus();
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}


	@SneakyThrows
	public String getArtileTask(String para) {
		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
		zhuaquTest.init_main(para);
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	@SneakyThrows
	public String changeTaskRule(String para) {
		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
		wmTaskTypeService.changeTaskTypeInfo(para);
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	@SneakyThrows
	public String buildTaskImg(String para) {
		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
		wmTaskService.buildTaskImg(para);
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	/**
	 * 每日GMVs统计
	 *
	 * @param para
	 * @return
	 */
	@SneakyThrows
	public String dailyGMVsStatistic(String para) {
		log.info("dailyGMVsStatistic开始于:{}，输入参数{}", LocalDateTime.now(), para);
		wmStatisticsService.dailyGMVsStatistics(para);
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	@SneakyThrows
	public String setHotArtileTask(String para) {
		log.info("setHotArtileTask开始于:{}，输入参数{}", LocalDateTime.now(), para);
		wmWkArticleService.setHotArtileTask(para);
		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	/**
	 * 同一用户，连续多月结算金额相同
	 *
	 * @param para 参数（月数）
	 * @return 运行结果
	 */
	@SneakyThrows
	public String singleMemberSettleSameAmountInSeveralMonths(String para) {
		// 校验参数
		if (StrUtil.isBlank(para)) {
			log.error("参数缺失");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		List<String> params = StrUtil.split(para, StrUtil.COMMA);
		int period = Integer.parseInt(params.get(0).trim());
		String uuid = params.get(params.size() - 1);

		if (period < 2) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		// 计算查询时间
		LocalDate now = LocalDateTime.now().toLocalDate().with(TemporalAdjusters.firstDayOfNextMonth());
		LocalDateTime startTime = LocalDateTime.of(now.minusMonths(period), LocalTime.MIN);
		LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MIN).minusSeconds(1);

		log.info("singleMemberSettleSameAmountInSeveralMonths开始于:{}，输入参数{}", LocalDateTime.now(), para);

		List<SingleMemberSettleSameAmountInSeveralMonths> result = scorePackageSettleNoteService.singleMemberSettleSameAmountInSeveralMonths(startTime, endTime);

		if (CollUtil.isNotEmpty(result)) {
			result.forEach(e -> {
				e.setPeriod(period);
				e.setUuid(uuid);
				singleMemberSettleSameAmountInSeveralMonthsMapper.insert(e);
			});
		}

		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	/**
	 * 同一用户，连续多月结算金额超过限额
	 *
	 * @param para 参数（月数和限额）
	 * @return 运行结果
	 */
	@SneakyThrows
	public String singleMemberSettleAmountOverrunInSeveralMonths(String para) {
		// 校验参数
		if (StrUtil.isBlank(para)) {
			log.error("参数缺失");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		if (!para.contains(StrUtil.COMMA)) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		List<String> params = StrUtil.split(para.trim(), StrUtil.COMMA);

		if (params.size() != 3) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		int period = Integer.parseInt(params.get(0));
		BigDecimal limit = new BigDecimal(params.get(1));
		String uuid = params.get(params.size() - 1);

		if (period < 1 || limit.doubleValue() < 0.01) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		// 计算查询时间
		LocalDate now = LocalDateTime.now().toLocalDate().with(TemporalAdjusters.firstDayOfNextMonth());
		LocalDateTime startTime = LocalDateTime.of(now.minusMonths(period), LocalTime.MIN);
		LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MIN).minusSeconds(1);

		log.info("singleMemberSettleAmountOverrunInSeveralMonths开始于:{}，输入参数{}", LocalDateTime.now(), para);

		List<SingleMemberSettleSameAmountInSeveralMonths> result = scorePackageSettleNoteService.singleMemberSettleAmountOverrunInSeveralMonths(startTime, endTime, limit);

		if (CollUtil.isNotEmpty(result)) {
			result.forEach(e -> {
				SingleMemberSettleAmountOverrunInSeveralMonths singleMemberSettleAmountOverrunInSeveralMonths
						= BeanUtil.copyProperties(e, SingleMemberSettleAmountOverrunInSeveralMonths.class);
				singleMemberSettleAmountOverrunInSeveralMonths.setPeriod(period);
				singleMemberSettleAmountOverrunInSeveralMonths.setPlatformLimit(limit);
				singleMemberSettleAmountOverrunInSeveralMonths.setCreateTime(LocalDateTime.now());
				singleMemberSettleAmountOverrunInSeveralMonths.setUuid(uuid);
				singleMemberSettleAmountOverrunInSeveralMonthsMapper.insert(singleMemberSettleAmountOverrunInSeveralMonths);
			});
		}

		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();

	}


	/**
	 * 同一企业，当前月给多个用户支付相同金额
	 *
	 * @param para 参数（统计人数）
	 * @return 运行结果
	 */
	@SneakyThrows
	public String singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth(String para) {

		// 校验参数
		if (StrUtil.isBlank(para)) {
			log.error("参数缺失");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		List<String> params = StrUtil.split(para, StrUtil.COMMA);

		int memberCount = Integer.parseInt(params.get(0).trim());

		if (memberCount <= 1) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		String uuid = params.get(params.size() - 1);

		// 计算查询时间
		int period = 1;
		LocalDate now = LocalDateTime.now().toLocalDate().with(TemporalAdjusters.firstDayOfNextMonth());
		LocalDateTime startTime = LocalDateTime.of(now.minusMonths(period), LocalTime.MIN);
		LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MIN).minusSeconds(1);

		log.info("singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth开始于:{}，输入参数{}", LocalDateTime.now(), para);

		List<SingleMemberSettleSameAmountInSeveralMonths> result = scorePackageSettleNoteService.singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth(startTime, endTime, memberCount);

		if (CollUtil.isNotEmpty(result)) {
			result.forEach(e -> {
				SingleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth
						= BeanUtil.copyProperties(e, SingleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth.class);
				singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth.setPeriod(period);
				singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth.setMemberCount(memberCount);
				singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth.setCreateTime(LocalDateTime.now());
				singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth.setUuid(uuid);
				singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonthMapper.insert(singleEnterpriseSettleSameAmountForSeveralMembersInCurrentMonth);
			});
		}

		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();

	}


	/**
	 * 同一用户，连续多月没有指定任务类型
	 *
	 * @param para 参数（周期和任务类型）
	 * @return 运行结果
	 */
	@SneakyThrows
	public String singleMemberWithoutSuchTaskTypesInSeveralMonths(String para) {

		// 校验参数
		if (StrUtil.isBlank(para)) {
			log.error("参数缺失");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		if (!para.contains(StrUtil.COMMA)) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		List<String> params = StrUtil.split(para, StrUtil.COMMA);

		if (params.size() < 2) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		int period = Integer.parseInt(params.get(0));
		if (period < 2) {
			log.error("参数错误");
			return HnqzQuartzEnum.JOB_LOG_STATUS_FAIL.getType();
		}

		List<String> typeList = params.subList(1, params.size() - 1);
		String uuid = params.get(params.size() - 1);
		// 计算查询时间
		LocalDate now = LocalDateTime.now().toLocalDate().with(TemporalAdjusters.firstDayOfNextMonth());
		LocalDateTime startTime = LocalDateTime.of(now.minusMonths(period), LocalTime.MIN);
		LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MIN).minusSeconds(1);

		log.info("singleMemberWithoutSuchTaskTypesInSeveralMonths开始于:{}，输入参数{}", LocalDateTime.now(), para);

		List<Map<String, Object>> result = wmTaskService.singleMemberWithoutSuchTaskTypesInSeveralMonths(startTime, endTime, typeList);

		if (CollUtil.isNotEmpty(result)) {

			String types = String.join(StrUtil.COMMA, typeList.toArray(new String[0]));

			result.forEach(e -> {
				SingleMemberWithoutSuchTaskTypesInSeveralMonths singleMemberWithoutSuchTaskTypesInSeveralMonths
						= BeanUtil.mapToBean(e, SingleMemberWithoutSuchTaskTypesInSeveralMonths.class, true, new CopyOptions());

				List<WmTask> list = wmTaskService.list(Wrappers.<WmTask>lambdaQuery().eq(WmTask::getScorePackageId, e.get(singleMemberWithoutSuchTaskTypesInSeveralMonths.getPackageId())).orderByDesc(WmTask::getCreateTime));

				if (CollUtil.isNotEmpty(list)) {
					singleMemberWithoutSuchTaskTypesInSeveralMonths.setFirstTaskTime(list.get(0).getCreateTime());
				}
				singleMemberWithoutSuchTaskTypesInSeveralMonths.setPeriod(period);
				singleMemberWithoutSuchTaskTypesInSeveralMonths.setTypeList(types);
				singleMemberWithoutSuchTaskTypesInSeveralMonths.setCreateTime(LocalDateTime.now());
				singleMemberWithoutSuchTaskTypesInSeveralMonths.setUuid(uuid);
				singleMemberWithoutSuchTaskTypesInSeveralMonthsMapper.insert(singleMemberWithoutSuchTaskTypesInSeveralMonths);
			});
		}

		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();

	}


	@SneakyThrows
	public String pushUserCertFailure(String para) {

		String[] re = {
				"qutong@yaoyi.net",
				"yangshuang@yaoyi.net",
				"changtianchen@yaoyi.net",
				"huangyinyu@yaoyi.net",
				"zhaoshunyu@yaoyi.net",
				"lishuilian@yaoyi.net"
		};

		log.info("pushUserCertFailure:{}，输入参数{}", LocalDateTime.now(), para);

		List<TreeMap<String, Object>> stringObjectMap = sysUserMapper.listUserCertFailure();
		if (CollUtil.isNotEmpty(stringObjectMap)) {

			StringBuilder text = new StringBuilder("<html><head></head><body><table style=\"width:100%\">\n" +
					"    <tr>\n" +
					"        <th>ID</th>\n" +
					"        <th>姓名</th>\n" +
					"        <th>账号</th>\n" +
					"        <th>所属企业</th>\n" +
					"        <th>结算平台</th>\n" +
					"        <th>税源地</th>\n" +
					"        <th>认证表述</th>\n" +
					"        <th>认证状态</th>\n" +
					"        <th>发起状态</th>\n" +
					"        <th>上次回信信息</th>\n" +
					"        <th>是否有手签</th>\n" +
					"        <th>是否有e证通认证结果</th>\n" +
					"        <th>用户操作认证时间</th>\n" +
					"    </tr>");

			stringObjectMap.forEach(e -> {
				text.append("<tr>");

				text.append("<td>").append(e.get("ID")).append("</td>");
				text.append("<td>").append(e.get("姓名")).append("</td>");
				text.append("<td>").append(e.get("账号")).append("</td>");
				text.append("<td>").append(e.get("所属企业")).append("</td>");
				text.append("<td>").append(e.get("结算平台")).append("</td>");
				text.append("<td>").append(e.get("税源地")).append("</td>");
				text.append("<td>").append(e.get("认证表述")).append("</td>");
				text.append("<td>").append(e.get("认证状态")).append("</td>");
				text.append("<td>").append(e.get("发起状态")).append("</td>");
				text.append("<td>").append(e.get("上次回信信息")).append("</td>");
				text.append("<td>").append(e.get("手签")).append("</td>");
				text.append("<td>").append(e.get("E证通认证")).append("</td>");
				text.append("<td>").append(e.get("用户认证时间")).append("</td>");

				text.append("</tr>");
			});


			text.append("</table></body></html>");

			log.info("table ==> {}", text);
			MimeMessage mail = sender.createMimeMessage();
			try {

				MimeMessageHelper helper = new MimeMessageHelper(mail, true);

				helper.setFrom("yaoyi_report@yaoyi.net");
				helper.setTo(re);

				helper.setSubject("零工平台人员认证未完成信息汇总(" + DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now().minusDays(1L)) + ")");

				helper.setText(text.toString(), true);
				sender.send(mail);
			} catch (MessagingException ex) {
				log.error("邮件发送失败");
			}
		}

		return HnqzQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}
}
