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.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.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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
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;

    @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) {
            return ResultBody.success();
        }
        userPointsDO.setTotalPoints(userPointsDO.getTotalPoints() + changePoint.getChangePoint());
        // 修改用户积分
        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) {
        //先根据积分变动id pointChangeTypeId 去找到积分变动类型信息
        UserPointChangeTypeDO userPointChangeTypeDO = userPointsDetailsDao.selectChangePoint(pointChangeTypeId);
        if(userPointChangeTypeDO == null) {
            return ResultBody.error("扣除积分类型不存在");
        }
        UserPointsDO userPointsDO = userPointsDao.selectUserPoints(userId);
        if(userPointsDO == null) {
            userPointsDO.setUserAccountId(userId);
            userPointsDO.setTotalPoints(0);
            userPointsDao.insertPoints(userPointsDO);
        }
        //用户更改完积分后如果小于0就代表积分不够 大于0就去修改数据库用户总积分
        //改变的积分
        Integer changePoint = userPointChangeTypeDO.getChangePoint();
        //改变后的用户总积分
        Integer userNowPoints =  userPointsDO.getTotalPoints() + changePoint;
        if(userNowPoints < 0) {
            return ResultBody.error("积分不足，请先去赚取积分");
        }
        userPointsDO.setTotalPoints(userNowPoints);
        userPointsDao.updatePoints(userPointsDO);
        //添加一条积分变动记录
        UserPointsDetails userPointsDetails = new UserPointsDetails(userId,changePoint,userPointChangeTypeDO.getPointSource());
        userPointsDetailsDao.insertPointsDetails(userPointsDetails);
        return ResultBody.success();
    }
}
