package com.cyksj.service.invoice.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.mapper.UserInvoiceApplyRecordMapper;
import com.cyksj.mapper.UserInvoiceOrderRelateMapper;
import com.cyksj.mapper.channel.ShopConfigMapper;
import com.cyksj.model.entity.OrderDon;
import com.cyksj.model.entity.ShopConfig;
import com.cyksj.model.entity.UserInvoiceApplyRecord;
import com.cyksj.model.entity.UserInvoiceOrderRelate;
import com.cyksj.model.request.UserInvoiceOrderReq;
import com.cyksj.redis.RedisService;
import com.cyksj.service.invoice.UserInvoiceApplyRecordService;
import com.cyksj.service.user.UserBindRelationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 项目名: yhlxj
 * 文件名: UserInvoiceServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/12/13 15:28
 */
@Service
@RequiredArgsConstructor
public class UserInvoiceApplyRecordServiceImpl implements UserInvoiceApplyRecordService {
	private final UserInvoiceApplyRecordMapper userInvoiceApplyRecordMapper;

	private final UserInvoiceOrderRelateMapper userInvoiceOrderRelateMapper;

	private final OrderDonMapper orderDonMapper;

	private final UserBindRelationService userBindRelationService;

	private final ShopConfigMapper shopConfigMapper;

	private final RedisService redisService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public Long applyOrderInvoice(UserInvoiceOrderReq req) {
		Long userId = req.getUserId();
		String key = "invoice:key:" + userId;
		try {
			List<Long> orderIds = req.getOrderIds();
			if (CollUtil.isEmpty(orderIds)) {
				throw BusinessRuntimeException.getInstance("请选择对应订单");
			}
			String head = req.getHead();
			String taxNo = req.getTaxNo();
			String email = req.getEmail();
			String bank = req.getBank();
			String bankNo = req.getBankNo();
			if (StrUtil.hasEmpty(head, taxNo, email)) {
				throw BusinessRuntimeException.getInstance("请完成必填项");
			}
			if (!redisService.setNx(key, userId, 30l)) {
				throw BusinessRuntimeException.getInstance("正在提交中，请勿重复提交");
			}
			List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
			//订单里是否存在开过发票
			Integer selectCount = userInvoiceOrderRelateMapper.selectCount(Wrappers.lambdaQuery(UserInvoiceOrderRelate.class)
					.in(UserInvoiceOrderRelate::getOrderId, orderIds));
			if (selectCount > 0) {
				throw BusinessRuntimeException.getInstance("您选择的订单存在开过发票，请刷新页面重新选择");
			}
			//是否是自己订单
			List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
					.in(OrderDon::getId, orderIds)
					.in(OrderDon::getUserId, userIdList)
					.select(OrderDon::getId, OrderDon::getMoney, OrderDon::getShopId));
			if (orderDonList.size() != orderIds.size()) {
				throw BusinessRuntimeException.getInstance("订单选择错误，请刷新页面重新选择");
			}
			Set<String> shopIdSet = new HashSet<>();
			BigDecimal money = BigDecimal.ZERO;
			for (OrderDon orderDon : orderDonList) {
				shopIdSet.add(orderDon.getShopId());
				money = money.add(orderDon.getMoney());
			}
			//是否是统一主体
			if (shopIdSet.size() > 1) {
				throw BusinessRuntimeException.getInstance("所选订单的支付主体不一致，请重新选择)");
			}
			UserInvoiceApplyRecord invoiceApplyRecord = new UserInvoiceApplyRecord();
			invoiceApplyRecord.setHead(head);
			invoiceApplyRecord.setTaxNo(taxNo);
			invoiceApplyRecord.setUserId(userId);
			invoiceApplyRecord.setBank(bank);
			invoiceApplyRecord.setBankNo(bankNo);
			ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class)
					.in(ShopConfig::getAppId, shopIdSet)
					.last("limit 1"));
			if (shopConfig == null) {
				throw BusinessRuntimeException.getInstance("申请发票错误，请联系客服处理");
			}
			invoiceApplyRecord.setZfbPayment(shopConfig.getPayment());
			invoiceApplyRecord.setMoney(money);
			invoiceApplyRecord.setEmail(email);
			userInvoiceApplyRecordMapper.insert(invoiceApplyRecord);

			//关联记录id
			Long recordId = invoiceApplyRecord.getId();
			userInvoiceOrderRelateMapper.batchInsert(recordId, userId, orderIds);
			return invoiceApplyRecord.getId();
		} finally {
			redisService.del(key);
		}
	}
}
