package cn.newfeifan.mall.module.distri.service.usertopupconsumptionpointsorder;

import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
import cn.newfeifan.mall.module.distri.controller.admin.integralchangelog.vo.IntegralChangeLogSaveReqVO;
import cn.newfeifan.mall.module.distri.controller.admin.integral.vo.IntegralSaveReqVO;
import cn.newfeifan.mall.module.distri.controller.admin.usertopupconsumptionpointsorder.vo.*;
import cn.newfeifan.mall.module.distri.dal.dataobject.integral.IntegralDO;
import cn.newfeifan.mall.module.distri.dal.dataobject.usertopupconsumptionpointsorder.UserTopUpConsumptionPointsOrderDO;
import cn.newfeifan.mall.module.distri.dal.mysql.usertopupconsumptionpointsorder.UserTopUpConsumptionPointsOrderMapper;
import cn.newfeifan.mall.module.distri.enums.IntegralEnum;
import cn.newfeifan.mall.module.distri.service.integralchangelog.IntegralChangeLogService;
import cn.newfeifan.mall.module.distri.service.integral.IntegralService;
import cn.newfeifan.mall.module.pay.dal.dataobject.order.PayOrderDO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.module.distri.enums.ErrorCodeConstants.USER_TOP_UP_CONSUMPTION_POINTS_ORDER_NOT_EXISTS;

/**
 * 用户充值消费分订单 Service 实现类
 *
 * @author 非繁人
 */
@Service
@Validated
public class UserTopUpConsumptionPointsOrderServiceImpl implements UserTopUpConsumptionPointsOrderService {

    @Resource
    private UserTopUpConsumptionPointsOrderMapper userTopUpConsumptionPointsOrderMapper;
    @Resource
    private IntegralService integralService;
    @Resource
    private IntegralChangeLogService integralChangeLogService;

    @Override
    public Long createUserTopUpConsumptionPointsOrder(UserTopUpConsumptionPointsOrderSaveReqVO createReqVO) {
        // 插入
        UserTopUpConsumptionPointsOrderDO userTopUpConsumptionPointsOrder = BeanUtils.toBean(createReqVO, UserTopUpConsumptionPointsOrderDO.class);
        userTopUpConsumptionPointsOrderMapper.insert(userTopUpConsumptionPointsOrder);
        // 返回
        return userTopUpConsumptionPointsOrder.getId();
    }

    @Override
    public void updateUserTopUpConsumptionPointsOrder(UserTopUpConsumptionPointsOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateUserTopUpConsumptionPointsOrderExists(updateReqVO.getId());
        // 更新
        UserTopUpConsumptionPointsOrderDO updateObj = BeanUtils.toBean(updateReqVO, UserTopUpConsumptionPointsOrderDO.class);
        userTopUpConsumptionPointsOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserTopUpConsumptionPointsOrder(Long id) {
        // 校验存在
        validateUserTopUpConsumptionPointsOrderExists(id);
        // 删除
        userTopUpConsumptionPointsOrderMapper.deleteById(id);
    }

    private void validateUserTopUpConsumptionPointsOrderExists(Long id) {
        if (userTopUpConsumptionPointsOrderMapper.selectById(id) == null) {
            throw exception(USER_TOP_UP_CONSUMPTION_POINTS_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public UserTopUpConsumptionPointsOrderDO getUserTopUpConsumptionPointsOrder(Long id) {
        return userTopUpConsumptionPointsOrderMapper.selectById(id);
    }

    @Override
    public PageResult<UserTopUpConsumptionPointsOrderDO> getUserTopUpConsumptionPointsOrderPage(UserTopUpConsumptionPointsOrderPageReqVO pageReqVO) {
        pageReqVO.setPayStatus(true);
        return userTopUpConsumptionPointsOrderMapper.selectPage(pageReqVO);
    }

    @Override
    public void topUpConsumptionPoints(PayOrderDO payOrderDO) {
        UserTopUpConsumptionPointsOrderDO topUpOrder = userTopUpConsumptionPointsOrderMapper.selectById(payOrderDO.getMerchantOrderId());

        if(topUpOrder.getPayStatus()){
            return;
        }

        // 修改订单状态
        userTopUpConsumptionPointsOrderMapper.updateById(UserTopUpConsumptionPointsOrderDO.builder()
                .id(topUpOrder.getId())
                .payStatus(true)
                .payTime(LocalDateTime.now())
                .payChannelCode(payOrderDO.getChannelCode())
                .finishTime(LocalDateTime.now())
                .build());

        // 获取钱包
        IntegralDO integralDO = integralService.selectByUser(topUpOrder.getUserId());
        integralDO.setConsumptionPoints(integralDO.getConsumptionPoints() + topUpOrder.getPracticalConsumptionPoints());
        integralService.updateIntegral(BeanUtils.toBean(integralDO, IntegralSaveReqVO.class));

        // 消费分变动日志
        integralChangeLogService.createConsumptionChangeLog(IntegralChangeLogSaveReqVO.builder()
                .userId(topUpOrder.getUserId())
                .integralStatus(IntegralEnum.TOP_UP_GET.getType())
                .integralPoints(topUpOrder.getPracticalConsumptionPoints())
                .afterIntegralPoints(integralDO.getConsumptionPoints())
                .practicalIntegralPoints(topUpOrder.getTopUpConsumptionPoints())
                .generateUserId(topUpOrder.getUserId())
                .build());
    }

    @Override
    public List<UserTopUpConsumptionPointsOrderDO> getUserTopUpConsumptionPointsOrderList() {
        return userTopUpConsumptionPointsOrderMapper.selectList(UserTopUpConsumptionPointsOrderDO::getPayStatus,true);
    }

}