package cn.iocoder.yudao.module.member.service.user;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberPointsPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberPointsRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.*;
import cn.iocoder.yudao.module.member.dal.mysql.user.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.Date;
import java.util.List;


/**
 * 会员用户积分 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class MemberPointsServiceImpl implements MemberPointsService {

    @Resource
    private MemberPointsMapper pointsMapper;
    @Resource
    private MemberBonusPointsMapper memberBonusPointsMapper;
    @Resource
    private MemberPointsExchangeMapper pointsExchangeMapper;
    @Resource
    private MemberPointsItemMapper memberPointsItemMapper;

    @Resource
    private MemberPointsResetConfigMapper memberPointsResetConfigMapper;

    @Resource
    private MemberPointsConfigMapper memberPointsConfigMapper;


    @Override
    public PageResult<MemberPointsDO> getMemberPointsPage(MemberPointsPageReqVO pageReqVO) {
        return pointsMapper.selectPage(pageReqVO);
    }

    @Override
    public void bonusPoints(MemberBonusPointsDO bonusPointsDO) {
        bonusPointsDO.setCreatedTime(new Date());
        bonusPointsDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        memberBonusPointsMapper.insert(bonusPointsDO);

        MemberPointsDO memberPoints = pointsMapper.selectOne(new LambdaQueryWrapperX<MemberPointsDO>()
                .eq(MemberPointsDO::getMemberUserId, bonusPointsDO.getMemberUserId()));
        Integer points = bonusPointsDO.getPoints();
        memberPoints.setAccumulatedPoints(memberPoints.getAccumulatedPoints() + points);
        memberPoints.setRemainingPoints(memberPoints.getRemainingPoints() + points);
        pointsMapper.updateById(memberPoints);
    }

    @Override
    public void exchangePointsItem(MemberPointsExchangeDO memberPointsExchangeDO) {
        memberPointsExchangeDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        memberPointsExchangeDO.setCreatedTime(new Date());
        pointsExchangeMapper.insert(memberPointsExchangeDO);

        MemberPointsDO memberPoints = pointsMapper.selectOne(new LambdaQueryWrapperX<MemberPointsDO>()
                .eq(MemberPointsDO::getMemberUserId, memberPointsExchangeDO.getMemberUserId()));

        Integer points = memberPointsExchangeDO.getPoints();
        memberPoints.setRedeemPoints(memberPoints.getRedeemPoints() + points);
        memberPoints.setRemainingPoints(memberPoints.getRemainingPoints() - points);
        pointsMapper.updateById(memberPoints);
    }

    @Override
    public MemberPointsRespVO getDetail(Long id) {
        MemberPointsRespVO respVO = new MemberPointsRespVO();
        MemberPointsDO memberPoints = pointsMapper.selectById(id);
        BeanUtils.copyProperties(memberPoints, respVO);

        List<MemberPointsExchangeDO> memberPointsExchanges = pointsExchangeMapper.selectList(new LambdaQueryWrapperX<MemberPointsExchangeDO>()
                .eq(MemberPointsExchangeDO::getMemberUserId, memberPoints.getMemberUserId()));

        List<MemberBonusPointsDO> memberBonusPoints = memberBonusPointsMapper.selectList(new LambdaQueryWrapperX<MemberBonusPointsDO>()
                .eq(MemberBonusPointsDO::getMemberUserId, memberPoints.getMemberUserId()));

        respVO.setBonusPointsRecord(memberBonusPoints);
        respVO.setExchangePointsRecord(memberPointsExchanges);
        return respVO;
    }

    @Override
    public void settingPointsItems(List<MemberPointsItemDO> items) {
        for (MemberPointsItemDO item : items) {
            item.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
            item.setCreatedTime(new Date());
            memberPointsItemMapper.insert(item);
        }
    }

    @Override
    public void addMemberPointsResetConfig(MemberPointsResetConfigDO resetConfigDO) {
        resetConfigDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        resetConfigDO.setCreatedTime(new Date());
        memberPointsResetConfigMapper.insert(resetConfigDO);
    }

    @Override
    public void editMemberPointsResetConfig(MemberPointsResetConfigDO resetConfigDO) {
        memberPointsResetConfigMapper.updateById(resetConfigDO);
    }

    @Override
    public MemberPointsResetConfigDO getMemberPointsResetConfig(Integer orgType, Long tenantId) {
        return memberPointsResetConfigMapper.selectList(new LambdaQueryWrapperX<MemberPointsResetConfigDO>()
                        .eqIfPresent(MemberPointsResetConfigDO::getOrgType, orgType)
                        .eqIfPresent(MemberPointsResetConfigDO::getTenantId, tenantId))
                        .stream()
                        .findFirst()
                        .get();
    }

    @Override
    public void updateMemberPointsConfig(MemberPointsConfigDO pointsConfigDO) {
        memberPointsConfigMapper.updateById(pointsConfigDO);
    }

    @Override
    public List<MemberPointsConfigDO> getMemberPointsConfigList(Integer orgType, Long tenantId) {
        return memberPointsConfigMapper.selectList(new LambdaQueryWrapperX<MemberPointsConfigDO>()
                .eqIfPresent(MemberPointsConfigDO::getOrgType,orgType)
                .eqIfPresent(MemberPointsConfigDO::getTenantId,tenantId));
    }

    @Override
    public List<MemberPointsItemDO> getPointsItems(Integer orgType, Long tenantId) {
        return memberPointsItemMapper
                .selectList(new LambdaQueryWrapperX<MemberPointsItemDO>()
                        .eqIfPresent(MemberPointsItemDO::getOrgType, orgType)
                        .eqIfPresent(MemberPointsItemDO::getTenantId,tenantId));
    }
}