package com.jd.lightapplication.easemob;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jd.lightapplication.common.lang.R;
import com.jd.lightapplication.easemob.dto.*;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/easemob")
@ApiOperation("环信相关接口")
@AllArgsConstructor
public class EasemobComtroller {

    private RedisTemplate redisTemplate;
    private final String EASEMOB_TOKEN = "EASEMOB_TOKEN";//存储环信token的redis的key

    private final String ORG_NAME = "1160220415096727"; //企业的唯一标识，开发者在环信开发者管理后台注册账号之后自动生成的企业 ID。
    private final String APP_NAME = "light-application";//同一“企业”下“APP”唯一标识，开发者在环信开发者管理后台创建应用时填写的“应用名称”。

    private final String GRANT_TYPE = "client_credentials";//获取token 这里直接写死
    private final String CLIENT_ID = "YXA6Z1TGzj7dTvmtgQkyTKPnNw";//可在环信后台-->应用管理查看
    private final String CLIENT_SECRET = "YXA6vOkXod1I_TZ1XWypfr_bKkzYgCM";//可在环信后台-->应用管理查看

    private final String TOKEN_URL = "http://a1.easemob.com/%s/%s/token";//获取token
    private final String REGISTER_USER_URL = "http://a1.easemob.com/%s/%s/users";//注册用户
    private final String QUERY_USER_PAGE_URL = "http://a1.easemob.com/%s/%s/users";//分页查询用户
    private final String DELETE_USER_PAGE_URL = "http://a1.easemob.com/%s/%s/users/%s";//删除环信用户(单个)
    private final String CREATE_GROUP_URL = "http://a1.easemob.com/%s/%s/chatgroups";//创建群组
    private final String UPDATE_GROUP_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s";//修改群组详情
    private final String DELETE_GROUP_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s";//删除群组
    private final String QUERY_GROUP_PAGE_URL = "http://a1.easemob.com/%s/%s/chatgroups";//分页查询群组
    private final String QUERY_GROUP_DETAILS_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s";//查询群组详情
    private final String QUERY_GROUP_USER_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s/users";//查询群组内所有成员
    private final String ADD_GROUP_USER_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s/users";//批量添加群组成员
    private final String DELETE_GROUP_USER_URL = "http://a1.easemob.com/%s/%s/chatgroups/%s/users/%s";//批量移除群组成员
    private final String SET_USER_ATTRIBUTE_URL = "http://a1.easemob.com/%s/%s/metadata/user/%s";//设置环信用户属性
    private final String GET_USER_ATTRIBUTE_URL = "http://a1.easemob.com/%s/%s/metadata/user/%s";//获取环信用户属性
    private final String GET_USER_ATTRIBUTE_BATH_URL = "http://a1.easemob.com/%s/%s/metadata/user/get";//获取环信用户属性批量

    @PostMapping("/getToken")
    @ApiOperation("获取环信token接口")
    public R getToken() {
        //获取环信token，如果redis里面没有。就向环信获取token
        Object easemobTokenObj = redisTemplate.opsForValue().get(EASEMOB_TOKEN);
        if (easemobTokenObj != null) {
            return R.success(easemobTokenObj.toString());
        }
        //拼接请求路径
        String tokenUrl = String.format(TOKEN_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("grant_type", GRANT_TYPE)
                .put("client_id", CLIENT_ID)
                .put("client_secret", CLIENT_SECRET)
                .map();
        //获取响应参数
        String result = HttpRequest.post(tokenUrl)
                .header("Accept", "application/json")
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject resultJsonObj = JSONUtil.parseObj(result);
        String token = resultJsonObj.getStr("access_token");
        //如果redis里面没有环信的token并且目前获取到了token，把token存到redis里面。有效期为7天
        if (token != null && redisTemplate.opsForValue().get(EASEMOB_TOKEN) == null) {
            redisTemplate.opsForValue().set(EASEMOB_TOKEN, token, 7, TimeUnit.DAYS);
        }
        return R.success(token);
    }

    @PostMapping("/registerUser")
    @ApiOperation("注册环信用户")
    public R registerUser(@RequestBody EasemobUserAddDto easemobUserAddDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(REGISTER_USER_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("username", easemobUserAddDto.getUsername())
                .put("password", easemobUserAddDto.getPassword())
                .map();
        String result = HttpRequest.post(url)
                .header("Accept", "application/json")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @GetMapping("/queryGroupPage")
    @ApiOperation("分页查询环信应用内的群组")
    public R queryGroupPage(QueryPageDto queryPageDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(QUERY_GROUP_PAGE_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<String, Object> params = new HashMap<>();
        new MapBuilder<>(params)
                .put("limit", queryPageDto.getLimit())
                .put("cursor", queryPageDto.getCursor())
                .map();
        String result = HttpRequest.get(url)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .form(params)
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @GetMapping("/queryGroupDetails/{groupIds}")
    @ApiOperation("查询群组详情 多个groupIds用逗号隔开")
    public R queryGroupDetails(@PathVariable("groupIds") String groupIds) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(QUERY_GROUP_DETAILS_URL, ORG_NAME, APP_NAME, groupIds);
        String result = HttpRequest.get(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @PostMapping("/createGroup")
    @ApiOperation("创建环信群组")
    public R createGroup(@RequestBody CreateGroupDto createGroupDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(CREATE_GROUP_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("groupname", createGroupDto.getGroupname())
                .put("desc", createGroupDto.getDesc())
                .put("public", createGroupDto.getIspublic())
                .put("maxusers", createGroupDto.getMaxusers())
                .put("approval", createGroupDto.getApproval())
                .put("owner", createGroupDto.getOwner())
                .put("members", createGroupDto.getMembers())
                .map();
        String result = HttpRequest.post(url)
                .header("Accept", "application/json")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @PostMapping("/updateGroup")
    @ApiOperation("修改环信群组")
    public R updateGroup(@RequestBody updateGroupDto updateGroupDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(UPDATE_GROUP_URL, ORG_NAME, APP_NAME, updateGroupDto.getId());
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("groupname", updateGroupDto.getGroupname())
                .put("description", updateGroupDto.getDescription())
                .put("maxusers", updateGroupDto.getMaxusers())
                .map();
        String result = HttpRequest.put(url)
                .header("Accept", "application/json")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @DeleteMapping("/deleteGroup/{groupId}")
    @ApiOperation("删除环信群组")
    public R deleteGroup(@PathVariable("groupId") String groupId) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(DELETE_GROUP_URL, ORG_NAME, APP_NAME, groupId);
        String result = HttpRequest.delete(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @PostMapping("/addGroupUser")
    @ApiOperation("批量添加群组成员")
    public R addGroupUser(@RequestBody AddGroupUserDto addGroupUserDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(ADD_GROUP_USER_URL, ORG_NAME, APP_NAME, addGroupUserDto.getChatgroupid());
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("usernames", addGroupUserDto.getUsernames())
                .map();
        String result = HttpRequest.post(url)
                .header("Accept", "application/json")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @GetMapping("/queryGroupUser")
    @ApiOperation("查询群组内所有的用户")
    public R queryGroupUser(String groupId) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(QUERY_GROUP_USER_URL, ORG_NAME, APP_NAME, groupId);
        String result = HttpRequest.get(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject resultJsonObj = JSONUtil.parseObj(result);
        return R.success(resultJsonObj);
    }

    @DeleteMapping("/removeGroupUser/{groupId}")
    @ApiOperation("批量删除群组内的用户")
    public R removeGroupUser(@PathVariable("groupId") String groupId, String usernames) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(DELETE_GROUP_USER_URL, ORG_NAME, APP_NAME, groupId, usernames);
        String result = HttpRequest.delete(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject resultJsonObj = JSONUtil.parseObj(result);
        return R.success(resultJsonObj);
    }

    @PostMapping("/setUpUserAttribute")
    @ApiOperation("设置环信用户属性")
    public R setUpUserAttribute(@RequestBody SetUserAttributeDto setUserAttributeDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(SET_USER_ATTRIBUTE_URL, ORG_NAME, APP_NAME, setUserAttributeDto.getUsername());
        //封装请求参数
        Map<String, Object> params = new HashMap<>();
        new MapBuilder<>(params)
                .put("nickname", setUserAttributeDto.getNickname())
                .put("avatarurl", setUserAttributeDto.getAvatarurl())
                .put("mail", setUserAttributeDto.getMail())
                .put("phone", setUserAttributeDto.getPhone())
                .put("gender", setUserAttributeDto.getGender())
                .put("birth", setUserAttributeDto.getBirth())
                .put("sign", setUserAttributeDto.getSign())
                .put("ext", setUserAttributeDto.getExt())
                .map();
        String result = HttpRequest.put(url)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .header("Authorization", "Bearer " + easemobTokenStr)
                .form(params)
                .execute()
                .body();
        JSONObject resultJsonObj = JSONUtil.parseObj(result);
        return R.success(resultJsonObj);
    }

    @PostMapping("/getUpUserAttribute/{username}")
    @ApiOperation("获取环信用户属性")
    public R getUpUserAttribute(@PathVariable("username") String username) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(GET_USER_ATTRIBUTE_URL, ORG_NAME, APP_NAME, username);
        String result = HttpRequest.get(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @PostMapping("/getUpUserAttributeBath")
    @ApiOperation("获取环信用户属性(批量)")
    public R getUpUserAttributeBath(@RequestBody GetUpUserAttributeBathDto getUpUserAttributeBathDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(GET_USER_ATTRIBUTE_BATH_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<Object, Object> params = MapUtil.builder()
                .put("properties", getUpUserAttributeBathDto.getProperties())
                .put("targets", getUpUserAttributeBathDto.getTargets())
                .map();
        String result = HttpRequest.get(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .body(JSONUtil.parse(params).toString(), "application/json")
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }

    @PostMapping("/queryUserPage")
    @ApiOperation("分页查询环信用户")
    public R queryUserPage(QueryPageDto queryPageDto) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(QUERY_USER_PAGE_URL, ORG_NAME, APP_NAME);
        //封装请求参数
        Map<String, Object> params = new HashMap<>();
        new MapBuilder<>(params)
                .put("limit", queryPageDto.getLimit())
                .put("cursor", queryPageDto.getCursor())
                .map();
        String result = HttpRequest.get(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .form(params)
                .execute()
                .body();
        JSONObject resultJsonObj = JSONUtil.parseObj(result);
        return R.success(resultJsonObj);
    }

    @DeleteMapping("/deleteUser/{username}")
    @ApiOperation("删除环信用户")
    public R deleteUser(@PathVariable("username") String username) {
        //获取环信token
        String easemobTokenStr = this.getToken().getData().toString();
        //拼接请求路径
        String url = String.format(DELETE_USER_PAGE_URL, ORG_NAME, APP_NAME, username);
        String result = HttpRequest.delete(url)
                .header("Authorization", "Bearer " + easemobTokenStr)
                .execute()
                .body();
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return R.success(jsonObject);
    }
}
