/*
 *    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.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qunzhixinxi.hnqz.admin.entity.MonitoringIndicator;
import com.qunzhixinxi.hnqz.admin.entity.SysDeptSub;
import com.qunzhixinxi.hnqz.admin.entity.WmScorePackageSettleNote;
import com.qunzhixinxi.hnqz.admin.entity.output.SettleAmountMonitorOutput;
import com.qunzhixinxi.hnqz.admin.enums.SubjectLocation;
import com.qunzhixinxi.hnqz.admin.enums.SubjectTypeEnum;
import com.qunzhixinxi.hnqz.admin.mapper.MonitoringIndicatorMapper;
import com.qunzhixinxi.hnqz.admin.service.MonitoringIndicatorService;
import com.qunzhixinxi.hnqz.admin.service.SysDeptSubService;
import com.qunzhixinxi.hnqz.common.core.util.R;
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants.MONITORING_INDICATOR;

/**
 * 风险监控
 *
 * @author ryz
 * @date 2021-04-19 16:08:29
 */
@Slf4j
@Service
@AllArgsConstructor
public class MonitoringIndicatorServiceImpl extends ServiceImpl<MonitoringIndicatorMapper, MonitoringIndicator> implements MonitoringIndicatorService {

	private final SysDeptSubService sysDeptSubService;

	/**
	 * 获取税源地限额
	 *
	 * @param subjectLocation 税源地
	 * @return 限额信息
	 */
	@Override
	public MonitoringIndicator locationLimit(SubjectLocation subjectLocation) {
		MonitoringIndicator one = this.getOne(Wrappers.<MonitoringIndicator>lambdaQuery().eq(MonitoringIndicator::getSubjectLocation, subjectLocation));

		if (one == null) {
			throw new RuntimeException("风控信息不存在");
		}

		log.info("风控信息:{}", one);
		return one;
	}

	/**
	 * 结算校验
	 *
	 * @param notes    结算记录
	 * @param location 税源地
	 * @return 总结算额
	 */
	@Override
	public BigDecimal settleMonitoringIndicator(Collection<WmScorePackageSettleNote> notes, SubjectLocation location) {
		// 结算渠道
		SysDeptSub sysDeptSub = sysDeptSubService.getDeptSub(SecurityUtils.getUser().getDeptId(), location);

		// 校验当月结算额度
		List<String> idCards = notes.stream().map(WmScorePackageSettleNote::getIdCardNumber).collect(Collectors.toList());
		List<Integer> noteIds = notes.stream().map(WmScorePackageSettleNote::getId).filter(Objects::nonNull).collect(Collectors.toList());
		Set<Integer> userIds = notes.stream().map(WmScorePackageSettleNote::getUserId).map(Integer::valueOf).collect(Collectors.toSet());

		List<SettleAmountMonitorOutput> monitorOutputList = sysDeptSubService.getSettleAmountMonitor(idCards, noteIds, location);
		List<SettleAmountMonitorOutput> yaoyiAmountMonitor = sysDeptSubService.getYaoyiAmountMonitor(idCards, noteIds, location);
		List<SettleAmountMonitorOutput> deptAmountMonitor = sysDeptSubService.getDeptAmountMonitor(userIds, noteIds, location);

		// 限额
		MonitoringIndicator monitoringIndicator = this.locationLimit(location);

		BigDecimal deptLimit = sysDeptSub.getLimitAmount();
		BigDecimal monitoringLimit = monitoringIndicator.getLimitAmount();
		BigDecimal yaoyiLimitAmount = monitoringIndicator.getYaoyiLimitAmount();

		BigDecimal total = BigDecimal.ZERO;
		for (WmScorePackageSettleNote note : notes) {
			total = total.add(note.getSettleAmount());
			BigDecimal monitorAmount = note.getSettleAmount();
			BigDecimal deptMonitorAmount = note.getSettleAmount();
			BigDecimal yaoyiMonitorAmount = note.getSettleAmount();
			SettleAmountMonitorOutput monitorOutput = monitorOutputList.stream().filter(item -> item.getIdCardNumber()
					.equals(note.getIdCardNumber())).findFirst().orElse(null);

			SettleAmountMonitorOutput deptMonitorOutput = deptAmountMonitor.stream().filter(item -> item.getUserId()
					.equals(note.getUserId())).findFirst().orElse(null);

			SettleAmountMonitorOutput yaoyiMonitorOutput = yaoyiAmountMonitor.stream().filter(item -> item.getIdCardNumber()
					.equals(note.getIdCardNumber())).findFirst().orElse(null);

			if (null != monitorOutput) {
				monitorAmount = monitorAmount.add(monitorOutput.getTotalAmount());
			}

			if (null != deptMonitorOutput) {
				deptMonitorAmount = deptMonitorAmount.add(deptMonitorOutput.getTotalAmount());
			}

			if (null != yaoyiMonitorOutput) {
				yaoyiMonitorAmount = yaoyiMonitorAmount.add(yaoyiMonitorOutput.getTotalAmount());
			}

			if (null != deptLimit && deptMonitorAmount.compareTo(deptLimit) > 0) {
				throw new RuntimeException(note.getRealName() + "：超过当月限额");
			}

			if (null != monitoringLimit && monitorAmount.compareTo(monitoringLimit) > 0) {
				throw new RuntimeException(note.getRealName() + "：超过结算渠道限额");
			}
			if (null != yaoyiLimitAmount && yaoyiMonitorAmount.compareTo(yaoyiLimitAmount) > 0) {
				throw new RuntimeException(note.getRealName() + "：超过平台限额");
			}
		}

		return total;
	}
}
