package com.ym.mec.biz.service.impl;

import com.google.common.collect.Lists;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dto.CashAccountDetail;
import com.ym.mec.biz.dal.dto.WithdrawDto;
import com.ym.mec.biz.dal.dto.WithdrawInfoDto;
import com.ym.mec.biz.dal.entity.SysUserCashAccount;
import com.ym.mec.biz.dal.entity.SysUserCashAccountDetail;
import com.ym.mec.biz.dal.enums.PlatformCashAccountDetailTypeEnum;
import com.ym.mec.biz.service.SysUserCashAccountDetailService;
import com.ym.mec.biz.service.SysUserCashAccountService;
import com.ym.mec.biz.dal.enums.TransTypeEnum;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.utils.DateUtils;
import com.ym.mec.util.string.IdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.ym.mec.biz.dal.dao.StudentWithdrawDao;
import com.ym.mec.biz.dal.entity.StudentWithdraw;
import com.ym.mec.biz.service.StudentWithdrawService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class StudentWithdrawServiceImpl extends BaseServiceImpl<String, StudentWithdraw>  implements StudentWithdrawService {

	@Autowired
	private StudentWithdrawDao studentWithdrawDao;

	@Override
	public BaseDAO<String, StudentWithdraw> getDAO() {
		return studentWithdrawDao;
	}

	private static final Logger log = LoggerFactory.getLogger(StudentWithdrawServiceImpl.class);

//	@Qualifier("auth-server")
//	@Autowired
//	private SysUserFeignService sysUserFeignService;
	@Autowired
	private SysUserCashAccountService cashAccountService;
	@Autowired
	private SysUserCashAccountDetailService cashAccountDetailService;
	@Autowired
	private SysUserCashAccountDetailService accountDetailService;

	private Lock lock = new ReentrantLock();

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean confirmWithdraw(WithdrawDto withdrawDto) {
		try {
//			SysUser sysUser = sysUserFeignService.queryUserInfo();
//			if (Objects.isNull(sysUser)) {
//				throw new BizException("请重新登录");
//			}
			lock.lock();
			SysUserCashAccount sysUserCashAccount = cashAccountService.get(withdrawDto.getUserId().intValue());
			if (Objects.isNull(sysUserCashAccount)){
				throw new BizException("账户不存在！");
			}
			//校验银行账户余额
			if (sysUserCashAccount.getBalance().compareTo(withdrawDto.getAmount()) < 0) {
				throw new BizException("余额不足，提现失败！");
			}
			//第三方提现到用户银行卡
			//用户个人虚拟账户金额减少
			updateCashAccount(sysUserCashAccount, withdrawDto);
			//生成提现记录(缺少银行流水号，交易状态，用户承担的费用，平台承担的费用)
			saveStudentWithdraw(withdrawDto);
		} catch (Exception e) {
			log.error("用户提现出现异常 {}", e.getMessage(), e);
			throw new BizException(e.getMessage());
		} finally {
			lock.unlock();
		}
		return true;
	}

	@Override
	public PageInfo<WithdrawInfoDto> queryWithdrawPage(CashAccountDetail cashAccountDetail) {
		PageInfo<WithdrawInfoDto> result = new PageInfo<>();
		cashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.WITHDRAW.getCode());
		PageInfo<SysUserCashAccountDetail> accountDetailPageInfo = accountDetailService.queryPage(cashAccountDetail);
		List<WithdrawInfoDto> dataList = Lists.newArrayList();
		accountDetailPageInfo.getRows().forEach(data ->{
			WithdrawInfoDto withdrawInfoDto = new WithdrawInfoDto();
			StudentWithdraw studentWithdraw = studentWithdrawDao.getByUserId(data.getUserId().longValue());
			withdrawInfoDto.setWithdrawId(studentWithdraw.getId());
			withdrawInfoDto.setDateTime(DateUtils.date2ChineseDate(studentWithdraw.getCreateTime()));
			withdrawInfoDto.setAmount(data.getAmount());
			withdrawInfoDto.setBalance(data.getBalance());
			withdrawInfoDto.setTransTypeName(TransTypeEnum.getDescriptionByCode(data.getTransType().getCode()));
			withdrawInfoDto.setAccountNo(studentWithdraw.getBankCardNo());
			withdrawInfoDto.setWithdrawStatus(studentWithdraw.getStatus().getMsg());
			//支付账号
			dataList.add(withdrawInfoDto);
		});
		BeanUtils.copyProperties(accountDetailPageInfo, result);
		result.setRows(dataList);
		return result;
	}

	/**
	 * 修改用户账户余额，保存账户明细
	 *
	 * @param withdrawDto
	 */
	private void updateCashAccount(SysUserCashAccount sysUserCashAccount, WithdrawDto withdrawDto) {
		BigDecimal balance = sysUserCashAccount.getBalance().subtract(withdrawDto.getAmount());
		SysUserCashAccount account = new SysUserCashAccount();
		account.setUserId(sysUserCashAccount.getUserId());
		account.setBalance(balance);
		account.setUpdateTime(new Date());
		cashAccountService.update(account);
		SysUserCashAccountDetail cashAccountDetail = new SysUserCashAccountDetail();
		cashAccountDetail.setUserId(withdrawDto.getUserId());
		cashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.WITHDRAW);
		cashAccountDetail.setAmount(withdrawDto.getAmount());
		cashAccountDetail.setBalance(balance);
		cashAccountDetail.setCreateTime(new Date());
		cashAccountDetailService.insert(cashAccountDetail);
	}

	/**
	 * 保存提现记录
	 *
	 * @param withdrawDto
	 */
	private void saveStudentWithdraw(WithdrawDto withdrawDto) {
		IdWorker idWorker = new IdWorker(0, 0);
		StudentWithdraw studentWithdraw = new StudentWithdraw();
		studentWithdraw.setId(idWorker.nextId());
		studentWithdraw.setUserId(withdrawDto.getUserId().longValue());
		studentWithdraw.setBankCardNo(withdrawDto.getBankCardNo());
		studentWithdraw.setAmount(withdrawDto.getAmount());
		studentWithdraw.setCreateTime(new Date());
		insert(studentWithdraw);
	}

}
