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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zanxiang.erp.security.util.SecurityUtil;
import com.zanxiang.game.module.manage.enums.KfActionEnum;
import com.zanxiang.game.module.manage.enums.KfApiEnum;
import com.zanxiang.game.module.manage.pojo.dto.KfMsgResultDTO;
import com.zanxiang.game.module.manage.pojo.params.KfApiParam;
import com.zanxiang.game.module.manage.pojo.vo.KfGameVO;
import com.zanxiang.game.module.manage.service.IGameAppletService;
import com.zanxiang.game.module.manage.service.IGameAuthService;
import com.zanxiang.game.module.manage.service.IKfMsgService;
import com.zanxiang.game.module.manage.service.IKfUserService;
import com.zanxiang.game.module.mybatis.entity.GameApplet;
import com.zanxiang.game.module.mybatis.entity.GameAuth;
import com.zanxiang.game.module.mybatis.entity.KfUser;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.URIUtil;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2023-11-27
 * @description : 客服消息
 */
@Slf4j
@Service
public class KfMsgServiceImpl implements IKfMsgService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IKfUserService kfUserService;

    @Autowired
    private IGameAuthService gameAuthService;

    @Autowired
    private IGameAppletService gameAppletService;

    @Override
    public Tuple2<String, String> uploadMsg(KfApiParam param, MultipartFile files) {
        //查询用户授权信息
        KfUser kfUser = kfUserService.getKfUser(SecurityUtil.getUserId(), param.getAppId());
        //图片上传腾讯
        String uploadResult = this.imgUploadApi(kfUser, files);
        Map<String, Object> uploadResultMap = JsonUtil.toMap(uploadResult, Map.class, Object.class);
        //发送客服消息
        Map<String, Object> paramMap = param.getParam();
        paramMap.put("msg_content", uploadResult);
        paramMap.put("msg_id", uploadResultMap.get("msg_id"));
        //腾讯api
        String apiResult = this.commKfApi(kfUser, param.getAction().getValue(), KfApiEnum.getApiUrl(param.getAction()), paramMap);
        //返回图片上传结果和消息发送结果
        return Tuples.of(uploadResult, apiResult);
    }

    private String imgUploadApi(KfUser kfUser, MultipartFile files) {
        //请求地址
        URI uri = UriComponentsBuilder.fromHttpUrl(KfApiEnum.UPLOAD_MSG.getApiUrl())
                .queryParam("action", KfActionEnum.UPLOAD_PIC_MSG.getValue())
                .queryParam("token", kfUser.getToken())
                .queryParam("lang", "zh_CN")
                .build().toUri();
        //最外层请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        httpHeaders.add("cookie", kfUser.getCookie());
        LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        //文件内容请求头
        HttpHeaders formHeader = new HttpHeaders();
        formHeader.setContentType(MediaType.MULTIPART_FORM_DATA);
        formHeader.setContentDispositionFormData("image", files.getOriginalFilename());
        HttpEntity<Resource> formEntity = new HttpEntity<>(files.getResource(), formHeader);
        map.add("image", formEntity);
        //http请求头
        HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, httpHeaders);
        Object result;
        try {
            result = restTemplate.postForObject(uri, httpEntity, Object.class);
        } catch (Exception e) {
            log.error("腾讯上传图片接口调用异常, uri : {}, e : {}", uri, e.getMessage());
            throw new BaseException("腾讯上传图片接口调用异常!");
        }
        return JsonUtil.toString(result);
    }

    @Override
    public List<KfGameVO> getKfGameList() {
        List<GameAuth> gameAuthList = gameAuthService.list(new LambdaQueryWrapper<GameAuth>()
                .eq(!SecurityUtil.isAdmin(), GameAuth::getUserId, SecurityUtil.getUserId()));
        if (!SecurityUtil.isAdmin() && CollectionUtils.isEmpty(gameAuthList)) {
            return Collections.emptyList();
        }
        return gameAppletService.list(new LambdaQueryWrapper<GameApplet>()
                .eq(GameApplet::getType, 1)
                .eq(GameApplet::getKfNew, Boolean.FALSE)
                .in(!SecurityUtil.isAdmin(), GameApplet::getGameId,
                        gameAuthList.stream().map(GameAuth::getGameId).collect(Collectors.toSet()))
        ).stream().map(this::toVO).collect(Collectors.toList());
    }

    private KfGameVO toVO(GameApplet gameApplet) {
        KfGameVO kfGameVO = BeanUtil.copy(gameApplet, KfGameVO.class);
        if (kfGameVO == null) {
            return null;
        }
        //判断是否存在授权记录
        KfUser kfUser = kfUserService.getOne(new LambdaQueryWrapper<KfUser>()
                .eq(KfUser::getKfUserId, SecurityUtil.getUserId())
                .eq(KfUser::getAppId, kfGameVO.getAppId()));
        kfGameVO.setIsAuth(kfUser != null ? Boolean.TRUE : Boolean.FALSE);
        if (kfUser == null) {
            return kfGameVO;
        }
        //判断授权信息是否过期, 请求获取客服信息接口
        String result = this.commKfApi(kfUser, KfActionEnum.GET_KF_ACCT.getValue(),
                KfApiEnum.getApiUrl(KfActionEnum.GET_KF_ACCT), Collections.emptyMap());
        KfMsgResultDTO kfMsgResultDTO = JsonUtil.toObj(result, KfMsgResultDTO.class);
        kfGameVO.setIsValid(kfMsgResultDTO.isSueecss());
        return kfGameVO;
    }

    @Override
    public String kfApi(KfApiParam param) {
        //查询用户授权信息
        KfUser kfUser = kfUserService.getKfUser(SecurityUtil.getUserId(), param.getAppId());
        //请求调用腾讯接口
        return this.commKfApi(kfUser, param.getAction().getValue(), KfApiEnum.getApiUrl(param.getAction()), param.getParam());
    }

    private String commKfApi(KfUser kfUser, String action, String url, Map<String, Object> param) {
        Map<String, String> pathParam = new HashMap<>(3);
        pathParam.put("action", action);
        pathParam.put("f", "json");
        pathParam.put("token", kfUser.getToken());
        HttpHeaders headers = new HttpHeaders();
        headers.add("cookie", kfUser.getCookie());
        ResponseEntity<String> responseEntity;
        try {
            responseEntity = restTemplate.exchange(URIUtil.fillUrlParams(url, pathParam, Boolean.FALSE),
                    HttpMethod.POST, new HttpEntity<>(param, headers), String.class);
        } catch (Exception e) {
            log.error("腾讯接口调用异常, url : {}, param : {}, e : {}", url, param, e.getMessage());
            throw new BaseException("腾讯接口调用异常!");
        }
        return responseEntity.getBody();
    }
}
