package com.qs.mp.web.controller.api.open;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.redis.RedisCache;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.LogUtils;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.common.utils.ip.IpUtils;
import com.qs.mp.framework.redis.RedisKey;
import com.qs.mp.framework.security.handle.HostHolder;
import com.qs.mp.framework.service.IWxUrlLinkService;
import com.qs.mp.open.domain.ApiCallLog;
import com.qs.mp.open.domain.IpWhitelist;
import com.qs.mp.open.domain.param.SchemeParam;
import com.qs.mp.open.service.IApiCallLogService;
import com.qs.mp.open.service.IIpWhitelistService;
import com.qs.mp.user.domain.vo.UserShareVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
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 javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author Cup
 * @date 2022/6/1
 */
@Api(tags = "外部链接相关接口")
@RestController
@RequestMapping("/api/v1/mp/open/link")
public class LinkController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());


    @Value("${wx-user.appId}")
    private String userAppId;

    @Autowired
    private IWxUrlLinkService wxUrlLinkService;

    @Autowired
    private IIpWhitelistService ipWhitelistService;

    @Autowired
    private IApiCallLogService apiCallLogService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IChannelService channelService;

    @PostMapping("wx/scheme")
    @ApiOperation("微信小程序跳转链接")
    public AjaxResult wxScheme(@Validated @RequestBody SchemeParam schemeParam, HttpServletRequest request) {

        // 获取调用方ip
        String ipaddr = IpUtils.getIpAddr(request);
        // 白名单判断
        int whiteCount = ipWhitelistService.count(new LambdaQueryWrapper<IpWhitelist>().eq(IpWhitelist::getCallNo, schemeParam.getCallNo())
                .eq(IpWhitelist::getIpAddr, ipaddr));
        if (whiteCount <= 0) {
            LogUtil.info(logger, "调用方不在白名单,callNo:{0},ip:{1}", schemeParam.getCallNo(), ipaddr);
            return AjaxResult.error("您不在白名单中，请联系管理员");
        }

        // 保存调用日志
        ApiCallLog apiCallLog = new ApiCallLog();
        apiCallLog.setCallNo(schemeParam.getCallNo());
        apiCallLog.setIpAddr(ipaddr);
        apiCallLog.setInterfaceInfo("/api/v1/mp/open/link/wx/scheme");
        apiCallLogService.save(apiCallLog);
        LogUtil.info(logger, "微信Scheme生成调用日志:{0}", apiCallLog);

        // 构建scheme缓存key
        String key = RedisKey.build(RedisKey.OPEN_LINK_KEY, schemeParam.getCallNo(), schemeParam.getUid());
        // 从redis中获取scheme
        String scheme = redisCache.getCacheObject(key);
        if (StringUtils.isNotBlank(scheme)) {
            LogUtil.info(logger, "生成的scheme码:{0}", scheme);
            // 不为空则直接返回,不生成新的
            return AjaxResult.success("success",scheme);
        }

        Channel channel = channelService.getById(schemeParam.getCallNo());
        if (Objects.isNull(channel)) {
            LogUtil.info(logger, "非法访问,callNo:{0},ip:{1}", schemeParam.getCallNo(), ipaddr);
            return AjaxResult.error("非法访问");
        }


        if (StringUtils.isBlank(schemeParam.getBoxId())) {
            // 生成scheme,并缓存到redis中,1天过期
            scheme = wxUrlLinkService.generateUrlSchema("", "uid=" + channel.getUserId() + "&t=" + UserShareVO.SHARE_TYPE_SITE, userAppId);
        } else {
            scheme = wxUrlLinkService.generateUrlSchema("pages/ticketBox/detail", "uid=" + channel.getUserId() + "&t=" + UserShareVO.SHARE_TYPE_SITE + "&boxId=" + schemeParam.getBoxId(), userAppId);
        }

        redisCache.setCacheObject(key, scheme,1, TimeUnit.DAYS);
        LogUtil.info(logger, "生成的scheme码:{0}", scheme);
        return AjaxResult.success("success",scheme);
    }
}
