package com.ssyf.ws.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ssyf.ws.constants.CommandType;
import com.ssyf.ws.constants.WebSocketConstants;
import com.ssyf.ws.domain.WsMessage;
import com.ssyf.ws.domain.SessionInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class WsClientService {

    @Autowired
    private SessionService sessionService;

    @Autowired
    private UserStatusService userStatusService;

    /**
     * 主播信息和粉丝信息聊天时对应的session情况
     */
    private Map<String, WebSocketSession> masterAccountIdAndFansIdTodSession = new ConcurrentHashMap<>();

    public void updateClientInfo(WebSocketSession session){
        // 获取认证信息
        Map<String, Object> attributes = session.getAttributes();
        String userId = (String) attributes.get(WebSocketConstants.SESSION_ATTR_USER_ID);
        String username = (String) attributes.get(WebSocketConstants.SESSION_ATTR_USERNAME);

        if (userId == null || username == null) {
            log.error("WebSocket更新客户端信息：未找到用户信息, sessionId={}", session.getId());
            return;
        }

        // 创建会话信息
        SessionInfo sessionInfo = new SessionInfo(userId, username, session.getId());
        sessionInfo.setClientInfo(session.getRemoteAddress().toString());

        // 保存会话信息
        sessionService.saveSession(sessionInfo);

        // 更新用户在线状态
        userStatusService.userOnline(userId, sessionInfo);
    }



    public boolean validToken(WebSocketSession session) {
        // 获取认证信息
        Map<String, Object> attributes = session.getAttributes();
        String token = (String) attributes.get(WebSocketConstants.TOKEN_KEY);
        if(StrUtil.isBlank( token)){
            log.error("WebSocket验证Token失败: sessionId={}", session.getId());
            return false;
        }
        return validToken(token, session);
    }

    public boolean validToken(String token, WebSocketSession session) {
        log.info("验证Token: {}", token);
        //TODO 调用方法进行验证
        boolean b = false;


        //校验成功则需要更新客户端状态
        if(b){
            updateClientInfo(session);
        }

        return b;
    }

    /**
     * 是否校验了token
     * @param session
     */
    public  boolean isValidToken(WebSocketSession session){
       return  sessionService.getSession(session.getId()) != null;
    }

    public void sendErrorMessage(WebSocketSession session , String msg) {
        sendErrorMessage(session, null, msg);
    }

    public void sendErrorMessage(WebSocketSession session , WsMessage oldMessage, String msg) {
        if(!session.isOpen()){
            return;
        }
        log.error("发送错误消息失败:", msg);
        WsMessage message = new WsMessage();
        message.setCommand(CommandType.ERROR_RESPONSE.getCode()).setMsg( msg);
        if(oldMessage != null) {
            message.setSequenceId(oldMessage.getSequenceId());
        }
        try {
            session.sendMessage(new TextMessage(JSONUtil.toJsonStr( message)));
        } catch (IOException e) {
            log.error("发送错误消息失败", e);
        }
    }

    public void closeSession(WebSocketSession session) {
        if(session != null && session.isOpen()){
            try {
                session.close();
            } catch (IOException e) {
                log.error("关闭WebSocketSession失败:", e);
            }
            SessionInfo sessionInfo = sessionService.getSession(session.getId());
            //移除会话信息
            String userId = sessionInfo.getUserId();

            // 移除会话信息
            sessionService.removeSession(session.getId());

            // 更新用户离线状态
            userStatusService.userOffline(userId, session.getId());

            // 移除主播和粉丝信息对应的session
            masterAccountIdAndFansIdTodSession.remove(createMasterAccountIdAndFansIdKey(sessionInfo.getMasterAccountId(), sessionInfo.getFansId()));

            log.info("WebSocket连接关闭: userId={}, sessionId={}, masterAccountId={} ,fansId={}",sessionInfo.getUserId(), session.getId(), sessionInfo.getMasterAccountId(), sessionInfo.getFansId());
        }
    }

    public String createMasterAccountIdAndFansIdKey(String masterAccountId, String fansId) {
        String key = masterAccountId + "_" + fansId;
        return key;
    }

    public void initChatSession(WebSocketSession session, String masterAccountId, String fansAccountId) {
        String key = createMasterAccountIdAndFansIdKey(masterAccountId, fansAccountId);
        masterAccountIdAndFansIdTodSession.put(key, session);
        log.info("初始化聊天会话: key={}", key);
    }

    public boolean isOnline(String accountNumber, String fansNumber) {
        return masterAccountIdAndFansIdTodSession.containsKey(createMasterAccountIdAndFansIdKey(accountNumber, fansNumber));
    }
}
