package com.wecloud.im.action;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.wecloud.dispatch.annotation.ActionMapping;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.param.ClientInfoParam;
import com.wecloud.im.param.GetClientInfoParam;
import com.wecloud.im.param.GetOnlineStatusParam;
import com.wecloud.im.param.LogoutParam;
import com.wecloud.im.param.add.ImClientHeadPortraitAdd;
import com.wecloud.im.param.add.ImClientHeadPortraitAndNicknameUpdate;
import com.wecloud.im.param.add.ImClientNicknameAdd;
import com.wecloud.im.service.ContextService;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.vo.ClientInfoVo;
import com.wecloud.im.vo.GetInfoListVo;
import com.wecloud.im.vo.ImOnlineStatusVo;
import com.wecloud.im.vo.MyInfoVo;
import com.wecloud.im.ws.cache.UserStateCacheManager;
import com.wecloud.im.ws.model.WsResponse;

/**
 * 终端 action
 * @Author luozh
 * @Date 2022年04月02日 15:14
 * @Version 1.0
 */
@Slf4j
@Component
@ActionMapping("/im/client")
@Api(value = "ws-终端", tags = {"终端"})
public class ClientAction {

    @Autowired
    private ImClientService imClientService;

    @Autowired
    private UserStateCacheManager userStateCacheManager;

    @Autowired
    private ImApplicationService imApplicationService;

    @Autowired
    private ContextService contextService;

    /**
     * 查询我的信息
     */
    @ActionMapping("/myInfo")
    @ApiOperation(value = "查询我的信息")
    public WsResponse<MyInfoVo> myInfo() {
        MyInfoVo myInfo = imClientService.getMyInfo();
        return WsResponse.ok(myInfo);
    }


    @ActionMapping("/infoList")
    @ApiOperation(value = "根据id获取Client的头像昵称")
    public WsResponse<List<GetInfoListVo>> getInfoList(GetClientInfoParam data) throws Exception {
        return WsResponse.ok(imClientService.getInfoList(data));
    }

    /**
     * 查询用户信息 用户可能是好友、陌生人、被拉黑名单的人
     */
    @ActionMapping("/clientInfo")
    @ApiOperation(value = "查询用户信息 用户可能是好友、陌生人、被拉黑名单的人")
    public WsResponse<ClientInfoVo> getClientInfo(ClientInfoParam data) {
        ClientInfoVo clientInfoVo = imClientService.getClientInfo(data);
        return WsResponse.ok(clientInfoVo);
    }


    @ActionMapping("/updateHeadAndNickname")
    @ApiOperation(value = "添加或修改头像和昵称")
    public WsResponse<Boolean> updateHeadAndNickname(ImClientHeadPortraitAndNicknameUpdate data) throws Exception {
        log.info("添加或修改头像和昵称入参 {}", JSON.toJSONString(data));
        boolean flag = imClientService.updateHeadAndNickname(data);
        return WsResponse.ok(flag);
    }


    @ActionMapping("/updateHeadPortrait")
    @ApiOperation(value = "添加或修改头像")
    public WsResponse<Boolean> updateHeadPortrait(ImClientHeadPortraitAdd data) throws Exception {
        log.info("添加或修改头像入参 {}", JSON.toJSONString(data));
        boolean flag = imClientService.updateHeadPortrait(data);
        return WsResponse.ok(flag);
    }

    @ActionMapping("/updateNickname")
    @ApiOperation(value = "添加或修改主昵称")
    public WsResponse<Boolean> updateNickname(ImClientNicknameAdd data) throws Exception {
        log.info("添加或修改主昵称入参 {}", JSON.toJSONString(data));
        boolean flag = imClientService.updateNickname(data);
        return WsResponse.ok(flag);
    }


    /**
     * 退出登陆
     *
     * @return
     * @throws Exception
     */
    @ActionMapping("/logout")
    @ApiOperation(value = "退出登陆 清除推送token等")
    public WsResponse<Boolean> logout(LogoutParam param) {
        log.info("退出登陆入参 {}", JSON.toJSONString(param));
        boolean flag = imClientService.logout(param);
        return WsResponse.ok(flag);
    }

    /**
     * 获取用户在线状态(批量)
     *
     * @return true:在线, false 不在线
     */
    @ActionMapping("/onlineStatus")
    @ApiOperation(value = "获取用户在线状态(批量)")
    public WsResponse<List<ImOnlineStatusVo>> getOnlineStatus(
            GetOnlineStatusParam getOnlineStatusParam) {
        // shiro线程中获取当前token
        ImClient imClient = contextService.getImClientIfNotNullOrThrow();
        ImApplication imApplication = contextService.getImApplicationIfNotNullOrThrow(imClient.getFkAppid());

        ArrayList<ImOnlineStatusVo> imOnlineStatusVos = new ArrayList<>();
        for (String clientId : getOnlineStatusParam.getClientIds()) {

            ImOnlineStatusVo imOnlineStatusVo = new ImOnlineStatusVo();
            // todo 需要改成批量
            ImClient client = imClientService.getCacheImClient(imApplication.getId(), clientId);
            imOnlineStatusVo.setStatus(userStateCacheManager.isOnline(client.getId()));
            imOnlineStatusVo.setClientId(clientId);
            imOnlineStatusVos.add(imOnlineStatusVo);
        }
        return WsResponse.ok(imOnlineStatusVos);
    }
}
