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.auth.api.entity.SysUserRole;
import com.ym.mec.biz.dal.dao.MusicGroupDao;
import com.ym.mec.biz.dal.dao.StudentWithdrawDao;
import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
import com.ym.mec.biz.dal.dto.CashAccountDetail;
import com.ym.mec.biz.dal.dto.WithdrawInfoDto;
import com.ym.mec.biz.dal.entity.StudentWithdraw;
import com.ym.mec.biz.dal.entity.SysUserCashAccount;
import com.ym.mec.biz.dal.entity.SysUserCashAccountDetail;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.service.StudentWithdrawService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.biz.service.SysUserCashAccountDetailService;
import com.ym.mec.biz.service.SysUserCashAccountService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

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

	@Autowired
	private StudentWithdrawDao studentWithdrawDao;
	@Autowired
	private SysUserCashAccountDao sysUserCashAccountDao;

	@Autowired
	private SysUserFeignService sysUserFeignService;

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

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

	@Autowired
	private SysUserCashAccountService cashAccountService;
	@Autowired
	private SysUserCashAccountDetailService cashAccountDetailService;
	@Autowired
	private SysUserCashAccountDetailService accountDetailService;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private MusicGroupDao musicGroupDao;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean confirmWithdraw(Integer id, DealStatusEnum status, String memo, String transNo, TransTypeEnum transType, String platformAccountNo) {
		
		if (status == null || status == DealStatusEnum.ING) {
			throw new BizException("交易状态有误");
		}

		StudentWithdraw studentWithdraw = get(id);

		if (studentWithdraw == null) {
			throw new BizException("提现申请记录不存在");
		}

		Date date = new Date();

		Integer userId = studentWithdraw.getUserId();
		BigDecimal amount = studentWithdraw.getAmount();

		studentWithdraw.setComment(memo);
		studentWithdraw.setModifyTime(date);
		studentWithdraw.setStatus(status);
		studentWithdraw.setTransNo(transNo);

		studentWithdrawDao.update(studentWithdraw);

		try {
			SysUserCashAccount sysUserCashAccount = cashAccountService.get(userId);
			if (Objects.isNull(sysUserCashAccount)) {
				throw new BizException("账户不存在！");
			}
			// 校验银行账户余额
			if (sysUserCashAccount.getFrozenAmount().compareTo(amount) < 0) {
				throw new BizException("账户冻结金额异常");
			}
			sysUserCashAccount.setFrozenAmount(sysUserCashAccount.getFrozenAmount().subtract(amount));

			if (status == DealStatusEnum.FAILED) {
				sysUserCashAccount.setBalance(sysUserCashAccount.getBalance().add(amount));
			}
			sysUserCashAccount.setUpdateTime(date);
			cashAccountService.update(sysUserCashAccount);

			SysUserCashAccountDetail sysUserCashAccountDetail = new SysUserCashAccountDetail();
			sysUserCashAccountDetail.setUserId(userId);
			sysUserCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.WITHDRAW);
			sysUserCashAccountDetail.setStatus(status);
			sysUserCashAccountDetail.setAmount(amount.negate());
			sysUserCashAccountDetail.setAttribute(id + "");
			sysUserCashAccountDetail.setComment(memo);
			sysUserCashAccountDetail.setTransNo(transNo);
			sysUserCashAccountDetail.setTransType(transType);
			sysUserCashAccountDetail.setBalance(sysUserCashAccount.getBalance());
			sysUserCashAccountDetail.setPlatformAccountNo(platformAccountNo);
			sysUserCashAccountDetail.setCreateTime(date);

			cashAccountDetailService.insert(sysUserCashAccountDetail);

		} catch (Exception e) {
			log.error("用户提现出现异常 {}", e.getMessage(), e);
			throw new BizException(e.getMessage());
		}
		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());
			List<StudentWithdraw> studentWithdraws = studentWithdrawDao.queryByUserId(data.getUserId());
			withdrawInfoDto.setWithdrawId(studentWithdraw.getWithdrawNo());
			withdrawInfoDto.setDateTime(DateUtil.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;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void apply(String bankCardNo, BigDecimal amount) throws Exception {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null || sysUser.getId() == null) {
			throw new BizException("获取用户信息失败");
		}
		SysUserCashAccount account = sysUserCashAccountDao.getLocked(sysUser.getId());
		// 账户状态正常
		if (account != null && account.getStatus() == PlatformCashAccountStatusEnum.NORMAL) {
			// 提现金额不大于账户可用余额
			if (amount.compareTo(account.getBalance()) < 1) {
				Date date = new Date();

				StudentWithdraw withdraw = new StudentWithdraw();
				withdraw.setAmount(amount);
				withdraw.setBankCardNo(bankCardNo);
				withdraw.setCreateTime(date);
				withdraw.setModifyTime(date);
				withdraw.setStatus(DealStatusEnum.ING);
				withdraw.setUserId(sysUser.getId());
				withdraw.setWithdrawNo(System.currentTimeMillis() + "");

				// 修改账户余额
				BigDecimal subtract = account.getBalance().subtract(amount);
				account.setBalance(subtract);
				account.setFrozenAmount(account.getFrozenAmount().add(amount));
				account.setUpdateTime(date);
				sysUserCashAccountDao.update(account);

				studentWithdrawDao.insert(withdraw);

				SysUserCashAccountDetail cashAccountDetail = new SysUserCashAccountDetail();
				cashAccountDetail.setUserId(account.getUserId());
				cashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.WITHDRAW);
				cashAccountDetail.setAmount(amount.negate());
				cashAccountDetail.setBalance(subtract);
				cashAccountDetail.setCreateTime(date);
				cashAccountDetail.setStatus(DealStatusEnum.ING);
				cashAccountDetail.setAttribute(withdraw.getId()+"");
				cashAccountDetailService.insert(cashAccountDetail);
				Set<Integer> roleIds = new HashSet<>(1);
				roleIds.add(SysUserRole.SECTION_MANAGER);
				sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds,sysUser.getOrganId()), MessageTypeEnum.BACKSTAGE_STUDENT_APPLY_WITHDRAW,"",sysUser.getUsername());
			} else {
				throw new BizException("账户余额不足");
			}
		} else {
			throw new BizException("账户状态异常");
		}
	}

}
