package com.zanxiang.game.module.manage.service.impl;

import cn.hutool.http.ContentType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.erp.base.ErpServer;
import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
import com.zanxiang.game.module.manage.service.IGameService;
import com.zanxiang.game.module.manage.service.IListenCallService;
import com.zanxiang.game.module.mybatis.entity.Game;
import com.zanxiang.game.module.mybatis.entity.ListenCall;
import com.zanxiang.game.module.mybatis.mapper.ListenCallMapper;
import com.zanxiang.module.redis.service.IDistributedLockComponent;
import com.zanxiang.module.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2024-01-16
 * @description : 监听呼叫
 */
@Slf4j
@Service
public class ListenCallServiceImpl extends ServiceImpl<ListenCallMapper, ListenCall> implements IListenCallService {

    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private IDingTalkMsgRpc dingTalkMsgRpc;

    @Autowired
    private IDistributedLockComponent distributedLockComponent;

    @Autowired
    private IGameService gameService;

    @Override
    public void sendDingTalkMsg(Long gameId, boolean isSuper, String content) {
        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
        if (CollectionUtils.isEmpty(listenCallList)) {
            return;
        }
        Set<Long> userIdSet = listenCallList.stream()
                .filter(listenCall -> Strings.isNotBlank(listenCall.getDingTalkNum()))
                .map(ListenCall::getUserId).collect(Collectors.toSet());
        userIdSet.forEach(userId -> dingTalkMsgRpc.sendByUserId(userId, content));
    }

    @Override
    public void sendPhoneTalkMsg(Long gameId, boolean isSuper, String listenName) {
        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
        if (CollectionUtils.isEmpty(listenCallList)) {
            return;
        }
        String content = listenName + "监测异常";
        Set<String> phoneNumSet = listenCallList.stream()
                .filter(listenCall -> Strings.isNotBlank(listenCall.getPhoneNum()))
                .map(ListenCall::getPhoneNum).collect(Collectors.toSet());
        phoneNumSet.forEach(phoneNum -> {
            String lockKey = RedisKeyConstant.PHONE_CALL_LOCK + phoneNum;
            if (!distributedLockComponent.doLock(lockKey, 0L, 1L, TimeUnit.MINUTES)) {
                return;
            }
            this.phoneCall(content, phoneNum);
        });
    }

    private List<ListenCall> callListenUser(Long gameId, boolean isSuper) {
        List<Long> gameIdList = new ArrayList<>();
        if (isSuper) {
            gameIdList = gameService.list(new LambdaQueryWrapper<Game>()
                    .eq(Game::getSuperGameId, gameId)
            ).stream().map(Game::getId).collect(Collectors.toList());
        }
        List<ListenCall> listenCallList = super.list(new LambdaQueryWrapper<ListenCall>()
                .eq(!isSuper, ListenCall::getGameId, gameId)
                .in(isSuper && CollectionUtils.isNotEmpty(gameIdList), ListenCall::getGameId, gameIdList)
                .eq(ListenCall::getStatus, StatusEnum.YES.getCode()));
        if (CollectionUtils.isEmpty(listenCallList)) {
            return Collections.emptyList();
        }
        Collection<ListenCall> collection = listenCallList.stream()
                .collect(Collectors.toMap(ListenCall::getUserId, Function.identity(), (existing, replacement) -> existing))
                .values();
        return new ArrayList<>(collection);
    }

    private void phoneCall(String param, String mobile) {
        RestTemplate restTemplate = new RestTemplate();
        String appCode = "f395b1587fc04a49a975f908660fb1e9";
        String host = "https://jumfixed.market.alicloudapi.com/voice-notify/send";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "APPCODE " + appCode);
        headers.set("Content-Type", ContentType.FORM_URLENCODED.getValue());
        //参数
        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
        requestParams.add("mobile", mobile);
        requestParams.add("templateId", "JMJNAWUQOJP9");
        requestParams.add("param", param);
        String result = null;
        try {
            ResponseEntity<String> responseEntity = restTemplate.exchange(host, HttpMethod.POST,
                    new HttpEntity<>(requestParams, headers), String.class);
            result = responseEntity.getBody();
        } catch (Exception e) {
            log.error("阿里语音呼叫失败, requestParams : {}, e : {}", JsonUtil.toString(requestParams), e.getMessage());
        }
        log.error("阿里语音呼叫结果, result : {}", result);
    }
}
