package cn.edu.whu.boot.message.controller;


import cn.edu.whu.boot.message.bean.ChatMessage;
import cn.edu.whu.boot.message.bean.ResultMessage;
import cn.edu.whu.boot.message.bean.Team;
import cn.edu.whu.boot.message.bean.Worker;
import com.alibaba.fastjson.JSONObject;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 1.创建房间
 * 2.获取已有房间，加入房间
 * 3.群聊
 * 4.私聊
 * @author Li Haoming
 */
@RestController
public class ChatController {

    Map<String, Team> teamMap = new HashMap<>();

    Map<String, String> conversation = new HashMap<>();

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    /**
     * 1. 创建房间相当于产生新的消息代理
     * 2. 消息代理以小队为单位，所以需要通过 teamId 保存
     * 3. 注意 前端 subscribe() 如果返回为该房间已存在，需要通过 unsubscribe() 取消订阅
     * @param captain
     * @param teamId
     * @return
     */
    @MessageMapping("/createRoom/{teamId}")
    public String createChatRoom(Worker captain, @DestinationVariable String teamId) {

        if (null != teamMap.get(teamId)) {
            return new ResultMessage<String>(false, "该房间已经存在", teamId).toString();
        }

        Team team = new Team(teamId, captain);
        teamMap.put(teamId, team);

        return new ResultMessage<String>(true, "创建房间成功").toString();
    }


    /**
     * 将返回所有的teamIds
     * 目前没有考虑用户有没有权限获取
     * 进一步的版本将会考虑
     * @return
     */
    @RequestMapping("/getAllRooms")
    public String getAllRooms() {
        Set set = teamMap.keySet();
        return JSONObject.toJSONString(set);
    }


    /**
     * 1. 队伍存在，加入队伍，广播 xxx 加入队伍
     * 2. 队伍不存在，告诉申请者队伍不存在
     * @param worker 要加入的人，需要填写相关信息
     * @param teamId 要加入的队伍Id
     * @return
     */
    @MessageMapping("/join/{roomId}")
    @SendTo("/chat/{roomId}")
    public String joinTeam(Worker worker, @DestinationVariable String teamId) {

        if (null == teamMap.get(teamId)) {
            return new ResultMessage<String>(false, "房间不存在，请先创建房间").toString();
        }

        teamMap.get(teamId).getMembers().put(worker.getName(), worker);

        return new ResultMessage<String>(true, worker.getName() + "已加入" + teamId + "队伍").toString();
    }


    /**
     * 在聊天室内发送消息
     * 1.name 是发送者的用户信息
     * 更规范的写法是添加 WebSocketHandler
     * 通过 WebSocketSession 获取
     * 2.向聊天室内的所有人推送  xxx date message
     * 例如 : Ferry  2019-09-10 20:03:47 : Hello
     * 3.建议前端作字符串长度等检验
     * 个人担心字符串长度如果过长，会不会影响效率
     * 具体限制长度待定
     * @param name
     * @param message
     * @param teamId
     * @return
     */
    @MessageMapping("/group/{teamId}")
    @SendTo("/chat/{teamId}")
    public String sendToTeam(String name, String message, @DestinationVariable String teamId) {
        return new ChatMessage(name, message, dateFormat.format(new Date())).toString();
    }


    /**
     * 这里目前知识猜测
     * 1. 这里实现的关键 !:
     * 任何一个前端都需要订阅自己的频道
     * 2. Example:
     * (1) a 订阅 chat/broker/conversation/a
     *     b 订阅 chat/broker/conversation/b
     * (2) 发送消息时 a 向 chat/broker/conversation/b 发送消息
     * (3) 由于 b 订阅了chat/broker/conversation/b，所以 b 可以接收到该消息
     * (4) 存在 c d e ...  同时向 chat/broker/conversation/b 发送消息，因此前端需要根据 name(发送者) 在前端分别展示
     * @param name
     * @param message
     * @param receiver
     * @return
     */
    @MessageMapping("/conversation/{receiver}")
    @SendTo("/conversation/{receiver}")
    public String sendToUser(String name, String message, @DestinationVariable String receiver) {
        return new ChatMessage(name, message, dateFormat.format(new Date())).toString();
    }


}
