
package com.tmerclub.cloud.user.controller.app;

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.auth.bo.UidInfoBO;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.payment.constant.PayEntry;
import com.tmerclub.cloud.api.user.vo.UserApiVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.bo.OrderStatusBO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.user.bo.mongo.MongoPopupUserLogBO;
import com.tmerclub.cloud.user.bo.mongo.MongoUserBalanceLogBO;
import com.tmerclub.cloud.user.constant.LevelTypeEnum;
import com.tmerclub.cloud.user.constant.PopupPageTypeEnum;
import com.tmerclub.cloud.user.dto.QueryPopupDTO;
import com.tmerclub.cloud.user.model.CostPerPopup;
import com.tmerclub.cloud.user.model.UserLevelLog;
import com.tmerclub.cloud.user.service.*;
import com.tmerclub.cloud.user.vo.UserLevelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 弹窗广告
 * @author TRACK
 */
@RestController("userCostPerPopupController")
@RequestMapping("/ma/costPerPopup")
@Tag(name = "用户弹窗广告")
public class CostPerPopupController {

    @Autowired
    private CostPerPopupService costPerPopupService;
    @Autowired
    private UserService userService;
    @Autowired
    private ShopCustomerService shopCustomerService;
    @Autowired
    private PopupUserLogService popupUserLogService;
    @Autowired
    private UserLevelService userLevelService;
    @DubboReference
    private OrderFeignClient orderFeignClient;
    @Autowired
    private UserBalanceLogService userBalanceLogService;
    @Autowired
    private UserLevelLogService userLevelLogService;

    @PostMapping("/popup")
    @Operation(summary = "获取用户在当前页面的弹窗广告")
    public ServerResponseEntity<CostPerPopup> page(@RequestBody QueryPopupDTO queryPopupDTO) {
        Long userId = getUserId(queryPopupDTO.getUuid());
        // 先获取有没有符合条件的一个弹窗广告
        CostPerPopup costPerPopup = getCostPerPopup(queryPopupDTO, userId);
        if (Objects.isNull(costPerPopup)) {
            // 没有符合条件的弹窗广告直接返回
            return ServerResponseEntity.success();
        }
        if (Objects.equals(queryPopupDTO.getPageType(), PopupPageTypeEnum.PAY_SUCCESS.value())) {
            if (Objects.equals(queryPopupDTO.getPayEntry(), PayEntry.ORDER.value())) {
                List<OrderStatusBO> orderStatusBOList =
                        orderFeignClient.getOrdersStatus(Collections.singletonList(queryPopupDTO.getOrderId())).getData();
                if (CollUtil.isEmpty(orderStatusBOList) || OrderStatus.unPay(orderStatusBOList.get(0).getStatus())) {
                    // 没有支付成功不记录弹窗广告
                    return ServerResponseEntity.success();
                }
            }
            else if (Objects.equals(queryPopupDTO.getPayEntry(), PayEntry.RECHARGE.value())) {
                MongoUserBalanceLogBO userBalanceLogBO = userBalanceLogService.getByBalanceLogId(queryPopupDTO.getOrderId());
                if (Objects.isNull(userBalanceLogBO) || Objects.equals(userBalanceLogBO.getIsPayed(), 0)) {
                    // 没有支付成功不记录弹窗广告
                    return ServerResponseEntity.success();
                }
            }
            else if (Objects.equals(queryPopupDTO.getPayEntry(), PayEntry.VIP.value())) {
                UserLevelLog userLevelLog = userLevelLogService.getByLevelLogId(queryPopupDTO.getOrderId());
                if (Objects.isNull(userLevelLog) || Objects.equals(userLevelLog.getIsPayed(), 0)) {
                    // 没有支付成功不记录弹窗广告
                    return ServerResponseEntity.success();
                }
            }
        }
        // 最后保存弹窗广告记录
        popupUserLogService.save(new MongoPopupUserLogBO(costPerPopup.getPopupId(), userId, queryPopupDTO.getUuid()));
        return ServerResponseEntity.success(costPerPopup);
    }

    private CostPerPopup getCostPerPopup(QueryPopupDTO queryPopupDTO, Long userId) {
        Long uuid = queryPopupDTO.getUuid();
        Integer pageType = queryPopupDTO.getPageType();
        Long shopId = queryPopupDTO.getShopId();
        CostPerPopup costPerPopup;
        if (PopupPageTypeEnum.isSys(pageType)) {
            // 平台弹窗
            UserApiVO userApiVO = getUserApiVO(userId);
            costPerPopup = costPerPopupService.getSysPopupByCondition(userApiVO, pageType, uuid);
        } else {
            // 商家弹窗
            Integer isShopCustomer = Objects.nonNull(userId) ? shopCustomerService.getIsShopCustomer(shopId, userId) : 0;
            costPerPopup = costPerPopupService.getShopPopupByCondition(isShopCustomer, pageType, queryPopupDTO.getSpuId(), shopId, userId, uuid);
        }
        return costPerPopup;
    }

    private static Long getUserId(Long uuid) {
        UidInfoBO uidInfoBO = AuthUserContext.get();
        Long userId = null;
        if (Objects.nonNull(uidInfoBO)) {
            userId = uidInfoBO.getUserId();
        } else if (Objects.isNull(uuid)){
            throw new LuckException("uuid不能为空");
        }
        return userId;
    }

    private UserApiVO getUserApiVO(Long userId) {
        UserApiVO userApiVO = new UserApiVO();
        if (Objects.nonNull(userId)) {
            userApiVO = userService.getByUserId(userId);
            UserLevelVO ordinary = userLevelService.getOneByTypeAndLevel(LevelTypeEnum.ORDINARY_USER.value(), userApiVO.getLevel());
            userApiVO.setUserLevelId(ordinary.getUserLevelId());
            if (Objects.equals(userApiVO.getLevelType(), LevelTypeEnum.PAY_USER.value()) && Objects.nonNull(userApiVO.getVipLevel())) {
                UserLevelVO vip = userLevelService.getOneByTypeAndLevel(LevelTypeEnum.PAY_USER.value(), userApiVO.getVipLevel());
                userApiVO.setVipUserLevelId(vip.getUserLevelId());
            }
        }
        return userApiVO;
    }
}
