package com.cyksj.service.goods.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.Xmls;
import com.cyksj.mapper.GoodsWholesaleMapper;
import com.cyksj.mapper.GoodsWholesaleOrderDonMapper;
import com.cyksj.mapper.GoodsWholesaleUserAccountMapper;
import com.cyksj.mapper.GoodsWholesaleUserDepositMapper;
import com.cyksj.mapper.channel.ShopConfigMapper;
import com.cyksj.mapper.manage.cms.CmsUserMapper;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.model.dto.GoodsWholesaleUserDepositDto;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.OrderRefundReq;
import com.cyksj.service.goods.GoodsWholesaleService;
import com.cyksj.service.order.OrderRefundService;
import com.cyksj.service.user.UserBindRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 项目名: yhlxj
 * 文件名: GoodsWholesaleServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/8/26 11:49
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GoodsWholesaleServiceImpl extends ServiceImpl<GoodsWholesaleMapper, GoodsWholesale> implements GoodsWholesaleService {
	private final GoodsWholesaleUserDepositMapper goodsWholesaleUserDepositMapper;

	private final OrderRefundService orderRefundService;

	private final ShopConfigMapper shopConfigMapper;

	private final CmsUserMapper cmsUserMapper;

	private final GoodsWholesaleOrderDonMapper wholesaleOrderDonMapper;

	private final GoodsWholesaleUserAccountMapper goodsWholesaleUserAccountMapper;

	private final SysConfigMapper sysConfigMapper;

	private final UserBindRelationService userBindRelationService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void depositRefund(Long id, Long adminId) throws Exception {
		GoodsWholesaleUserDeposit goodsWholesaleUserDeposit = goodsWholesaleUserDepositMapper.selectById(id);
		if (goodsWholesaleUserDeposit == null) {
			throw BusinessRuntimeException.getInstance("记录不存在");
		}
		if (goodsWholesaleUserDeposit.getStatus() == GoodsWholesaleUserDeposit.Status.refund) {
			throw BusinessRuntimeException.getInstance("押金已退");
		}

		int update = goodsWholesaleUserDepositMapper.update(null, Wrappers.lambdaUpdate(GoodsWholesaleUserDeposit.class)
				.set(GoodsWholesaleUserDeposit::getStatus, GoodsWholesaleUserDeposit.Status.refund)
				.eq(GoodsWholesaleUserDeposit::getId, id)
				.eq(GoodsWholesaleUserDeposit::getStatus, GoodsWholesaleUserDeposit.Status.hasPayment));
		if (update == 0) {
			throw BusinessRuntimeException.getInstance("押金已退");
		}
		String outRefundNo = orderRefundService.refundWholesaleUserDeposit(goodsWholesaleUserDeposit);
		goodsWholesaleUserDeposit.setRefundOutNo(outRefundNo);
		Optional.ofNullable(cmsUserMapper.selectById(adminId)).ifPresent(cu -> goodsWholesaleUserDeposit.setOperator(cu.getNickname()));
		//是否达到目标额
		setStatusIfGoal(goodsWholesaleUserDeposit);
		goodsWholesaleUserDeposit.setStatus(GoodsWholesaleUserDeposit.Status.refund);
		goodsWholesaleUserDepositMapper.updateById(goodsWholesaleUserDeposit);
	}

	@Override
	public void wxRefundNotify(Map<String, String> map) throws Exception {
		// 对退款数据 解密
		String md5Key = Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(shopConfigMapper.getByAppId(map.get("mch_id")).getSecret()).toHexString();
		String reqInfoXml = Codec.DoCipher.custom().setAlgorithm(Codec.DoCipher.Trans.AES_ECB_PKCS7Padding).setBase64Data(map.get("req_info")).setStringKey(md5Key).ofDecrypt().toText();
		log.info("=== 退款数据解密: \n {}", reqInfoXml);
		Map<String, String> reqInfoMap = Xmls.toMap(reqInfoXml);
		// 退款失败
		if (StrUtil.equals("CHANGE", reqInfoMap.get("refund_status"))) {
			throw BusinessRuntimeException.getInstance("退款异常.");
		} else if (StrUtil.equals("REFUNDCLOSE", reqInfoMap.get("refund_status"))) {
			throw BusinessRuntimeException.getInstance("退款关闭.");
		}
		/* 此处处理业务逻辑 */
		String outRefundNo = reqInfoMap.get("out_refund_no");
		String transactionId = reqInfoMap.get("transaction_id");
		String refundFee = reqInfoMap.get("refund_fee");
		GoodsWholesaleUserDeposit userDeposit = goodsWholesaleUserDepositMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserDeposit.class).eq(GoodsWholesaleUserDeposit::getTransactionId, transactionId).last("limit 1"));
		if (userDeposit == null) {
			log.error("退款回调,transactionId:{}订单不存在", transactionId);
			return;
		}
		log.info("微信退款: 退款单号[{}] 退款成功.", outRefundNo);
		if (userDeposit.getStatus()!= GoodsWholesaleUserDeposit.Status.refund) {
			userDeposit.setStatus(GoodsWholesaleUserDeposit.Status.refund);
			goodsWholesaleUserDepositMapper.updateById(userDeposit);
		}
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void uploadAccount(List<Object> acountList, Long orderId) {
		GoodsWholesaleOrderDon orderDon = wholesaleOrderDonMapper.selectById(orderId);

		if (orderDon.getStatus() != GoodsWholesaleOrderDon.Status.hasPayment) {
			throw BusinessRuntimeException.getInstance("订单状态错误");
		}

		int update = wholesaleOrderDonMapper.update(null, Wrappers.lambdaUpdate(GoodsWholesaleOrderDon.class)
				.set(GoodsWholesaleOrderDon::getStatus, GoodsWholesaleOrderDon.Status.complete)
				.eq(GoodsWholesaleOrderDon::getStatus, GoodsWholesaleOrderDon.Status.hasPayment)
				.eq(GoodsWholesaleOrderDon::getId, orderId));
		if (update == 0) {
			throw BusinessRuntimeException.getInstance("账号已发货");
		}
		String regex = "----";

		List<GoodsWholesaleUserAccount> insert = new ArrayList<>();

		GoodsWholesaleUserAccount goodsWholesaleUserAccount = null;

		for (Object obj : acountList) {
			Map<String, Object> map = Jsons.toMap(obj);

			String data = map.get(0).toString();

			String[] split = data.split(regex);

			String account = split[0];
			String password = split[1];

			goodsWholesaleUserAccount = new GoodsWholesaleUserAccount();

			goodsWholesaleUserAccount.setAccount(account);
			goodsWholesaleUserAccount.setPassword(password);
			insert.add(goodsWholesaleUserAccount);
		}

		goodsWholesaleUserAccountMapper.batchInsert(orderDon.getUserId(), orderId, insert);
	}

	@Override
	public void saveOrUpdateWholesale(GoodsWholesale wholesale) throws Exception {
		List<GoodsWholesale.GoodsWholesaleConfig> wholesaleConfig = wholesale.getWholesaleConfig();
		String config = Jsons.toJson(wholesaleConfig);
		wholesale.setConfig(config);
		try {
			this.saveOrUpdate(wholesale);
		} catch (DuplicateKeyException e) {
			throw BusinessRuntimeException.getInstance("已存在该批发规格");
		}
	}

	@Override
	public void updateOrderAccount(List<GoodsWholesaleUserAccount> goodsWholesaleUserAccounts) {
		goodsWholesaleUserAccounts.forEach(order -> {
			goodsWholesaleUserAccountMapper.updateById(order);
			if (order.getId() == null) {
				goodsWholesaleUserAccountMapper.insert(order);
			}
		});
	}

	@Override
	public void insertOrderAccount(List<GoodsWholesaleUserAccount> goodsWholesaleUserAccounts) {
		goodsWholesaleUserAccounts.forEach(order -> {
			goodsWholesaleUserAccountMapper.insert(order);
		});
		if (CollUtil.isNotEmpty(goodsWholesaleUserAccounts)) {
			Long orderId = goodsWholesaleUserAccounts.get(0).getOrderId();
			GoodsWholesaleOrderDon orderDon = wholesaleOrderDonMapper.selectById(orderId);
			orderDon.setStatus(GoodsWholesaleOrderDon.Status.complete);
			wholesaleOrderDonMapper.updateById(orderDon);
		}
	}

	@Override
	public void wholesaleOrderRefund(OrderRefundReq refundReq) throws Exception {
		Long orderId = refundReq.getOrderId();
		GoodsWholesaleOrderDon orderDon = wholesaleOrderDonMapper.selectById(orderId);
		if (orderDon == null) {
			return;
		}
		//余额
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			return;
		}
		if (orderDon.getStatus() == GoodsWholesaleOrderDon.Status.refund) {
			return;
		}
		orderDon.setRefundMoney(refundReq.getRefundMoney());
		String outRefundNo = orderRefundService.refundWholesaleOrder(orderDon);
		orderDon.setOutRefundNo(outRefundNo);
		orderDon.setStatus(GoodsWholesaleOrderDon.Status.refund);
		wholesaleOrderDonMapper.updateById(orderDon);
	}

	private void setStatusIfGoal(GoodsWholesaleUserDeposit goodsWholesaleUserDeposit) throws Exception {
		//是否已满足 批发足够账号
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.WHOLESALE_DEPOSIT_KEY)
				.last("limit 1"));
		if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
			log.error("押金配置已失效");
			return;
		}
		GoodsWholesaleUserDepositDto goodsWholesaleUserDepositDto = Jsons.parseObject(sysConfig.getSysValue(), GoodsWholesaleUserDepositDto.class);
		Integer num = goodsWholesaleUserDepositDto.getNum();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(goodsWholesaleUserDeposit.getUserId(), null);
		Integer payNum = wholesaleOrderDonMapper.getUserWholesaleNumByUserIds(userIdList, null);
		if (payNum >= num) {
			//批发数量已达
			goodsWholesaleUserDeposit.setIsGoal(true);
		}
	}
}
