package cn.ysk.cashier.utils;

import cn.ysk.cashier.enums.ShopWxMsgTypeEnum;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper;
import cn.ysk.cashier.mybatis.mapper.TbShopOpenIdMapper;
import cn.ysk.cashier.mybatis.service.TbShopMsgStateService;
import cn.ysk.cashier.mybatis.service.TbShopOpenIdService;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.function.Consumer;

@Component
@Slf4j
public class WxMsgUtils {

    private final TbShopOpenIdService tbShopOpenIdService;

    private final RedisUtils redisUtils;

    private final WxAccountUtil wxAccountUtil;
    private final TbShopMsgStateService shopMsgStateService;
    private final TbShopMsgStateMapper shopMsgStateMapper;
    private final TbShopOpenIdMapper shopOpenIdMapper;
    private final TbShopInfoRepository shopInfoRepository;

    public WxMsgUtils(TbShopOpenIdService tbShopOpenIdService, RedisUtils redisUtils, WxAccountUtil wxAccountUtil, TbShopMsgStateService shopMsgStateService, TbShopMsgStateMapper shopMsgStateMapper, TbShopOpenIdMapper shopOpenIdMapper, TbShopInfoRepository shopInfoRepository) {
        this.tbShopOpenIdService = tbShopOpenIdService;
        this.redisUtils = redisUtils;
        this.wxAccountUtil = wxAccountUtil;
        this.shopMsgStateService = shopMsgStateService;
        this.shopMsgStateMapper = shopMsgStateMapper;
        this.shopOpenIdMapper = shopOpenIdMapper;
        this.shopInfoRepository = shopInfoRepository;
    }

    public boolean checkIsOpen(Integer shopId, ShopWxMsgTypeEnum shopWxMsgTypeEnum) {
        TbShopMsgState allState = shopMsgStateMapper.selectOne(new LambdaQueryWrapper<TbShopMsgState>()
                .eq(TbShopMsgState::getShopId, shopId)
                .eq(TbShopMsgState::getState, 1)
                .eq(TbShopMsgState::getType, ShopWxMsgTypeEnum.ALL_MSG.getType()));
        if (allState == null) {
            log.warn("店铺全局推送开关未开启");
            return false;
        }

        TbShopMsgState currentState = shopMsgStateMapper.selectOne(new LambdaQueryWrapper<TbShopMsgState>()
                .eq(TbShopMsgState::getShopId, shopId)
                .eq(TbShopMsgState::getState, 1)
                .eq(TbShopMsgState::getType, shopWxMsgTypeEnum.getType()));
        if (currentState == null) {
            log.warn("当前推送未开启: {}", shopWxMsgTypeEnum);
            return false;
        }
        return true;
    }

    public void aboardOperationMsg(String operationDesc, Integer shopId1) {
        if (!checkIsOpen(shopId1, ShopWxMsgTypeEnum.OPERATION_MSG)) {
            return;
        }

        HttpServletRequest request = RequestHolder.getHttpServletRequest();

        Object o = redisUtils.get("online-token-"+getToken(request));
        JSONObject jsonObject;
        Integer shopId;
        String nickName;
        if (o != null) {
            String jsonString = JSON.toJSONString(o);
            jsonObject = JSONObject.parseObject(jsonString);
            shopId = (Integer) jsonObject.get("shopId");
            nickName = jsonObject.get("nickName") == null ? "" : jsonObject.get("nickName").toString();
            List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery()
                    .eq(TbShopOpenId::getShopId, shopId)
                    .eq(TbShopOpenId::getStatus, 1)
                    .and((queryWrapper) -> queryWrapper.eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.ALL_MSG.getType())
                            .or().eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.OPERATION_MSG.getType()))
                    .groupBy(TbShopOpenId::getOpenId)
                    .list();
            log.info("即将开始推送敏感操作消息, 接收推送openId列表: {}", openIds);
            String finalNickName = nickName;
            wxAccountUtil.sendOperationMsg(openIds, finalNickName, operationDesc);
        }else {
            log.warn("发送敏感操作预警失败，未获取到登录信息");
        }
    }

    public void aboardStockMsg(String shopName, Integer shopId, String proName, Integer stock) {
        if (!checkIsOpen(shopId, ShopWxMsgTypeEnum.OPERATION_MSG)) {
            return;
        }
        
        List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery()
                .eq(TbShopOpenId::getShopId, shopId)
                .eq(TbShopOpenId::getStatus, 1)
                .and((queryWrapper) -> queryWrapper.eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.ALL_MSG.getType())
                        .or().eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.STOCK_MSG.getType()))
                .groupBy(TbShopOpenId::getOpenId)
                .list();
        log.info("即将开始推送敏感操作消息, 接收推送openId列表: {}", openIds);
        openIds.parallelStream().forEach(item -> {
            wxAccountUtil.sendStockMsg(shopName, proName, stock, item.getOpenId(), ShopWxMsgTypeEnum.STOCK_MSG, shopId);
        });
    }

    public String getToken(HttpServletRequest request) {
        final String requestHeader = request.getHeader("Authorization");
        if (requestHeader != null && requestHeader.startsWith("Bearer")) {
            return requestHeader.substring(7);
        }
        return null;
    }
}
