package com.wecloud.im.action;

import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import com.alibaba.fastjson.JSON;
import com.wecloud.dispatch.annotation.ActionMapping;
import com.wecloud.im.param.DisbandConversationParam;
import com.wecloud.im.param.ImConversationQueryParam;
import com.wecloud.im.param.MutedGroupMemberParam;
import com.wecloud.im.param.MutedGroupParam;
import com.wecloud.im.param.SetAdminsParam;
import com.wecloud.im.param.TransferOwnerParam;
import com.wecloud.im.param.add.ImClientLeaveConversation;
import com.wecloud.im.param.add.ImClientToConversation;
import com.wecloud.im.param.add.ImConversationAttrUpdate;
import com.wecloud.im.param.add.ImConversationCreate;
import com.wecloud.im.param.add.ImConversationDisplayUpdate;
import com.wecloud.im.param.add.ImConversationNameUpdate;
import com.wecloud.im.service.ImConversationService;
import com.wecloud.im.vo.ConversationVo;
import com.wecloud.im.vo.ImConversationCreateVo;
import com.wecloud.im.ws.model.WsResponse;

/**
 *
 * @Author luozh
 * @Date 2022年04月02日 16:39
 * @Version 1.0
 */
@Slf4j
@Component
@ActionMapping(value = "/im/conversation")
@Api(value = "ws-会话表API", tags = {"ws-会话表"})
public class ConversationAction {

    @Autowired
    private ImConversationService imConversationService;


    /**
     * 添加或修改会话名称
     */
    @ActionMapping("/saveOrUpdateName")
    @ApiOperation(value = "添加或修改会话名称", notes = "权限:目前只有创建者有权限操作")
    public WsResponse<Map<String, Boolean>> saveOrUpdateName(ImConversationNameUpdate data) {
        log.info("添加或修改会话名称入参 {}", JSON.toJSONString(data));
        imConversationService.saveOrUpdateName(data);
        return WsResponse.ok();
    }


    /**
     * 添加或修改会话拓展字段
     */
    @ActionMapping("/saveOrUpdateAttr")
    @ApiOperation(value = "添加或修改会话拓展字段", notes = "权限:所有client都权限操作")
    public WsResponse<Map<String, Boolean>> saveOrUpdateAttr(ImConversationAttrUpdate data) {
        log.info("添加或修改会话拓展字段 {}", JSON.toJSONString(data));
        imConversationService.saveOrUpdateAttr(data);
        return WsResponse.ok();
    }


    /**
     * client退出会话
     */
    @ActionMapping("/leave")
    @ApiOperation(value = "client退出会话", notes = "若是创建者退出,[创建者]权限将会转移给按加入会话时间排序的下一个client")
    public WsResponse<Map<String, Boolean>> leaveConversation(ImClientLeaveConversation data) {
        log.info("client退出会话入参 {}", JSON.toJSONString(data));
        imConversationService.leaveConversation(data);
        return WsResponse.ok();
    }


    /**
     * 将client从会话移除
     * @return
     */
    @ActionMapping("/delClient")
    @ApiOperation(value = "将client从会话移除", notes = "权限:目前只有群主有权限操作")
    public WsResponse<Map<String, Boolean>> delClientToConversation(ImClientToConversation data) throws Exception {
        log.info("将client从会话移除入参 {}", JSON.toJSONString(data));
        boolean r = imConversationService.delClientToConversation(data);
        Map<String, Boolean> result = new HashMap<>();
        result.put("result", r);
        return WsResponse.ok(result);
    }

    /**
     * 解散群聊
     */
    @ActionMapping("/disband")
    @ApiOperation(value = "解散群聊", notes = "权限:目前只有群主有权限操作")
    public WsResponse<Map<String, Boolean>> disband(DisbandConversationParam data) throws Exception {
        log.info("解散群聊入参 {}", JSON.toJSONString(data));
        imConversationService.disband(data);
        return WsResponse.ok();
    }


    /**
     * 将用户添加进会话
     */
    @ActionMapping("/addClient")
    @ApiOperation(value = "将用户添加进会话", notes = "权限:会话中所有client都有权限操作")
    public WsResponse<Map<String, Boolean>> addClientToConversation(ImClientToConversation data) throws Exception {
        log.info("将用户添加进会话入参 {}", JSON.toJSONString(data));
        imConversationService.addClientToConversation(data);
        return WsResponse.ok();
    }

    /**
     * 创建会话
     */
    @ActionMapping("/create")
    @ApiOperation(value = "创建会话", notes = "后台可配置:两个客户端如果已经创建过会话,是否重复创建会话")
    public WsResponse<ImConversationCreateVo> createImConversation(ImConversationCreate data) throws Exception {
        log.info("创建会话入参 {}", JSON.toJSONString(data));
        ImConversationCreateVo vo = imConversationService.createImConversation(data);
        return WsResponse.ok(vo);
    }

    /**
     * 群主转让
     * @return
     */
    @ActionMapping("/transferOwner")
    @ApiOperation(value = "群主转让", notes = "权限:目前只有群主有权限操作")
    public WsResponse<Map<String, Boolean>> transferOwner(TransferOwnerParam data) {
        log.info("群主转让入参 {}", JSON.toJSONString(data));
        Boolean r = imConversationService.transferOwner(data);
        Map<String, Boolean> result = new HashMap<>();
        result.put("result", r);
        return WsResponse.ok(result);
    }

    /**
     * 设置群管理员
     * @return
     */
    @ActionMapping("/setAdmins")
    @ApiOperation(value = "设置群管理员", notes = "权限:目前只有群主有权限操作")
    public WsResponse<Map<String, Boolean>> setAdmins(@Validated SetAdminsParam data) {
        log.info("设置群管理员入参 {}", JSON.toJSONString(data));
        if (CollectionUtils.isEmpty(data.getClientIds())) {
            return WsResponse.fail(ApiCode.PARAMETER_EXCEPTION, null);
        }
        Boolean r = imConversationService.setAdmins(data);
        Map<String, Boolean> result = new HashMap<>();
        result.put("result", r);
        return WsResponse.ok(result);
    }

    /**
     * 群禁言、取消群禁言
     * @return
     */
    @ActionMapping("/mutedGroup")
    @ApiOperation(value = "群禁言、取消群禁言", notes = "权限:群主和管理员有权限操作")
    public WsResponse<Map<String, Boolean>> mutedGroup(@Validated MutedGroupParam data) {
        log.info("群禁言、取消群禁言入参 {}", JSON.toJSONString(data));
        Boolean r = imConversationService.mutedGroup(data);
        Map<String, Boolean> result = new HashMap<>();
        result.put("result", r);
        return WsResponse.ok(result);
    }

    /**
     * 选择禁言
     */
    @ActionMapping("/mutedGroupMember")
    @ApiOperation(value = "选择禁言", notes = "权限:群主和管理员有权限操作")
    public WsResponse<Map<String, Boolean>> mutedGroupMember(@Validated MutedGroupMemberParam data) {
        log.info("选择禁言入参 {}", JSON.toJSONString(data));
        if (CollectionUtils.isEmpty(data.getClientIds())) {
            return WsResponse.fail(ApiCode.PARAMETER_EXCEPTION, null);
        }
        Boolean r = imConversationService.mutedGroupMember(data);
        Map<String, Boolean> result = new HashMap<>();
        result.put("result", r);
        return WsResponse.ok(result);
    }

    /**
     * 查询用户加入的所有会话 与每个会话的未读条数 成员
     * @return
     */
    @ActionMapping("/getList")
    @ApiOperation(value = "查询加入的会话列表", notes = "查询用户加入的非隐藏状态的会话列表 与每个会话的未读条数 成员")
    public WsResponse<Map<String, List<ConversationVo>>> getMyImConversationListAndMsgCount() {
        List<ConversationVo> conversationList = imConversationService.getMyImConversationListAndMsgCount();
        Map<String, List<ConversationVo>> result = new HashMap<>();
        result.put("result", conversationList);
        return WsResponse.ok(result);
    }

    /**
     * 根据会话id查询指定会话信息
     */
    @ActionMapping("/info")
    @ApiOperation(value = "根据会话id查询指定会话信息", notes = "根据会话id查询指定会话信息 与每个会话的未读条数")
    public WsResponse<ConversationVo> info(@Validated ImConversationQueryParam data) throws Exception {
        log.info("根据会话id查询指定会话信息 {}", JSON.toJSONString(data));
        ConversationVo conversationVo = imConversationService.infoImConversationAndMsgCount(data);
        return WsResponse.ok(conversationVo);
    }

    /**
     * 批量修改单向隐藏或显示会话
     */
    @ActionMapping("/displayUpdate")
    @ApiOperation(value = "批量修改单向隐藏或显示会话", notes = "拉取会话列表不展示已隐藏状态的会话,云端聊天记录不删除;假设有A和B两个用户,A删会话,B还能发; 如果B发了消息,A这边要重新把会话显示出来,并能显示之前的聊天记录")
    public WsResponse<Map<String, Boolean>> updateDisplayConversation(ImConversationDisplayUpdate data) throws Exception {
        log.info("批量修改单向隐藏或显示会话 {}", JSON.toJSONString(data));
        imConversationService.updateDisplayConversation(data);
        return WsResponse.ok();
    }
}
