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

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
import com.ym.mec.biz.dal.dao.SysUserCashAccountDetailDao;
import com.ym.mec.biz.dal.dao.SysUserCoursesAccountDetailDao;
import com.ym.mec.biz.dal.entity.SysUserCashAccount;
import com.ym.mec.biz.dal.entity.SysUserCashAccountDetail;
import com.ym.mec.biz.dal.entity.SysUserCoursesAccountDetail;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.PlatformCashAccountDetailTypeEnum;
import com.ym.mec.biz.dal.enums.PlatformCashAccountStatusEnum;
import com.ym.mec.biz.service.SysMessageService;
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.service.impl.BaseServiceImpl;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class SysUserCashAccountServiceImpl extends BaseServiceImpl<Integer, SysUserCashAccount> implements SysUserCashAccountService {

    @Autowired
    private SysUserCashAccountDao sysUserCashAccountDao;
    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private SysUserCashAccountDetailDao sysUserCashAccountDetailDao;
    @Autowired
    private SysUserCoursesAccountDetailDao sysUserCoursesAccountDetailDao;

    @Override
    public BaseDAO<Integer, SysUserCashAccount> getDAO() {
        return sysUserCashAccountDao;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateBalance(Integer userId, BigDecimal decimal) {

        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        if (cashAccount.getStatus() != PlatformCashAccountStatusEnum.NORMAL) {
            throw new BizException("账户不可用");
        }
        BigDecimal balance = cashAccount.getBalance().add(decimal);
        if (balance.doubleValue() < 0) {
            throw new BizException("现金账户[{}]余额不足，可用余额剩{}元", userId, cashAccount.getBalance().doubleValue());
        }

        cashAccount.setBalance(balance);
        cashAccount.setUpdateTime(new Date());

        sysUserCashAccountDao.update(cashAccount);

        return true;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String memo) {
        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        if (cashAccount.getStatus() != PlatformCashAccountStatusEnum.NORMAL) {
            throw new BizException("账户不可用");
        }
        BigDecimal balance = cashAccount.getBalance().add(decimal);
        if (balance.doubleValue() < 0) {
            throw new BizException("现金账户[{}]余额不足，可用余额剩{}元", userId, cashAccount.getBalance().doubleValue());
        }

        String comment = memo;
        if(sysUserFeignService.queryUserInfo() != null){
            comment = memo + "-" + sysUserFeignService.queryUserInfo().getId();
        }

        Date date = new Date();

        SysUserCashAccountDetail detail = new SysUserCashAccountDetail();
        detail.setAmount(decimal);
        detail.setBalance(cashAccount.getBalance().add(decimal));
        detail.setComment(comment);
        detail.setCreateTime(date);
        detail.setDescription(memo);
        detail.setStatus(DealStatusEnum.SUCCESS);
        detail.setType(type);
        detail.setUpdateTime(date);
        detail.setUserId(userId);

        sysUserCashAccountDetailDao.insert(detail);

        cashAccount.setBalance(balance);
        cashAccount.setUpdateTime(date);

        sysUserCashAccountDao.update(cashAccount);
        if (!decimal.equals(BigDecimal.ZERO)) {
            //推送余额消费信息
            Map<Integer, String> phoneMap = new HashMap<>(1);
            SysUser sysUser = sysUserFeignService.queryUserById(userId);
            phoneMap.put(userId, sysUser.getPhone());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_SMS_BALANCE_CONSUME,
                    phoneMap, null, 0, null, "", decimal, balance);
            Map<Integer, String> idMap = new HashMap<>(1);
            idMap.put(userId, userId.toString());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_SMS_BALANCE_CONSUME,
                    idMap, null, 0, null, "", decimal, balance);
        }
        return true;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String memo,String transNo) {
        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        if (cashAccount.getStatus() != PlatformCashAccountStatusEnum.NORMAL) {
            throw new BizException("账户不可用");
        }
        BigDecimal balance = cashAccount.getBalance().add(decimal);
        if (balance.doubleValue() < 0) {
            throw new BizException("现金账户[{}]余额不足，可用余额剩{}元", userId, cashAccount.getBalance().doubleValue());
        }

        Date date = new Date();

        SysUserCashAccountDetail detail = new SysUserCashAccountDetail();
        detail.setAmount(decimal);
        detail.setBalance(cashAccount.getBalance().add(decimal));
        detail.setComment(memo);
        detail.setTransNo(transNo);
        detail.setCreateTime(date);
        detail.setStatus(DealStatusEnum.SUCCESS);
        detail.setType(type);
        detail.setUpdateTime(date);
        detail.setUserId(userId);

        sysUserCashAccountDetailDao.insert(detail);

        cashAccount.setBalance(balance);
        cashAccount.setUpdateTime(date);

        sysUserCashAccountDao.update(cashAccount);
        if (!decimal.equals(BigDecimal.ZERO)) {
            //推送余额消费信息
            Map<Integer, String> phoneMap = new HashMap<>(1);
            SysUser sysUser = sysUserFeignService.queryUserById(userId);
            phoneMap.put(userId, sysUser.getPhone());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_SMS_BALANCE_CONSUME,
                    phoneMap, null, 0, null, "", decimal, balance);
            Map<Integer, String> idMap = new HashMap<>(1);
            idMap.put(userId, userId.toString());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_SMS_BALANCE_CONSUME,
                    idMap, null, 0, null, "", decimal, balance);
        }
        return true;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public boolean updateCourseBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, BigDecimal amount, String description) {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            throw new BizException("用户信息获取失败");
        }
        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        amount = decimal.subtract(cashAccount.getCourseBalance());
        
        Date date = new Date();

        cashAccount.setCourseBalance(decimal);
        cashAccount.setUpdateTime(date);

        sysUserCashAccountDao.update(cashAccount);

        if (amount.compareTo(BigDecimal.ZERO) !=0 ) {
            SysUserCoursesAccountDetail sysUserCoursesAccountDetail = new SysUserCoursesAccountDetail();
            sysUserCoursesAccountDetail.setUserId(userId);
            sysUserCoursesAccountDetail.setAmount(amount);
            sysUserCoursesAccountDetail.setBalance(decimal);
            sysUserCoursesAccountDetail.setComment(description + "-" + sysUser.getId());
            sysUserCoursesAccountDetail.setStatus(DealStatusEnum.SUCCESS);
            sysUserCoursesAccountDetail.setType(type);
            sysUserCoursesAccountDetail.setUpdateTime(date);
            sysUserCoursesAccountDetail.setCreateTime(date);
            sysUserCoursesAccountDetailDao.insert(sysUserCoursesAccountDetail);
        }
        return true;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public boolean appendCourseBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String description) {
        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        BigDecimal balance = cashAccount.getCourseBalance().add(decimal);
        if (balance.doubleValue() < 0) {
            throw new BizException("现金账户[{}]课程余额不足，可用余额剩{}元", userId, cashAccount.getCourseBalance().doubleValue());
        }

        Date date = new Date();
        cashAccount.setCourseBalance(balance);
        cashAccount.setUpdateTime(date);

        sysUserCashAccountDao.update(cashAccount);

        if (decimal.compareTo(BigDecimal.ZERO) != 0) {
           String comment = description;
            SysUser sysUser = sysUserFeignService.queryUserInfo();
            if(sysUser != null && sysUser.getId()!=null){
                comment +=  "-" + sysUser.getId();
            }
            SysUserCoursesAccountDetail sysUserCoursesAccountDetail = new SysUserCoursesAccountDetail();
            sysUserCoursesAccountDetail.setUserId(userId);
            sysUserCoursesAccountDetail.setAmount(decimal);
            sysUserCoursesAccountDetail.setBalance(balance);
            sysUserCoursesAccountDetail.setComment(comment);
            sysUserCoursesAccountDetail.setStatus(DealStatusEnum.SUCCESS);
            sysUserCoursesAccountDetail.setType(type);
            sysUserCoursesAccountDetail.setUpdateTime(date);
            sysUserCoursesAccountDetail.setCreateTime(date);
            sysUserCoursesAccountDetailDao.insert(sysUserCoursesAccountDetail);
        }

        return true;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean transferCourseBalanceToBalance(Integer userId, BigDecimal money) {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
        if (money == null || money.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BizException("充值金额必须大于0");
        }
        if (cashAccount == null) {
            throw new BizException("用户[{}]现金账户不存在", userId);
        }

        if (cashAccount.getStatus() != PlatformCashAccountStatusEnum.NORMAL) {
            throw new BizException("账户不可用");
        }

        if (money.compareTo(cashAccount.getCourseBalance()) > 0) {
            throw new BizException("充值金额不能大于课程余额");
        }

        Date date = new Date();

        SysUserCashAccountDetail detail = new SysUserCashAccountDetail();
        detail.setAmount(money);
        detail.setBalance(cashAccount.getBalance().add(money));
        detail.setDescription("课程余额转账");
        detail.setComment("课程余额转账-"+sysUser.getId());
        detail.setCreateTime(date);
        detail.setStatus(DealStatusEnum.SUCCESS);
        detail.setType(PlatformCashAccountDetailTypeEnum.FILL_ACCOUNT);
        detail.setUpdateTime(date);
        detail.setUserId(userId);

        sysUserCashAccountDetailDao.insert(detail);

        cashAccount.setBalance(cashAccount.getBalance().add(money));
        cashAccount.setCourseBalance(cashAccount.getCourseBalance().subtract(money));
        cashAccount.setUpdateTime(date);

        sysUserCashAccountDao.update(cashAccount);

        SysUserCoursesAccountDetail sysUserCoursesAccountDetail = new SysUserCoursesAccountDetail();
        sysUserCoursesAccountDetail.setUserId(userId);
        sysUserCoursesAccountDetail.setType(PlatformCashAccountDetailTypeEnum.FILL_ACCOUNT);
        sysUserCoursesAccountDetail.setAmount(money.negate());
        sysUserCoursesAccountDetail.setBalance(cashAccount.getCourseBalance());
        sysUserCoursesAccountDetail.setDescription("课程余额转账");
        sysUserCoursesAccountDetail.setComment("课程余额转账-"+sysUser.getId());
        sysUserCoursesAccountDetail.setStatus(DealStatusEnum.SUCCESS);
        sysUserCoursesAccountDetail.setUpdateTime(date);
        sysUserCoursesAccountDetail.setCreateTime(date);
        sysUserCoursesAccountDetailDao.insert(sysUserCoursesAccountDetail);

        return true;
    }

    @Override
    public SysUserCashAccount getLocked(Integer userId) {
        return sysUserCashAccountDao.getLocked(userId);
    }

}
