package com.mmc.iuav.user.service.userpoints.impl;

import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.user.controller.userpoints.config.UserPointsEnum;
import com.mmc.iuav.user.dao.userpoints.UserPointsDao;
import com.mmc.iuav.user.dao.userpoints.UserPointsDetailsDao;
import com.mmc.iuav.user.entity.userpoints.UserPointChangeTypeDO;
import com.mmc.iuav.user.entity.userpoints.UserPointsDO;
import com.mmc.iuav.user.entity.userpoints.UserPointsDetails;
import com.mmc.iuav.user.feign.PaymentAppApi;
import com.mmc.iuav.user.model.dto.userpoints.UserPointsDTO;
import com.mmc.iuav.user.model.dto.userpoints.UserPointsDetailsDTO;
import com.mmc.iuav.user.model.qo.userpoints.AppPointsDetailsQO;
import com.mmc.iuav.user.model.qo.userpoints.UserPointQO;
import com.mmc.iuav.user.model.qo.userpoints.UserPointsDetailsQO;
import com.mmc.iuav.user.model.vo.BuyPointsVO;
import com.mmc.iuav.user.model.vo.OrderRequestParamsVO;
import com.mmc.iuav.user.model.vo.userpoints.ChangeUserPointVO;
import com.mmc.iuav.user.model.vo.userpoints.PointTypeVO;
import com.mmc.iuav.user.service.userpoints.UserPointsService;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author small
 * @Date 2023/8/5 16:31
 * @Version 1.0
 */
@Service
public class UserPointsServiceImpl implements UserPointsService {

    @Autowired
    private UserPointsDao userPointsDao;

    @Autowired
    private UserPointsDetailsDao userPointsDetailsDao;

    @Qualifier("com.mmc.iuav.user.feign.PaymentAppApi")
    @Autowired
    private PaymentAppApi paymentAppApi;

    @Override
    public PageResult userPointList(UserPointQO param) {
        int count = userPointsDao.count(param);
        if (count == 0) {
            return PageResult.buildPage(param.getPageNo(), param.getPageSize(), count);
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        List<UserPointsDO> userPointList = userPointsDao.userPointList(param);
        List<UserPointsDTO> collect = userPointList.stream().map(UserPointsDO::buildUserPointsDTO).collect(Collectors.toList());
        return PageResult.buildPage(pageNo, param.getPageSize(), count, collect);

    }

    @Override
    public PageResult detailPoint(UserPointsDetailsQO param) {
        int count = userPointsDetailsDao.detailPointCount(param);
        if (count == 0) {
            return PageResult.buildPage(param.getPageNo(), param.getPageSize(), count);
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        List<UserPointsDetails> userPointsDetails = userPointsDetailsDao.detailPoint(param);
        List<UserPointsDetailsDTO> collect = userPointsDetails.stream().map(UserPointsDetails::buildPoint).collect(Collectors.toList());
        return PageResult.buildPage(pageNo, param.getPageSize(), count, collect);
    }

    @Override
    public PageResult appDetailPoint(Integer userAccountId, AppPointsDetailsQO param) {
        param.setUserAccountId(userAccountId);
        int count = userPointsDetailsDao.appDetailPointCount(param);
        if (count == 0) {
            return PageResult.buildPage(param.getPageNo(), param.getPageSize(), count);
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        List<UserPointsDetails> userPointsDetails = userPointsDetailsDao.appDetailPoint(param);
        List<UserPointsDetailsDTO> collect = userPointsDetails.stream().map(UserPointsDetails::buildPoint).collect(Collectors.toList());
        return PageResult.buildPage(pageNo, param.getPageSize(), count, collect);
    }

    @Transactional
    @Override
    public ResultBody change(ChangeUserPointVO changePoint) {
        UserPointsDO userPointsDO = userPointsDao.selectUserPoints(changePoint.getUserAccountId());
        //如果邀请人没有绑定手机号 是没有积分的
        if (userPointsDO == null) {
            userPointsDO = new UserPointsDO();
            userPointsDO.setUserAccountId(changePoint.getUserAccountId());
            userPointsDO.setTotalPoints(0);
            userPointsDao.insertPoints(userPointsDO);
        }
        //改变后的用户总积分
        Integer userNowPoints =  userPointsDO.getTotalPoints() + changePoint.getChangePoint();
        if(userNowPoints < 0) {
            return ResultBody.error("积分不足，请先去赚取积分");
        }
        userPointsDO.setTotalPoints(userNowPoints);
        // 修改用户积分
        userPointsDao.updatePoints(userPointsDO);
        // 添加记录
        UserPointsDetails userPointsDetails = new UserPointsDetails();
        userPointsDetails.setUserAccountId(changePoint.getUserAccountId());
        userPointsDetails.setPoint(changePoint.getChangePoint());
        // 根据不同变动
        userPointsDetails.setPointSource(UserPointsEnum.match(changePoint.getChangeType()).getMessage());
        userPointsDetailsDao.insertPointsDetails(userPointsDetails);
        return ResultBody.success();
    }

    @Override
    public ResultBody listChangeType() {
        List<PointTypeVO> types = new ArrayList<PointTypeVO>();
        for (UserPointsEnum pointsEnum : UserPointsEnum.values()) {
            PointTypeVO pointTypeVO = new PointTypeVO();
            pointTypeVO.setCode(pointsEnum.getCode());
            pointTypeVO.setMessage(pointsEnum.getMessage());
            types.add(pointTypeVO);
        }
        return ResultBody.success(types);
    }

    @Override
    public ResultBody changeUserPoints(Integer userId, Integer pointChangeTypeId,int changePoint,String reason) {
        //先根据积分变动id pointChangeTypeId 去找到积分变动类型信息
        if(pointChangeTypeId != null) {
            UserPointChangeTypeDO userPointChangeTypeDO = userPointsDetailsDao.selectChangePoint(pointChangeTypeId);
            if (userPointChangeTypeDO == null) {
                return ResultBody.error("扣除积分类型不存在");
            }
            //用户更改完积分后如果小于0就代表积分不够 大于0就去修改数据库用户总积分
            //改变的积分
            changePoint = userPointChangeTypeDO.getChangePoint();
            //改变积分的原因
            reason = userPointChangeTypeDO.getPointSource();
        }
        UserPointsDO userPointsDO = userPointsDao.selectUserPoints(userId);
        if (userPointsDO == null) {
            userPointsDO = new UserPointsDO();
            userPointsDO.setUserAccountId(userId);
            userPointsDO.setTotalPoints(0);
            userPointsDao.insertPoints(userPointsDO);
        }
        //改变后的用户总积分
        Integer userNowPoints =  userPointsDO.getTotalPoints() + changePoint;
        if(userNowPoints < 0) {
            return ResultBody.error("积分不足，请先去赚取积分");
        }
        userPointsDO.setTotalPoints(userNowPoints);
        userPointsDao.updatePoints(userPointsDO);

        //添加一条积分变动记录
        UserPointsDetails userPointsDetails = new UserPointsDetails(userId,changePoint,reason);
        userPointsDetailsDao.insertPointsDetails(userPointsDetails);
        return ResultBody.success();
    }

    @Override
    public ResultBody weixinBuyPoints(BuyPointsVO buyPointsVO, Integer userAccountId,String token) {
        if(buyPointsVO.getId() == null){
            return ResultBody.error("购买积分类型不能传递为空");
        }
        BuyPointsVO buyPointsVO1 = userPointsDao.selectBuyPointsType(buyPointsVO.getId());
        OrderRequestParamsVO orderRequestParamsVO = new OrderRequestParamsVO();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String content = "WP" + sdf.format(new Date());
        orderRequestParamsVO.setOrderNo(content);
        orderRequestParamsVO.setDescription("购买积分");
        BigDecimal money = buyPointsVO1.getMoney();
        BigDecimal amountInFen = money.multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN);
        orderRequestParamsVO.setAmount(amountInFen.intValue());
        orderRequestParamsVO.setOrderPort(4);
        // 扣除金额
        Map map = paymentAppApi.orderPay(orderRequestParamsVO, token);
        // 增加积分
        ChangeUserPointVO changeUserPointVO = new ChangeUserPointVO();
        changeUserPointVO.setUserAccountId(userAccountId);
        changeUserPointVO.setChangePoint(buyPointsVO1.getPoints());
        changeUserPointVO.setChangeType(9);
        ResultBody change = change(changeUserPointVO);
        return change;
    }

    @Override
    public ResultBody insertBuyPointsType(BuyPointsVO buyPointsVO) {
        userPointsDao.insertBuyPointsType(buyPointsVO);
        return ResultBody.success();
    }

    @Override
    public ResultBody updateBuyPointsType(BuyPointsVO buyPointsVO) {
        userPointsDao.updateBuyPointsType(buyPointsVO);
        return ResultBody.success();
    }

    @Override
    public ResultBody selectAllBuyPointsType() {
        List<BuyPointsVO> buyPointsVOS = userPointsDao.selectAllBuyPointsType();
        return ResultBody.success(buyPointsVOS);
    }
}
