package com.wecloud.im.action;

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

import java.util.List;

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 org.springframework.web.bind.annotation.RequestParam;

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<Boolean> saveOrUpdateName(@RequestParam(value = "data") ImConversationNameUpdate conversationNameUpdate) {
        log.info("添加或修改会话名称入参 {}", JSON.toJSONString(conversationNameUpdate));
        imConversationService.saveOrUpdateName(conversationNameUpdate);
        return WsResponse.ok();
    }


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


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


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

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


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

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

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

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

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

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

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

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

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

        imConversationService.updateDisplayConversation(imConversationDisplayUpdate);
        return ApiResult.result(true);
    }
}
