package com.wecloud.im.controller;

import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.param.ChatRoomMemberPageParam;
import com.wecloud.im.param.DisbandConversationParam;
import com.wecloud.im.param.ExitChatRoomParam;
import com.wecloud.im.param.GroupChatSettingParam;
import com.wecloud.im.param.ImConversationQueryParam;
import com.wecloud.im.param.IntoChatRoomParam;
import com.wecloud.im.param.ListConversationParam;
import com.wecloud.im.param.MutedGroupMemberParam;
import com.wecloud.im.param.MutedGroupParam;
import com.wecloud.im.param.SetAdminsParam;
import com.wecloud.im.param.SetHeadPortraitParam;
import com.wecloud.im.param.TransferOwnerParam;
import com.wecloud.im.param.add.AddOrModifyAttributeParam;
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.ChatRoomMemberVo;
import com.wecloud.im.vo.ConversationVo;
import com.wecloud.im.vo.ImConversationCreateVo;

/**
 * 会话表 控制器
 *
 * @author wei
 * @since 2021-05-07
 */
@Slf4j
@RestController
@RequestMapping("/conversation")
@Api(value = "会话表API", tags = {"会话表"})
public class ImConversationController extends BaseController {

    @Autowired
    private ImConversationService imConversationService;

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


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


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


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

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


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

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

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

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

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

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

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

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

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

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

    /**
     * 群聊设置
     */
    @PostMapping("/groupChatSetting")
    @ApiOperation(value = "群聊设置", notes = "权限:群主和管理员有权限操作")
    public ApiResult<Boolean> groupChatSetting(@RequestBody @Validated GroupChatSettingParam param) {
        log.info("群聊设置入参 {}", JSON.toJSONString(param));
        Boolean result = imConversationService.groupChatSetting(param);
        return ApiResult.ok(result);
    }

    /**
     * 群聊设置
     */
    @PostMapping("/groupChatSettingForSdk")
    @ApiOperation(value = "群聊设置", notes = "")
    public ApiResult<Boolean> groupChatSettingForSdk(@RequestBody @Validated GroupChatSettingParam param) {
        log.info("群聊设置入参 {}", JSON.toJSONString(param));
        Boolean result = imConversationService.groupChatSettingForSdk(param);
        return ApiResult.ok(result);
    }

    /**
     * 群头像设置
     */
    @PostMapping("/setGroupPortrait")
    @ApiOperation(value = "群头像设置", notes = "权限:群主和管理员有权限操作")
    public ApiResult<Boolean> setGroupPortrait(@RequestBody @Validated SetHeadPortraitParam param) {
        log.info("群头像设置入参 {}", JSON.toJSONString(param));
        Boolean result = imConversationService.setHeadPortrait(param);
        return ApiResult.ok(result);
    }


    /**
     * 用户进入聊天室
     */
    @PostMapping("/intoChatRoom")
    @ApiOperation(value = "用户进入聊天室", notes = "用户进入聊天室")
    public ApiResult<Boolean> intoChatRoom(@RequestBody IntoChatRoomParam param) {
        log.info("用户进入聊天室入参 {}", JSON.toJSONString(param));
        return ApiResult.ok(imConversationService.intoChatRoom(param));
    }


    /**
     * 用户退出聊天室
     */
    @PostMapping("/exitRoom")
    @ApiOperation(value = "用户退出聊天室", notes = "用户退出聊天室")
    public ApiResult<Boolean> exitChatRoom(@RequestBody ExitChatRoomParam param) {
        log.info("用户退出聊天室入参 {}", JSON.toJSONString(param));
        return ApiResult.ok(imConversationService.exitChatRoom(param));
    }

    /**
     * 全量获取聊天室成员
     */
    @PostMapping("/listChatRoomMember")
    @ApiOperation(value = "全量获取聊天室成员", notes = "全量获取聊天室成员")
    public ApiResult<List<ChatRoomMemberVo>> listChatRoomMember(@RequestBody ChatRoomMemberPageParam param) {
        log.info("全量获取聊天室成员入参 {}", JSON.toJSONString(param));
        return ApiResult.ok(imConversationService.listChatRoomMember(param));
    }

    /**
     * 查找会话信息
     * @return
     */
    @PostMapping("/listConversation")
    @ApiOperation(value = "批量查找会话信息", notes = "会话")
    public ApiResult<List<ConversationVo>> listConversation(@RequestBody ListConversationParam param) {
        List<ConversationVo> conversationList = imConversationService.listConversation(param);
        return ApiResult.ok(conversationList);
    }

    /**
     * 创建会话
     */
    @PostMapping("/sdk/create")
    @ApiOperation(value = "创建会话", notes = "后台可配置:两个客户端如果已经创建过会话,是否重复创建会话")
    public ApiResult<Long> create(@RequestBody ImConversationCreate imConversationCreate) throws Exception {
        log.info("sdk 创建会话入参 {}", JSON.toJSONString(imConversationCreate));
        ImConversation conversation = imConversationService.serverCreateImConversation(imConversationCreate);
        return ApiResult.ok(conversation.getId());
    }


    /**
     * 创建会话
     */
    @PostMapping("/sdk/addOrModifyAttribute")
    @ApiOperation(value = "修改会话拓展参")
    public ApiResult<Boolean> addOrModifyAttribute(@RequestBody AddOrModifyAttributeParam addOrModifyAttributeParam) throws Exception {
        log.info("sdk 修改会话拓展参数入参 {}", JSON.toJSONString(addOrModifyAttributeParam));
        return ApiResult.ok(imConversationService.addOrModifyAttribute(addOrModifyAttributeParam));
    }

}

