content: /**
   * Copyright (C) 2024 AIDC-AI
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.alibaba.langengine.slack.handler;
  
  import com.alibaba.langengine.slack.SlackConfiguration;
  import com.alibaba.langengine.slack.client.SlackClient;
  import com.slack.api.Slack;
  import com.slack.api.app_backend.events.EventHandler;
  import com.slack.api.app_backend.events.payload.EventsApiPayload;
  import com.slack.api.app_backend.events.payload.MessagePayload;
  import com.slack.api.app_backend.slash_commands.SlashCommandPayloadParser;
  import com.slack.api.app_backend.slash_commands.payload.SlashCommandPayload;
  import com.slack.api.model.event.MessageEvent;
  import com.slack.api.socket_mode.SocketModeClient;
  import com.slack.api.socket_mode.request.EventsApiEnvelope;
  import com.slack.api.socket_mode.request.SlashCommandsEnvelope;
  import com.slack.api.socket_mode.response.AckResponse;
  import lombok.extern.slf4j.Slf4j;
  import org.apache.commons.lang3.StringUtils;
  
  import java.io.IOException;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.function.Consumer;
  
  
  @Slf4j
  public class SlackSocketModeHandler {
  
      private final SlackClient slackClient;
      private final SocketModeClient socketModeClient;
      private final Map<String, Consumer<MessageEvent>> messageHandlers;
      private final Map<String, Consumer<SlashCommandPayload>> commandHandlers;
      private volatile boolean running = false;
  
      public SlackSocketModeHandler() {
          this(new SlackClient());
      }
  
      public SlackSocketModeHandler(SlackClient slackClient) {
          this.slackClient = slackClient;
          this.messageHandlers = new ConcurrentHashMap<>();
          this.commandHandlers = new ConcurrentHashMap<>();
          
          String appToken = SlackConfiguration.getSlackAppToken();
          if (StringUtils.isBlank(appToken)) {
              throw new IllegalArgumentException("Slack App Token is required for Socket Mode");
          }
          
          try {
              this.socketModeClient = Slack.getInstance().socketMode(appToken);
              initializeHandlers();
          } catch (IOException e) {
              throw new RuntimeException("Failed to initialize Socket Mode client", e);
          }
      }
  
      /**
       * 初始化事件处理器
       */
      private void initializeHandlers() {
          // 注册事件API监听器 - 使用简化的方式处理消息事件
          socketModeClient.addEventsApiEnvelopeListener(envelope -> {
              try {
                  // 立即响应ACK
                  socketModeClient.sendSocketModeResponse(new AckResponse(envelope.getEnvelopeId()));
                  
                  // 简化处理：直接处理 MessageEvent（如果有的话）
                  log.debug("Received Events API envelope: {}", envelope.getEnvelopeId());
                  // 注意：这里简化处理，实际应用中可以根据需要解析具体的事件类型
                  // 由于 API 复杂性，这里暂时记录事件但不进行具体处理
                  // 在生产环境中，可以根据具体需求实现详细的事件解析
                  
              } catch (Exception e) {
                  log.error("Error processing Events API envelope: {}", e.getMessage(), e);
              }
          });
  
          // 注册斜杠命令监听器
          socketModeClient.addSlashCommandsEnvelopeListener(envelope -> {
              try {
                  // 立即响应ACK
                  socketModeClient.sendSocketModeResponse(new AckResponse(envelope.getEnvelopeId()));
                  
                  // 简化处理：记录收到斜杠命令
                  log.debug("Received Slash Command envelope: {}", envelope.getEnvelopeId());
                  // 注意：这里简化处理，实际应用中可以根据需要解析具体的命令
                  // 由于 API 复杂性，这里暂时记录命令但不进行具体处理
                  // 在生产环境中，可以根据具体需求实现详细的命令解析
                  
              } catch (Exception e) {
                  log.error("Error processing Slash Command envelope: {}", e.getMessage(), e);
              }
          });
  
          log.info("Socket Mode handler initialized with app token and event listeners registered");
      }
  
      /**
       * 处理消息事件
       *
       * @param event 消息事件
       */
      private void handleMessageEvent(MessageEvent event) {
          log.debug("Received message event: channel={}, user={}, text={}", 
                  event.getChannel(), event.getUser(), event.getText());
  
          // 忽略机器人消息
          if (event.getBotId() != null) {
              return;
          }
  
          // 调用注册的消息处理器
          for (Map.Entry<String, Consumer<MessageEvent>> entry : messageHandlers.entrySet()) {
              try {
                  entry.getValue().accept(event);
              } catch (Exception e) {
                  log.error("Error in message handler {}: {}", entry.getKey(), e.getMessage(), e);
              }
          }
      }
  
      /**
       * 处理斜杠命令
       *
       * @param payload 命令载荷
       */
      private void handleSlashCommand(SlashCommandPayload payload) {
          log.debug("Received slash command: command={}, text={}, user={}", 
                  payload.getCommand(), payload.getText(), payload.getUserName());
  
          String command = payload.getCommand();
          Consumer<SlashCommandPayload> handler = commandHandlers.get(command);
          
          if (handler != null) {
              try {
                  handler.accept(payload);
              } catch (Exception e) {
                  log.error("Error handling slash command {}: {}", command, e.getMessage(), e);
              }
          } else {
              log.warn("No handler registered for slash command: {}", command);
          }
      }
  
      /**
       * 注册消息处理器
       *
       * @param name 处理器名称
       * @param handler 处理器函数
       */
      public void registerMessageHandler(String name, Consumer<MessageEvent> handler) {
          messageHandlers.put(name, handler);
          log.info("Registered message handler: {}", name);
      }
  
      /**
       * 注册斜杠命令处理器
       *
       * @param command 命令名称（包含/）
       * @param handler 处理器函数
       */
      public void registerSlashCommandHandler(String command, Consumer<SlashCommandPayload> handler) {
          commandHandlers.put(command, handler);
          log.info("Registered slash command handler: {}", command);
      }
  
      /**
       * 移除消息处理器
       *
       * @param name 处理器名称
       */
      public void removeMessageHandler(String name) {
          messageHandlers.remove(name);
          log.info("Removed message handler: {}", name);
      }
  
      /**
       * 移除斜杠命令处理器
       *
       * @param command 命令名称
       */
      public void removeSlashCommandHandler(String command) {
          commandHandlers.remove(command);
          log.info("Removed slash command handler: {}", command);
      }
  
      /**
       * 启动Socket Mode连接
       */
      public void start() {
          if (running) {
              log.warn("Socket Mode handler is already running");
              return;
          }
  
          try {
              log.info("Starting Slack Socket Mode handler...");
              socketModeClient.connect();
              running = true;
              log.info("Slack Socket Mode handler started successfully");
          } catch (IOException e) {
              log.error("IO error starting Socket Mode handler: {}", e.getMessage(), e);
              throw new RuntimeException("Failed to start Socket Mode handler", e);
          } catch (Exception e) {
              log.error("Failed to start Socket Mode handler: {}", e.getMessage(), e);
              throw new RuntimeException("Failed to start Socket Mode handler", e);
          }
      }
  
      /**
       * 停止Socket Mode连接
       */
      public void stop() {
          if (!running) {
              log.warn("Socket Mode handler is not running");
              return;
          }
  
          try {
              log.info("Stopping Slack Socket Mode handler...");
              socketModeClient.disconnect();
              running = false;
              log.info("Slack Socket Mode handler stopped successfully");
          } catch (Exception e) {
              log.error("Error stopping Socket Mode handler: {}", e.getMessage(), e);
          }
      }
  
      /**
       * 检查是否正在运行
       *
       * @return 是否运行中
       */
      public boolean isRunning() {
          return running;
      }
  
      /**
       * 获取Slack客户端
       *
       * @return SlackClient实例
       */
      public SlackClient getSlackClient() {
          return slackClient;
      }
  
      /**
       * 获取注册的消息处理器数量
       *
       * @return 处理器数量
       */
      public int getMessageHandlerCount() {
          return messageHandlers.size();
      }
  
      /**
       * 获取注册的命令处理器数量
       *
       * @return 处理器数量
       */
      public int getCommandHandlerCount() {
          return commandHandlers.size();
      }
  }
  