package com.jsowell.pile.service.impl;

import com.google.common.collect.Lists;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.MemberBasicInfo;
import com.jsowell.pile.domain.MemberPlateNumberRelation;
import com.jsowell.pile.domain.MemberWalletInfo;
import com.jsowell.pile.domain.MemberWalletLog;
import com.jsowell.pile.mapper.MemberBasicInfoMapper;
import com.jsowell.pile.mapper.MemberPlateNumberRelationMapper;
import com.jsowell.pile.mapper.MemberWalletInfoMapper;
import com.jsowell.pile.mapper.MemberWalletLogMapper;
import com.jsowell.pile.service.IMemberBasicInfoService;
import com.jsowell.pile.service.IPileBasicInfoService;
import com.jsowell.pile.vo.MemberPlateNumberVO;
import com.jsowell.pile.vo.uniapp.MemberVO;
import com.jsowell.pile.vo.uniapp.MemberWalletLogVO;
import com.jsowell.pile.vo.uniapp.PersonalPileInfoVO;
import com.jsowell.pile.vo.web.UpdateMemberBalanceDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会员基础信息Service业务层处理
 *
 * @author jsowell
 * @date 2022-10-12
 */
@Slf4j
@Service
public class MemberBasicInfoServiceImpl implements IMemberBasicInfoService {
	@Autowired
	private MemberBasicInfoMapper memberBasicInfoMapper;

	@Autowired
	private MemberWalletInfoMapper memberWalletInfoMapper;

	@Autowired
	private MemberWalletLogMapper memberWalletLogMapper;

	@Autowired
	private IPileBasicInfoService pileBasicInfoService;

	@Autowired
	private MemberPlateNumberRelationMapper memberPlateNumberRelationMapper;
	/**
	 * 查询会员基础信息
	 *
	 * @param id 会员基础信息主键
	 * @return 会员基础信息
	 */
	@Override
	public MemberBasicInfo selectMemberBasicInfoById(Integer id) {
		return memberBasicInfoMapper.selectMemberBasicInfoById(id);
	}

	/**
	 * 查询会员基础信息列表
	 *
	 * @param memberBasicInfo 会员基础信息
	 * @return 会员基础信息
	 */
	/*@Override
	public List<MemberVO> selectMemberBasicInfoList(MemberBasicInfo memberBasicInfo) {
		List<MemberVO> voList = memberBasicInfoMapper.selectMemberList(memberBasicInfo.getMobileNumber(), memberBasicInfo.getNickName());
		for (MemberVO memberVO : voList) {
			memberVO.setPrincipalBalance(memberVO.getPrincipalBalance() == null ? BigDecimal.ZERO : memberVO.getPrincipalBalance());
			memberVO.setGiftBalance(memberVO.getGiftBalance() == null ? BigDecimal.ZERO : memberVO.getGiftBalance());
		}
		return voList;
	}*/

	/**
	 * 新增会员基础信息
	 *
	 * @param memberBasicInfo 会员基础信息
	 * @return 结果
	 */
	@Override
	public int insertMemberBasicInfo(MemberBasicInfo memberBasicInfo) {
		memberBasicInfo.setCreateTime(DateUtils.getNowDate());
		return memberBasicInfoMapper.insertMemberBasicInfo(memberBasicInfo);
	}

	/**
	 * 修改会员基础信息
	 *
	 * @param memberBasicInfo 会员基础信息
	 * @return 结果
	 */
	@Override
	public int updateMemberBasicInfo(MemberBasicInfo memberBasicInfo) {
		memberBasicInfo.setUpdateTime(DateUtils.getNowDate());
		return memberBasicInfoMapper.updateMemberBasicInfo(memberBasicInfo);
	}

	/**
	 * 批量删除会员基础信息
	 *
	 * @param ids 需要删除的会员基础信息主键
	 * @return 结果
	 */
	@Override
	public int deleteMemberBasicInfoByIds(List<Integer> ids) {
		return memberBasicInfoMapper.deleteMemberBasicInfoByIds(ids);
	}

	/**
	 * 通过物理卡号查询会员基本信息
	 *
	 * @param physicsCard 物理卡号
	 * @return 会员基本信息
	 */
	@Override
	public MemberVO selectInfoByPhysicsCard(String physicsCard) {
		return memberBasicInfoMapper.selectInfoByPhysicsCard(physicsCard);
	}

	/**
	 * 根据手机号和运营商id查询会员信息
	 * @param mobileNumber 手机号
	 * @param merchantId 运营商id
	 * @return 会员信息
	 */
	public MemberBasicInfo selectInfoByMobileNumberAndMerchantId(String mobileNumber, String merchantId) {
		return memberBasicInfoMapper.selectInfoByMobileNumberAndMerchantId(mobileNumber, merchantId);
	}

	@Override
	public MemberBasicInfo selectInfoByMobileNumber(String mobileNumber) {
		return selectInfoByMobileNumberAndMerchantId(mobileNumber, null);
	}

	@Override
	public MemberBasicInfo selectInfoByMemberId(String memberId) {
		return memberBasicInfoMapper.selectInfoByMemberId(memberId);
	}

	/**
	 * 修改用户余额 唯一方法
	 * 接收的金额都是正数，通过操作类型判断 充值还是扣减
	 */
	@Override
	public int updateMemberBalance(UpdateMemberBalanceDTO dto) {
		String memberId = dto.getMemberId();
		BigDecimal updateGiftBalance = dto.getUpdateGiftBalance();
		BigDecimal updatePrincipalBalance = dto.getUpdatePrincipalBalance();
		log.info("修改用户余额 memberId:{}, updatePrincipalBalance:{}, updateGiftBalance:{}", memberId, updatePrincipalBalance, updateGiftBalance);
		// 查询用户余额
		MemberWalletInfo info = memberWalletInfoMapper.selectByMemberId(memberId);
		if (info == null) {
			log.warn("根据会员id:{}, 查询会员信息为空", memberId);
			return 0;
		}

		// 记录流水
		List<MemberWalletLog> logList = Lists.newArrayList();
		// 计算新的余额
		BigDecimal newPrincipalBalance = null;
		BigDecimal newGiftBalance = null;

		// 更新本金金额
		if (updatePrincipalBalance != null) {
			if (StringUtils.equals(dto.getType(), "2")) {
				// 扣款 转为负数
				updatePrincipalBalance = updatePrincipalBalance.negate();
			}
			// 会员老的余额
			BigDecimal oldPrincipalBalance = info.getPrincipalBalance() == null
					? BigDecimal.ZERO
					: info.getPrincipalBalance();
			newPrincipalBalance = oldPrincipalBalance.add(updatePrincipalBalance);
			if (newPrincipalBalance.compareTo(BigDecimal.ZERO) < 0) {
				log.warn("新本金余额不能为负数");
				return 0;
			}
			// 记流水
			logList.add(MemberWalletLog.builder()
					.memberId(dto.getMemberId())
					.type(dto.getType())
					.subType(dto.getSubType())
					.amount(updatePrincipalBalance)
					.category("1")
					.relatedOrderCode(dto.getRelatedOrderCode())
					.createBy(dto.getMemberId())
					.build());
		}

		// 更新赠送金额
		if (updateGiftBalance != null) {
			if (StringUtils.equals(dto.getType(), "2")) {
				// 扣款 转为负数
				updateGiftBalance = updateGiftBalance.negate();
			}
			BigDecimal oldGiftBalance = info.getGiftBalance() == null
					? BigDecimal.ZERO
					: info.getGiftBalance();
			newGiftBalance = oldGiftBalance.add(updateGiftBalance);
			// 余额不能为负数
			if (newGiftBalance.compareTo(BigDecimal.ZERO) < 0) {
				log.warn("新赠送余额不能为负数");
				return 0;
			}
			// 记流水
			logList.add(MemberWalletLog.builder()
					.memberId(dto.getMemberId())
					.type(dto.getType())
					.subType(dto.getSubType())
					.amount(updateGiftBalance)
					.category("2")
					.relatedOrderCode(dto.getRelatedOrderCode())
					.createBy(dto.getMemberId())
					.build());
		}

		// 修改数据库
		int i = 0;
		if (newPrincipalBalance != null || newGiftBalance != null) {
			i = memberBasicInfoMapper.updateMemberBalance(memberId, newPrincipalBalance, newGiftBalance, info.getVersion());
			if (i == 0) {
				log.warn("修改余额失败, memberId:{}", memberId);
			}
		}
		// 插入 member_wallet_log 表
		if (CollectionUtils.isNotEmpty(logList)) {
			memberWalletLogMapper.batchInsert(logList);
		}
		return i;
	}

	@Override
	public MemberVO queryMemberInfoByMemberId(String memberId) {
		if (StringUtils.isBlank(memberId)) {
			return null;
		}
		// 加缓存
		MemberVO vo = memberBasicInfoMapper.queryMemberInfoByMemberId(memberId);
		if (vo == null) {
			return null;
		}
		vo.setTotalAccountAmount(vo.getPrincipalBalance().add(vo.getGiftBalance()));

		// 查询用户车牌号
		MemberPlateNumberRelation memberPlateNumberRelation = new MemberPlateNumberRelation();
		memberPlateNumberRelation.setMemberId(memberId);
		List<MemberPlateNumberRelation> list = memberPlateNumberRelationMapper.selectMemberPlateNumberRelationList(memberPlateNumberRelation);
		List<String> plateNumberList = list.stream()
				.map(MemberPlateNumberRelation::getLicensePlateNumber)
				.collect(Collectors.toList());
		vo.setPlateNumberList(plateNumberList);
		return vo;
	}

	@Override
	public List<MemberVO> selectMemberList(String mobileNumber, String nickName) {
		return memberBasicInfoMapper.selectMemberList(mobileNumber, nickName);
	}

	/**
	 * 查询用户账户余额变动信息
	 * @param memberId 会员id
	 * @param type 1-进账；2-出账 不传查全部
	 */
    @Override
    public List<MemberWalletLogVO> getMemberBalanceChanges(String memberId, String type) {
    	return memberWalletLogMapper.getMemberBalanceChanges(memberId, type);
    }

	/**
	 * 通过memberId查询会员的个人桩信息
	 * @param memberId
	 * @return
	 */
	@Override
	public List<PersonalPileInfoVO> getMemberPersonPileInfo(String memberId) {
		return pileBasicInfoService.getPileInfoByMemberId(memberId);
	}


}
