package com.ruoyi.xq.service.impl;

import com.alibaba.fastjson.JSON;
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.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.VipOrder;
import com.ruoyi.xq.domain.VipPrice;
import com.ruoyi.xq.dto.admin.vipOrder.VipOrderAdminVo;
import com.ruoyi.xq.dto.app.pay.ConsumeResp;
import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.enums.vip.VipTimeEnum;
import com.ruoyi.xq.enums.vip.VipTypeEnum;
import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.TraceIdManager;
import com.ruoyi.xq.mapper.VipOrderMapper;
import com.ruoyi.xq.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * VIP订单Service业务层处理
 *
 * @author 77
 * @date 2024-03-04
 */
@RequiredArgsConstructor
@Service
public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> implements VipOrderService {

    @Autowired
    private VipPriceService vipPriceService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserVipService userVipService;
    @Autowired
    private ConsumeLogService consumeLogService;

    @Override
    public VipOrder createVipOrder(Long userId, Long vipPriceSettingId) {
        VipPrice vipPrice = vipPriceService.getById(vipPriceSettingId);
        if(vipPrice == null){
            throw new ServiceException("vip价格错误");
        }
        String orderNo = OrderNoUtil.gen(OrderTypeEnum.VIP);
        User user = userService.getById(userId);
        VipOrder vipOrder = new VipOrder();
        vipOrder.setUserId(user.getId());
        vipOrder.setUsercode(user.getUsercode());
        vipOrder.setBody(vipPrice.getVipName());
        vipOrder.setVipId(vipPrice.getId());
        vipOrder.setVipType(vipPrice.getVipType());
        vipOrder.setVipTime(vipPrice.getVipTime());
        vipOrder.setVipPrice(vipPrice.getVipPrice());
        VipTimeEnum vipTimeEnum = VipTimeEnum.getByCode(vipPrice.getVipTime());
        vipOrder.setVipMonth(vipTimeEnum.getMonth());
        vipOrder.setOrderNo(orderNo);
        vipOrder.setOrderName(vipPrice.getVipName());
        vipOrder.setPayStatus(PayStatusEnum.READY_PAY.getCode());
        this.save(vipOrder);
        return vipOrder;
    }

    @Override
    public Page<VipOrderAdminVo> pageApp(PageQuery pageQuery, VipOrderAdminVo bo) {
        return baseMapper.pageApp(pageQuery.build(), bo);
    }

    @Override
    public VipOrder getByOrderNo(String orderNo){
        return this.getOne(Wrappers.lambdaQuery(VipOrder.class).eq(VipOrder::getOrderNo, orderNo).last("limit 1"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ConsumeResp doSuccess(String orderNo, Map<String, String> params, String appId, PlatformTypeEnum payTypeEnum){
        VipOrder vipOrder = this.getByOrderNo(orderNo);
        if(vipOrder == null){
            ConsumeResp resp = new ConsumeResp();
            resp.setSuccess(false);
            return resp;
        }
        String traceId = TraceIdManager.gen(TraceIdEnum.VIP);
        boolean success = this.update(Wrappers.lambdaUpdate(VipOrder.class)
                .eq(VipOrder::getId, vipOrder.getId())
                .eq(VipOrder::getPayStatus, PayStatusEnum.READY_PAY.getCode())
                .set(VipOrder::getPayStatus, PayStatusEnum.PAY.getCode())
                .set(VipOrder::getTraceId, traceId)
                .set(VipOrder::getReturnContent, JSON.toJSONString(params))
                .set(VipOrder::getAppid,appId)
                .set(VipOrder::getPlatformType, payTypeEnum.getCode()));
        if(!success){
            ConsumeResp resp = new ConsumeResp();
            resp.setSuccess(false);
            return resp;
        }
        User user = userService.getById(vipOrder.getUserId());
        userVipService.incsVip(user, vipOrder.getVipType(), vipOrder.getVipMonth());
        ConsumeLog consumeLog = new ConsumeLog();
        consumeLog.init(user);
        consumeLog.setTraceId(traceId);
        consumeLog.setType(ConsumerTypeEnum.VIP.getCode());
        consumeLog.setAmount(vipOrder.getVipPrice());
        consumeLogService.calculateInitFenxiao(consumeLog);
        if(consumeLog.getOneUserId() != null){
            consumeLogService.save(consumeLog);
        }
        ConsumeResp resp = new ConsumeResp();
        resp.setConsumerId(consumeLog.getId());
        resp.setPrice(vipOrder.getVipPrice());
        resp.setUserId(vipOrder.getUserId());
        resp.setTraceId(traceId);
        resp.setSuccess(true);
        resp.setVipId(vipOrder.getVipId());
        return resp;

    }
}
