package org.wcs.helper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.wcs.constant.enums.business.SseEventTypeEnum;

import java.util.Map;

/**
 * SSE 帮助类
 */
@Slf4j
@Component
public class SseHelper {

    private static Map<String, SseEmitter> emitters;

    /**
     * 设置 SSEEmitter
     * @param key 键
     * @param emitter SSEEmitter
     */
    public synchronized void setEmitter(String key, SseEmitter emitter) {
        if(emitters == null) {
            emitters = new java.util.concurrent.ConcurrentHashMap<>();
        }
        if(emitters.containsKey(key)) {
            SseEmitter sseEmitter = emitters.get(key);
            try{
                sseEmitter.complete();
                emitters.remove(key);
                log.info("已存在连接，已关闭，连接 Key: {}",  key);
            } catch (Exception ignored){
            }
        }
        emitters.put(key, emitter);
        log.info("已创建连接，连接 Key: {}", key);
    }

    /**
     * 关闭所有 SSEEmitter
     */
    public synchronized void closeAllEmitter() {
        if(emitters == null) {
            return;
        }
        for (Map.Entry<String, SseEmitter> entry : emitters.entrySet()) {
            SseEmitter emitter = entry.getValue();
            try {
                emitter.complete();
                emitters.remove(entry.getKey());
            } catch (Exception ex) {
                emitter.complete();
                emitters.remove(entry.getKey());
                log.info("已关闭连接，连接 Key: {}，异常信息：{}", entry.getKey(), ex.getMessage());
            }
        }
    }

    /**
     * 移除 SSEEmitter
     * @param key 键
     */
    public synchronized void removeEmitter(String key) {
        if(emitters == null) {
            return;
        }
        SseEmitter emitter = emitters.get(key);
        if(emitter != null) {
            emitters.remove(key);
            emitter.complete();
            log.info("已关闭连接，连接 Key: {}", key);
        }
    }

    /**
     * 发送事件给所有连接
     * @param eventName 事件名称
     * @param message 消息
     */
    public void SendEventToAll(SseEventTypeEnum eventName, String message) {
        if(emitters == null) {
            return;
        }
        for (Map.Entry<String, SseEmitter> entry : emitters.entrySet()) {
            SseEmitter emitter = entry.getValue();
            try {
                SseEmitter.SseEventBuilder event = SseEmitter.event()
                        .name(eventName.getCode())
                        .reconnectTime(1000)
                        .data(message, MediaType.APPLICATION_JSON);
                emitter.send(event);
            } catch (Exception ex) {
                emitter.complete();
                emitters.remove(entry.getKey());
                log.info("已关闭连接，因为无法发送数据，连接 Key: {}，异常信息：{}", entry.getKey(), ex.getMessage());
            }
        }
    }

}
