package com.sqx.modules.app.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.bo.UpdateMoneyBO;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.dao.UserMoneyDao;
import com.sqx.modules.app.dao.UserMoneyDetailsDao;
import com.sqx.modules.app.entity.RechargeRecord;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.RechargeRecordService;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.goods.entity.GoodsShop;
import com.sqx.modules.goods.service.GoodsShopService;
import com.sqx.modules.order.entity.TbOrder;
import com.sqx.modules.pay.service.NewPayService;
import com.sqx.modules.utils.SenInfoCheckUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> implements UserMoneyService {
    @Autowired
    private UserMoneyDetailsDao userMoneyDetailsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserMoneyDao userMoneyDao;
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private RechargeRecordService rechargeRecordService;
    @Autowired
    private GoodsShopService goodsShopService;
    @Autowired
    private NewPayService newPayService;

    @Override
    public void updateMoney(int i, Long userId, double money) {
        baseMapper.updateMayMoney(i, userId, money);
    }

    @Override
    public UserMoney selectUserMoneyByUserId(Long userId) {
        UserMoney userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("user_id", userId));
        if (userMoney == null) {
            userMoney = new UserMoney();
            userMoney.setUserId(userId);
            userMoney.setMoney(BigDecimal.ZERO);
            baseMapper.insert(userMoney);
            userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("user_id", userId));
        }
        return userMoney;
    }

    @Override
    public Double selectMyProfit(Long userId) {

        return userMoneyDetailsDao.selectMyProfit(userId);
    }

    @Override
    public Result balanceDetailed(Long userId, Integer page, Integer limit, Integer classify) {
        //余额明细
        Page<UserMoneyDetails> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(userMoneyDetailsDao.selectUserMoneyDetails(pages, userId, classify));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result profitDetailed(Long userId, IPage ipage) {
        //收益明细
        return null;
    }

    @Override
    public Result addUserMoney(Long userId, BigDecimal money, Integer type, String account, String remark) {
        log.info("充值记录参数；userId:"+userId+"money:"+money+"type:"+type+"account:"+account+"remark:"+remark);

        if(account == null){
            return Result.error("充值账号不能为空");
        }

        if (type.equals(2) && money.signum() == -1) {
            return Result.error("金额输入框请勿填充负号");
        }

        //获取用户信息
        UserEntity userInfo = userDao.selectUserById(userId);
        if (userInfo == null) {
            return Result.error("用户失效，操作失败");
        }

        UserMoney um = userMoneyDao.selectMoney(userId);
        BigDecimal oldMoney = BigDecimal.ZERO;
        if (um != null) {
            oldMoney = um.getMoney() != null ? um.getMoney() : BigDecimal.ZERO;
        }

        userMoneyDao.addUserMoney(userId, money, type);
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(money);
        userMoneyDetails.setUserId(userId);
        if (type.equals(1)) {
            userMoneyDetails.setContent("赠送用户余额：" + money + "元");
            userMoneyDetails.setTitle("系统赠送用户余额");
        } else if (type.equals(2)) {
            userMoneyDetails.setContent("扣除用户余额：" + money + "元");
            userMoneyDetails.setTitle("系统扣除用户余额");
        }
        userMoneyDetails.setType(type);
        userMoneyDetails.setClassify(3);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String ct = simpleDateFormat.format(new Date());
        userMoneyDetails.setCreateTime(ct);
        userMoneyDetailsService.save(userMoneyDetails);

        //region 添加充值记录 将充值人和被充值手机号填进去
        RechargeRecord rr = new RechargeRecord();
        rr.setUserId(userInfo.getUserId());
        String orderNo = getGeneralOrder();//订单号
        rr.setOrderNo(orderNo);
        String RechargeAmount = type.equals(1) ? "+" + money.doubleValue() : "-" + money.doubleValue();//充值金额
        rr.setAmount(RechargeAmount);
        rr.setOldMoney(oldMoney);//充值前余额 oldMoney
        BigDecimal balance = type.equals(1) ? oldMoney.add(money) : (oldMoney.subtract(money).signum() == -1 ? BigDecimal.ZERO : (oldMoney.subtract(money))); //充值后余额
        rr.setBalance(balance);
        rr.setUserPhone(userInfo.getPhone());//手机号
        rr.setUserName(userInfo.getUserName());//用户名称
        rr.setUserNick(userInfo.getNickName());//昵称
        rr.setUserAvatar(userInfo.getAvatar());//头像
        //充值时间ct
        rr.setCreateTime(ct);
        rr.setUpdateTime(ct);
        rr.setAccount(account);//充值人账号 account
        if(remark != null){
            rr.setRemark(remark);
        }

        rechargeRecordService.insertRechargeRecord(rr);
        //endregion

        // 发送通知
        try {
            if (type.equals(1)) {
                UserEntity userEntity = userDao.selectById(userId);
                List<String> msgList = new ArrayList<>();
                msgList.add(userEntity.getUserName());
                msgList.add(money.toString());
                msgList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                CommonInfo one = commonInfoService.findOne(424);
                SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), one.getValue(), msgList, 10);
            }
        } catch (Exception e) {
            log.error("充值成功消息发送失败：{}", e.getMessage());
        }

        return Result.success();
    }

    public String getGeneralOrder() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return format + newString;
    }

    @Override
    public Result updateUserBalance(Long userId, BigDecimal money, Integer type) {
        userMoneyDao.updateUserBalance(userId, money, type);

        //将接单明细添加到钱包明细表里
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(money);
        userMoneyDetails.setUserId(userId);
        if (type.equals(1)) {
            userMoneyDetails.setContent("赠送骑手余额：" + money + "元");
            userMoneyDetails.setTitle("系统赠送骑手余额");
        } else if (type.equals(2)) {
            userMoneyDetails.setContent("扣除骑手余额：" + money + "元");
            userMoneyDetails.setTitle("系统扣除骑手余额");
        }
        userMoneyDetails.setType(type);
        userMoneyDetails.setClassify(3);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);

        return Result.success();
    }

    @Override
    public Result updateCashDeposit(Long userId, BigDecimal money, Integer type) {
        userMoneyDao.updateCashDeposit(userId, money, type);
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(money);
        userMoneyDetails.setUserId(userId);
        if (type.equals(1)) {
            userMoneyDetails.setContent("赠送用户保证金：" + money + "元");
            userMoneyDetails.setTitle("系统赠送用户保证金");
        } else if (type.equals(2)) {
            userMoneyDetails.setContent("扣除用户保证金：" + money + "元");
            userMoneyDetails.setTitle("系统扣除用户保证金");
        }
        userMoneyDetails.setType(type);
        userMoneyDetails.setClassify(1);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);
        return Result.success();
    }

    @Override
    public void addConsumeRecord(TbOrder order) {
        //添加用户钱包消费记录
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(order.getUserId());
        if (order.getPayType() == 1) {
            userMoneyDetails.setTitle("微信支付");
            userMoneyDetails.setContent("使用微信支付：" + order.getPayMoney() + "元");
        } else {
            userMoneyDetails.setTitle("支付宝支付");
            userMoneyDetails.setContent("使用支付宝支付：" + order.getPayMoney() + "元");
        }

        userMoneyDetails.setType(2);
        userMoneyDetails.setClassify(3);
        userMoneyDetails.setState(2);
        userMoneyDetails.setMoney(order.getPayMoney());

        userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userMoneyDetailsDao.insert(userMoneyDetails);
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public UserMoneyDetails updateUserMoney(UpdateMoneyBO updateMoneyBO) {
        Long userId = updateMoneyBO.getUserId();
        UserMoney userMoney = getByUserId(userId);
        BigDecimal changeAmount = updateMoneyBO.getAmount();
        Integer changeType = updateMoneyBO.getType();
        if (changeType == 2) {
            if (userMoney.getMoney().compareTo(changeAmount) <= 0) {
                throw new SqxException("当前店铺钱包余额不足,扣减失败!");
            }
        }

        // 修改总金额
        baseMapper.updateMayMoney(updateMoneyBO.getType(), userId, changeAmount.doubleValue());

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 新增明细
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(userId);
        userMoneyDetails.setTitle(updateMoneyBO.getTitle());
        userMoneyDetails.setType(changeType);
        userMoneyDetails.setClassify(3);
        userMoneyDetails.setState(2);
        userMoneyDetails.setMoney(changeAmount);
        String changeTypeFlag = changeType == 1 ? "新增" : "减少";
        userMoneyDetails.setContent(changeTypeFlag + ":" + changeAmount +"元");
        userMoneyDetails.setRemark(updateMoneyBO.getRemark());
        userMoneyDetails.setCreateTime(sdf.format(new Date()));
        userMoneyDetailsDao.insert(userMoneyDetails);

        return userMoneyDetails;
    }

    @Override
    @Transactional
    public void splitBill(Long shopId, BigDecimal amount) {
        GoodsShop goodsShop = goodsShopService.getById(shopId);
        if (ObjectUtil.isNull(goodsShop)) {
            throw new SqxException("无效的店铺id");
        }

        String mchId = goodsShop.getMchId();
        if (StrUtil.isBlank(mchId)) {
            throw new SqxException("店铺未录入商户号");
        }

        UpdateMoneyBO updateMoneyBO = UpdateMoneyBO.builder()
                .userId(goodsShop.getUserId())
                .type(2)
                .classify(3)
                .amount(amount)
                .title("系统分账-店铺")
                .build();
        UserMoneyDetails userMoneyDetails = updateUserMoney(updateMoneyBO);

        String traceNo = IdWorker.getTimeId();
        newPayService.wechatSplitBill(traceNo, mchId, amount);

        userMoneyDetails.setRemark(traceNo);
        userMoneyDetailsService.updateById(userMoneyDetails);
    }

    @Override
    public UserMoney getByUserId(Long userId) {
        LambdaQueryWrapper<UserMoney> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserMoney::getUserId, userId);

        UserMoney userMoney = this.getOne(queryWrapper);
        if (ObjectUtil.isNull(userMoney)) {
            throw new SqxException("未查到对应用户钱包信息");
        }

        return userMoney;
    }

    /**
     * 开通成功会员后  奖励金币
     *
     * @param userId
     * @param type
     */
    public void addMoney(Long userId, Integer type) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //是否填写过邀请码
        UserEntity userEntity = userDao.selectById(userId);
        if (userEntity.getInviterCode() != null) {
            //查询填写邀请码的所属人
            UserEntity user = userDao.selectOne(new QueryWrapper<UserEntity>().eq("", userEntity.getInviterCode()));
            //创建钱包详情模板
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            //设置收益人
            userMoneyDetails.setUserId(user.getUserId());
            //设置购买人
            //       userMoneyDetails.setByUserId(userId);
            //设置类型
            //       userMoneyDetails.setClassify(2);
            //设置title
            userMoneyDetails.setTitle("购买会员");
            //设置创建时间
            userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
            //填写过邀请码
            if (type.equals(0)) {
                //月奖励1金币
                //设置奖励金币
                userMoneyDetails.setMoney(BigDecimal.valueOf(1));
                //设置内容
                userMoneyDetails.setContent("购买月会员奖励1金币");
            } else if (type.equals(1)) {
                //季奖励3金币
                //设置奖励金币
                userMoneyDetails.setMoney(BigDecimal.valueOf(3));
                //设置内容
                userMoneyDetails.setContent("购买月会员奖励1金币");
            } else {
                //年奖励10金币
                //设置奖励金币
                userMoneyDetails.setMoney(BigDecimal.valueOf(10));
                //设置内容
                userMoneyDetails.setContent("购买月会员奖励1金币");
            }
            userMoneyDetailsDao.insert(userMoneyDetails);
            //将奖励的金币添加到受益人的钱包里
            UserMoney userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("user_id", user.getUserId()));
            userMoney.setMoney(userMoney.getMoney().subtract(userMoneyDetails.getMoney()));
            baseMapper.updateById(userMoney);
            log.info("奖励成功！");
        } else {
            log.error("没有填写过邀请码 无法奖励金币");
        }
    }
}
