#!/usr/bin/env bash

# TaskSentinel - 企业微信和钉钉通知工具
# Copyright (c) 2025 TaskSentinel
# MIT License

# 严格模式设置
# 暂时禁用 set -e 以避免异步执行问题，但保留其他严格检查
set -uo pipefail

# 全局变量
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
readonly CONFIG_DIR="$PROJECT_ROOT/config"
readonly DEFAULT_CONFIG="$CONFIG_DIR/config.json"
readonly USER_CONFIG="$HOME/.tasksentry/config.json"
readonly LOG_DIR="$HOME/.tasksentry"
readonly LOG_FILE="$LOG_DIR/tasksentry.log"
readonly THROTTLE_RECORD_FILE="$LOG_DIR/last_notification_timestamp"

# 配置变量 (从config.json加载)
ENABLED_PLATFORMS=()
CONFIG_DEBUG="false"
THROTTLE_SECONDS="60"

# 程序版本
readonly VERSION="1.0.0"

# 事件处理变量
INPUT_DATA=""
PROCESSED_MESSAGE=""
EVENT_TYPE=""

# 确保日志目录存在
ensure_log_directory() {
    if [[ ! -d "$LOG_DIR" ]]; then
        if ! mkdir -p "$LOG_DIR" 2>/dev/null; then
            log_error "无法创建日志目录: $LOG_DIR"
            return 1
        fi
        log_debug "创建日志目录: $LOG_DIR"
    fi
    return 0
}

# 确保节流目录存在（和日志目录相同，但保持函数分离以符合设计）
ensure_throttle_directory() {
    if [[ ! -d "$LOG_DIR" ]]; then
        if ! mkdir -p "$LOG_DIR" 2>/dev/null; then
            log_error "无法创建节流记录目录: $LOG_DIR"
            return 1
        fi
        log_debug "创建节流记录目录: $LOG_DIR"
    fi
    return 0
}

# 生成消息内容的哈希值
generate_content_hash() {
    local message="$1"
    local hash
    
    # 优先使用SHA256，备选MD5
    if command -v sha256sum >/dev/null 2>&1; then
        hash=$(echo -n "$message" | sha256sum | cut -d' ' -f1)
    elif command -v shasum >/dev/null 2>&1; then
        hash=$(echo -n "$message" | shasum -a 256 | cut -d' ' -f1)
    elif command -v md5sum >/dev/null 2>&1; then
        hash=$(echo -n "$message" | md5sum | cut -d' ' -f1)
    elif command -v md5 >/dev/null 2>&1; then
        hash=$(echo -n "$message" | md5)
    else
        log_error "未找到可用的哈希工具 (sha256sum, shasum, md5sum, md5)"
        return 1
    fi
    
    echo "$hash"
}

# 读取上次通知记录
read_last_notification() {
    local timestamp=""
    local content_hash=""
    
    # 确保节流记录目录存在
    if ! ensure_throttle_directory; then
        return 1
    fi
    
    # 检查记录文件是否存在
    if [[ ! -f "$THROTTLE_RECORD_FILE" ]]; then
        log_debug "节流记录文件不存在: $THROTTLE_RECORD_FILE"
        return 1
    fi
    
    # 读取文件内容
    while IFS='=' read -r key value; do
        case "$key" in
            "timestamp")
                timestamp="$value"
                ;;
            "content_hash")
                content_hash="$value"
                ;;
        esac
    done < "$THROTTLE_RECORD_FILE"
    
    # 验证读取的数据
    if [[ -z "$timestamp" || -z "$content_hash" ]]; then
        log_debug "节流记录文件格式无效或数据不完整"
        return 1
    fi
    
    # 验证时间戳是否为数字
    if [[ ! "$timestamp" =~ ^[0-9]+$ ]]; then
        log_debug "节流记录中的时间戳格式无效: $timestamp"
        return 1
    fi
    
    log_debug "读取节流记录: timestamp=$timestamp, content_hash=${content_hash:0:16}..."
    
    # 导出到全局变量供调用者使用
    export LAST_NOTIFICATION_TIMESTAMP="$timestamp"
    export LAST_NOTIFICATION_HASH="$content_hash"
    
    return 0
}

# 保存通知记录
save_notification_record() {
    local timestamp="$1"
    local content_hash="$2"
    
    # 确保节流记录目录存在
    if ! ensure_throttle_directory; then
        log_error "无法创建节流记录目录，跳过记录保存"
        return 1
    fi
    
    # 写入记录文件
    if ! cat > "$THROTTLE_RECORD_FILE" << EOF
timestamp=$timestamp
content_hash=$content_hash
EOF
    then
        log_error "无法写入节流记录文件: $THROTTLE_RECORD_FILE"
        return 1
    fi
    
    log_debug "节流记录已保存: timestamp=$timestamp, content_hash=${content_hash:0:16}..."
    return 0
}

# 检查是否应该抑制通知（节流检查）
is_throttled() {
    local message="$1"
    local current_timestamp
    local current_hash
    local time_diff
    
    log_debug "开始节流检查..."
    
    # 获取当前时间戳（Unix时间戳，秒级）
    current_timestamp=$(date +%s)
    
    # 生成当前消息的哈希值
    current_hash=$(generate_content_hash "$message")
    if [[ -z "$current_hash" ]]; then
        log_error "无法生成消息哈希值，跳过节流检查"
        return 1  # 生成哈希失败，允许发送（降级处理）
    fi
    
    log_debug "当前消息哈希: ${current_hash:0:16}..."
    
    # 尝试读取上次通知记录
    if ! read_last_notification; then
        log_debug "无法读取上次通知记录（可能是首次运行），允许发送通知"
        return 1  # 无法读取记录，允许发送
    fi
    
    # 计算时间差
    time_diff=$((current_timestamp - LAST_NOTIFICATION_TIMESTAMP))
    log_debug "时间差: ${time_diff}秒 (阈值: ${THROTTLE_SECONDS}秒)"
    
    # 检查时间条件
    if [[ $time_diff -ge $THROTTLE_SECONDS ]]; then
        log_debug "时间间隔已达到阈值，允许发送通知"
        return 1  # 时间已到，允许发送
    fi
    
    # 检查内容是否相同
    if [[ "$current_hash" != "$LAST_NOTIFICATION_HASH" ]]; then
        log_debug "消息内容不同，允许发送通知"
        return 1  # 内容不同，允许发送
    fi
    
    # 时间未到且内容相同，抑制通知
    log_debug "节流条件触发: 时间未到($time_diff < $THROTTLE_SECONDS)且内容相同，抑制通知"
    return 0  # 抑制通知
}

# 获取时间戳
get_timestamp() {
    date '+%Y-%m-%d %H:%M:%S'
}

# 统一的日志记录函数（支持不同级别）
write_log() {
    local level="$1"
    local message="$2"
    local timestamp
    timestamp=$(get_timestamp)
    
    # 根据级别决定是否输出到stderr
    case "$level" in
        "DEBUG")
            # DEBUG级别只在调试模式下输出
            if [[ "${CONFIG_DEBUG:-false}" == "true" || "${DEBUG:-false}" == "true" ]]; then
                echo "[DEBUG] $message" >&2
            fi
            ;;
        "INFO")
            # INFO级别只在调试模式下输出到stderr
            if [[ "${CONFIG_DEBUG:-false}" == "true" || "${DEBUG:-false}" == "true" ]]; then
                echo "[INFO] $message" >&2
            fi
            ;;
        "ERROR")
            # ERROR级别始终输出到stderr
            echo "[ERROR] $message" >&2
            ;;
    esac
    
    # 如果配置启用了调试模式、命令行启用DEBUG、或者是ERROR级别，写入日志文件
    if [[ "${CONFIG_DEBUG:-false}" == "true" || "${DEBUG:-false}" == "true" || "$level" == "ERROR" ]]; then
        ensure_log_directory && {
            echo "[$timestamp] [$level] $message" >> "$LOG_FILE" 2>/dev/null || true
        }
    fi
}

# 增强的调试日志记录（向后兼容）
enhanced_log_debug() {
    write_log "DEBUG" "$*"
}

# 记录关键变量值到日志
log_variables() {
    local var_name="$1"
    local var_value="$2"
    
    write_log "DEBUG" "Variable: $var_name=$var_value"
}

# 记录curl命令和响应到日志
log_curl_command() {
    local curl_command="$1"
    local response="${2:-}"
    
    write_log "DEBUG" "Curl command: $curl_command"
    if [[ -n "$response" ]]; then
        write_log "DEBUG" "API response: $response"
    fi
}

# 日志函数（向后兼容）
log_debug() {
    write_log "DEBUG" "$*"
}

log_info() {
    write_log "INFO" "$*"
}

log_error() {
    write_log "ERROR" "$*"
}

# 显示帮助信息
show_help() {
    cat << EOF
使用方法: $SCRIPT_NAME [选项]

TaskSentinel - 企业微信和钉钉通知工具

选项:
    -h, --help              显示此帮助信息
    -v, --version           显示版本信息
    -c, --config FILE       指定配置文件路径 (默认: $DEFAULT_CONFIG)
    -m, --message TEXT      要发送的消息内容
    -t, --title TEXT        消息标题 (可选)
    -d, --debug             启用调试模式

示例:
    $SCRIPT_NAME --message "测试消息"
    $SCRIPT_NAME --config custom.json --message "自定义配置消息"
    $SCRIPT_NAME --message "带标题消息" --title "警告"

EOF
}

# 显示版本信息
show_version() {
    echo "$SCRIPT_NAME version $VERSION"
}

# 读取标准输入JSON数据
read_input() {
    log_debug "开始读取标准输入..."
    
    # 读取所有stdin内容到INPUT_DATA变量
    if ! INPUT_DATA=$(cat); then
        log_error "读取标准输入失败"
        exit 1
    fi
    
    log_debug "读取到的原始输入数据长度: ${#INPUT_DATA} 字符"
    
    # 检查输入是否为空
    if [[ -z "$INPUT_DATA" ]]; then
        # 如果读取到空内容，说明没有实际的stdin输入，返回特殊状态
        return 1
    fi
    
    # 去除前后空白字符
    INPUT_DATA=$(echo "$INPUT_DATA" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    
    # 再次检查去除空白后是否为空
    if [[ -z "$INPUT_DATA" ]]; then
        return 1
    fi
    
    # 验证输入是否为有效JSON
    if ! echo "$INPUT_DATA" | jq empty >/dev/null 2>&1; then
        log_error "输入数据不是有效的JSON格式"
        log_debug "无效的输入数据: $INPUT_DATA"
        exit 1
    fi
    
    log_debug "标准输入读取完成，JSON格式验证通过"
    return 0
}

# 解析JSON事件数据
parse_event_data() {
    log_debug "开始解析事件数据..."
    
    # 使用jq提取message字段
    local message
    message=$(echo "$INPUT_DATA" | jq -r '.message // empty' 2>/dev/null) || {
        log_error "无法从JSON中提取message字段"
        exit 1
    }
    
    # 使用jq提取event字段
    local event
    event=$(echo "$INPUT_DATA" | jq -r '.event // empty' 2>/dev/null) || {
        log_error "无法从JSON中提取event字段"
        exit 1
    }
    
    # 验证message字段不为空
    if [[ -z "$message" ]]; then
        log_error "JSON输入缺少必需的'message'字段或字段值为空"
        exit 1
    fi
    
    # 验证event字段不为空
    if [[ -z "$event" ]]; then
        log_error "JSON输入缺少必需的'event'字段或字段值为空"
        exit 1
    fi
    
    # 将解析的数据保存到全局变量中
    PROCESSED_MESSAGE="$message"
    EVENT_TYPE="$event"
    
    log_debug "事件数据解析完成: event=$EVENT_TYPE, message长度=${#PROCESSED_MESSAGE}"
}

# 处理事件消息内容
process_event() {
    log_debug "开始处理事件消息内容..."
    
    # 根据事件类型格式化消息内容
    case "$EVENT_TYPE" in
        "task_complete")
            PROCESSED_MESSAGE="✅ 任务完成: $PROCESSED_MESSAGE"
            ;;
        "error")
            PROCESSED_MESSAGE="❌ 错误: $PROCESSED_MESSAGE"
            ;;
        "info")
            PROCESSED_MESSAGE="ℹ️ 信息: $PROCESSED_MESSAGE"
            ;;
        "warning")
            PROCESSED_MESSAGE="⚠️ 警告: $PROCESSED_MESSAGE"
            ;;
        *)
            # 对于未知事件类型，保持原始消息内容不变
            log_debug "未知事件类型: $EVENT_TYPE，保持原始消息内容"
            ;;
    esac
    
    log_debug "消息处理完成: $PROCESSED_MESSAGE"
    log_debug "准备用于通知构建的消息文本已就绪"
}

# 检查依赖
check_dependencies() {
    local missing_deps=()
    
    # 检查必需的命令
    local required_commands=("jq" "curl")
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
            missing_deps+=("$cmd")
        fi
    done
    
    # 如果配置为钉钉平台且设置了secret，检查openssl
    if [[ "${PLATFORM:-}" == "dingtalk" && -n "${SECRET:-}" ]]; then
        if ! command -v "openssl" >/dev/null 2>&1; then
            missing_deps+=("openssl")
        fi
    fi
    
    if [[ ${#missing_deps[@]} -gt 0 ]]; then
        log_error "缺少必需的依赖: ${missing_deps[*]}"
        log_error "请安装以下工具后重试:"
        for dep in "${missing_deps[@]}"; do
            echo "  - $dep" >&2
        done
        exit 1
    fi
    
    log_debug "所有依赖检查通过"
}

# 解析命令行参数
parse_arguments() {
    local config_file="$USER_CONFIG"
    local message=""
    local title=""
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -v|--version)
                show_version
                exit 0
                ;;
            -c|--config)
                if [[ -z "${2:-}" ]]; then
                    log_error "选项 --config 需要参数"
                    exit 1
                fi
                config_file="$2"
                shift 2
                ;;
            -m|--message)
                if [[ -z "${2:-}" ]]; then
                    log_error "选项 --message 需要参数"
                    exit 1
                fi
                message="$2"
                shift 2
                ;;
            -t|--title)
                if [[ -z "${2:-}" ]]; then
                    log_error "选项 --title 需要参数"
                    exit 1
                fi
                title="$2"
                shift 2
                ;;
            -d|--debug)
                export DEBUG=true
                shift
                ;;
            *)
                log_error "未知选项: $1"
                log_error "使用 --help 查看帮助信息"
                exit 1
                ;;
        esac
    done
    
    # 导出解析后的参数供其他函数使用
    export CONFIG_FILE="$config_file"
    export MESSAGE="$message"
    export TITLE="$title"
}

# 验证必需字段
validate_required_field() {
    local field_name="$1"
    local field_value="$2"
    
    if [[ -z "$field_value" ]]; then
        log_error "配置文件缺少必需字段: $field_name"
        exit 1
    fi
}

# 验证平台字段值
validate_platform() {
    local platform="$1"
    local valid_platforms=("wechat" "dingtalk" "slack")
    
    for valid_platform in "${valid_platforms[@]}"; do
        if [[ "$platform" == "$valid_platform" ]]; then
            return 0
        fi
    done
    
    log_error "platform 字段值无效: $platform (必须是 'wechat'、'dingtalk' 或 'slack')"
    exit 1
}

# 验证格式字段值
validate_format() {
    local format="$1"
    local valid_formats=("text" "markdown" "json")
    
    for valid_format in "${valid_formats[@]}"; do
        if [[ "$format" == "$valid_format" ]]; then
            return 0
        fi
    done
    
    log_error "format 字段值无效: $format (必须是 'text'、'markdown' 或 'json')"
    exit 1
}

# 验证debug字段值
validate_debug() {
    local debug="$1"
    local valid_values=("true" "false")
    
    for valid_value in "${valid_values[@]}"; do
        if [[ "$debug" == "$valid_value" ]]; then
            return 0
        fi
    done
    
    log_error "debug 字段值无效: $debug (必须是 'true' 或 'false')"
    exit 1
}

# 验证throttle_seconds字段值
validate_throttle_seconds() {
    local throttle_seconds="$1"
    
    # 检查是否为正整数
    if [[ ! "$throttle_seconds" =~ ^[1-9][0-9]*$ ]]; then
        log_error "throttle_seconds 字段值无效: $throttle_seconds (必须是正整数)"
        return 1
    fi
    
    return 0
}

# 安全地提取JSON字段
extract_json_field() {
    local config_file="$1"
    local field_path="$2"
    local default_value="${3:-}"
    
    local value
    value=$(jq -r "${field_path} // empty" "$config_file" 2>/dev/null) || {
        log_error "配置文件解析失败: 无法读取 ${field_path} 字段"
        exit 1
    }
    
    if [[ -z "$value" && -n "$default_value" ]]; then
        echo "$default_value"
    else
        echo "$value"
    fi
}

# 加载配置文件
load_config() {
    local config_file="${CONFIG_FILE:-$USER_CONFIG}"
    
    log_debug "检查配置文件: $config_file"
    enhanced_log_debug "开始配置加载过程"
    log_variables "CONFIG_FILE" "$config_file"
    
    # 检查配置文件是否存在
    if [[ ! -f "$config_file" ]]; then
        log_error "配置文件不存在: $config_file"
        log_error "请创建配置文件并参考 $CONFIG_DIR/config.example.json"
        exit 1
    fi
    
    enhanced_log_debug "配置文件存在性检查通过"
    
    # 检查配置文件是否为有效的JSON
    if ! jq empty "$config_file" >/dev/null 2>&1; then
        log_error "配置文件格式无效: $config_file"
        log_error "请检查JSON语法是否正确"
        exit 1
    fi
    
    enhanced_log_debug "配置文件JSON格式验证通过"
    
    # 加载全局配置
    CONFIG_DEBUG=$(extract_json_field "$config_file" ".debug" "false")
    THROTTLE_SECONDS=$(extract_json_field "$config_file" ".throttle_seconds" "60")
    
    # 验证debug字段
    validate_debug "$CONFIG_DEBUG"
    
    # 验证throttle_seconds字段，如果验证失败则使用默认值
    if ! validate_throttle_seconds "$THROTTLE_SECONDS"; then
        log_debug "throttle_seconds验证失败，使用默认值60秒"
        THROTTLE_SECONDS="60"
    fi
    
    # 查找所有启用的平台
    local platforms=("dingtalk" "wechat" "slack")
    ENABLED_PLATFORMS=()
    
    for platform in "${platforms[@]}"; do
        local enabled
        enabled=$(extract_json_field "$config_file" ".platforms.$platform.enabled" "false")
        if [[ "$enabled" == "true" ]]; then
            ENABLED_PLATFORMS+=("$platform")
        fi
    done
    
    if [[ ${#ENABLED_PLATFORMS[@]} -eq 0 ]]; then
        log_error "没有启用的通知平台，请在配置文件中启用至少一个平台"
        exit 1
    fi
    
    log_debug "启用的平台: ${ENABLED_PLATFORMS[*]} (共 ${#ENABLED_PLATFORMS[@]} 个平台)"
    enhanced_log_debug "配置加载过程完成"
    
    # 如果配置中启用了debug，则设置全局DEBUG变量
    if [[ "$CONFIG_DEBUG" == "true" ]]; then
        export DEBUG=true
        enhanced_log_debug "根据配置文件启用调试模式"
    fi
}

# 获取指定平台的配置
get_platform_config() {
    local platform="$1"
    local config_file="${CONFIG_FILE:-$USER_CONFIG}"
    
    # 验证平台是否启用
    local enabled
    enabled=$(extract_json_field "$config_file" ".platforms.$platform.enabled" "false")
    if [[ "$enabled" != "true" ]]; then
        return 1
    fi
    
    # 提取平台配置并导出到全局变量
    PLATFORM="$platform"
    WEBHOOK_URL=$(extract_json_field "$config_file" ".platforms.$platform.webhook_url")
    SECRET=$(extract_json_field "$config_file" ".platforms.$platform.secret" "")
    FORMAT=$(extract_json_field "$config_file" ".platforms.$platform.format" "text")
    
    # 加载提及功能配置
    MENTIONS_ENABLED=$(extract_json_field "$config_file" ".platforms.$platform.mentions.enabled" "false")
    MENTIONS_DEFAULT_MENTION=$(extract_json_field "$config_file" ".platforms.$platform.mentions.default_mention" "")
    MENTIONS_USER_MAPPINGS=$(extract_json_field "$config_file" ".platforms.$platform.mentions.user_mappings" "{}")
    MENTIONS_EVENT_MENTIONS=$(extract_json_field "$config_file" ".platforms.$platform.mentions.event_mentions" "{}")
    
    # 验证必需字段
    if [[ -z "$WEBHOOK_URL" ]]; then
        log_error "平台 $platform 缺少 webhook_url 配置"
        return 1
    fi
    
    # 验证format字段
    validate_format "$FORMAT"
    
    log_debug "加载平台配置: $platform, format=$FORMAT"
    return 0
}

# 生成钉钉签名
generate_dingtalk_signature() {
    local secret="$1"
    local timestamp="$2"
    local signature_string
    local signature
    
    log_debug "开始生成钉钉签名..."
    log_debug "时间戳: $timestamp"
    
    # 构建签名字符串: timestamp + "\n" + secret
    signature_string="${timestamp}\n${secret}"
    log_debug "签名字符串长度: ${#signature_string}"
    
    # 使用HMAC-SHA256算法生成签名，然后Base64编码
    signature=$(echo -ne "$signature_string" | openssl dgst -sha256 -hmac "$secret" -binary | base64)
    
    if [[ -z "$signature" ]]; then
        log_error "签名生成失败"
        exit 1
    fi
    
    log_debug "签名生成成功"
    echo "$signature"
}

# 对钉钉URL进行签名
sign_dingtalk_url() {
    local webhook_url="$1"
    local secret="$2"
    local timestamp
    local signature
    local url_encoded_signature
    local signed_url
    
    log_debug "开始构建钉钉签名URL..."
    enhanced_log_debug "开始钉钉URL签名过程"
    log_variables "webhook_url" "${webhook_url:0:50}..."
    log_variables "secret" "${secret:+[已设置]}"
    
    # 生成当前时间戳（毫秒级）
    timestamp=$(date +%s000)
    log_debug "生成时间戳: $timestamp"
    log_variables "timestamp" "$timestamp"
    
    # 生成签名
    enhanced_log_debug "开始生成HMAC-SHA256签名"
    signature=$(generate_dingtalk_signature "$secret" "$timestamp")
    log_variables "signature" "${signature:0:20}..."
    
    # URL编码签名（处理特殊字符）
    url_encoded_signature=$(echo "$signature" | sed 's/+/%2B/g; s/=/%3D/g; s/\//%2F/g')
    log_debug "URL编码签名: $url_encoded_signature"
    enhanced_log_debug "签名URL编码完成"
    
    # 构建签名URL
    if [[ "$webhook_url" == *"?"* ]]; then
        # URL已包含参数，使用&连接
        signed_url="${webhook_url}&timestamp=${timestamp}&sign=${url_encoded_signature}"
        enhanced_log_debug "URL包含参数，使用&连接签名参数"
    else
        # URL不包含参数，使用?连接
        signed_url="${webhook_url}?timestamp=${timestamp}&sign=${url_encoded_signature}"
        enhanced_log_debug "URL不包含参数，使用?连接签名参数"
    fi
    
    log_debug "签名URL构建完成"
    enhanced_log_debug "钉钉URL签名过程完成"
    log_variables "signed_url_length" "${#signed_url}"
    
    echo "$signed_url"
}



# 生成@提及字符串
generate_mentions() {
    local event_type="$1"
    local mentions_text=""
    
    log_debug "开始生成@提及字符串，事件类型: $event_type"
    
    # 检查是否启用了提及功能
    if [[ "$MENTIONS_ENABLED" != "true" ]]; then
        log_debug "提及功能未启用"
        echo ""
        return 0
    fi
    
    # 获取当前事件类型对应的提及用户列表
    local mention_users
    mention_users=$(echo "$MENTIONS_EVENT_MENTIONS" | jq -r --arg event "$event_type" '.[$event] // empty' 2>/dev/null)
    
    if [[ -z "$mention_users" || "$mention_users" == "null" ]]; then
        # 如果没有配置特定事件的提及，使用默认提及
        mention_users="$MENTIONS_DEFAULT_MENTION"
        log_debug "使用默认提及配置: $mention_users"
    else
        log_debug "使用事件特定提及配置: $mention_users"
    fi
    
    # 解析提及用户列表
    if [[ -n "$mention_users" && "$mention_users" != "null" ]]; then
        local user_array
        # 先尝试解析为JSON数组，如果失败则当作单个字符串处理
        if echo "$mention_users" | jq empty >/dev/null 2>&1; then
            # 是有效的JSON，提取数组元素
            user_array=$(echo "$mention_users" | jq -r '.[]' 2>/dev/null)
        else
            # 不是JSON，直接作为单个用户处理
            user_array="$mention_users"
        fi
        
        while IFS= read -r user; do
            if [[ -n "$user" && "$user" != "null" ]]; then
                if [[ "$user" == "@all" ]]; then
                    # 特殊处理@all
                    mentions_text="@all "
                    break
                else
                    # 查找用户映射
                    local user_info
                    user_info=$(echo "$MENTIONS_USER_MAPPINGS" | jq -r --arg user "$user" '.[$user] // empty' 2>/dev/null)
                    
                    if [[ -n "$user_info" && "$user_info" != "null" ]]; then
                        local mobile
                        mobile=$(echo "$user_info" | jq -r '.mobile // empty' 2>/dev/null)
                        
                        if [[ -n "$mobile" && "$mobile" != "null" ]]; then
                            if [[ "$PLATFORM" == "dingtalk" ]]; then
                                # 钉钉格式: @手机号
                                mentions_text="${mentions_text}@${mobile} "
                            elif [[ "$PLATFORM" == "wechat" ]]; then
                                # 企业微信格式: <@手机号>
                                mentions_text="${mentions_text}<@${mobile}> "
                            fi
                        fi
                    else
                        # 如果没有找到映射，直接使用用户名
                        if [[ "$PLATFORM" == "dingtalk" ]]; then
                            mentions_text="${mentions_text}@${user} "
                        elif [[ "$PLATFORM" == "wechat" ]]; then
                            mentions_text="${mentions_text}<@${user}> "
                        fi
                    fi
                fi
            fi
        done <<< "$user_array"
    fi
    
    # 移除末尾的空格
    mentions_text=$(echo "$mentions_text" | sed 's/[[:space:]]*$//')
    
    log_debug "生成的@提及字符串: '$mentions_text'"
    echo "$mentions_text"
}

# 构建Markdown内容  
build_markdown_content() {
    local message="$1"
    local markdown_content
    local current_time
    local current_dir
    local original_data_section
    
    # 获取当前时间
    current_time=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 获取当前工作目录（如果在事件处理模式中，使用JSON中的cwd字段）
    if [[ -n "$INPUT_DATA" ]]; then
        current_dir=$(echo "$INPUT_DATA" | jq -r '.cwd // empty' 2>/dev/null)
        if [[ -z "$current_dir" ]]; then
            current_dir=$(pwd)
        fi
    else
        current_dir=$(pwd)
    fi
    
    # 检查是否有原始钩子数据，如果有则显示完整信息
    local original_hook_data
    if [[ -n "$INPUT_DATA" ]]; then
        original_hook_data=$(echo "$INPUT_DATA" | jq -r '.original_hook_data // empty' 2>/dev/null)
        if [[ -n "$original_hook_data" && "$original_hook_data" != "null" ]]; then
            # 格式化原始钩子数据
            local formatted_hook_data
            formatted_hook_data=$(echo "$original_hook_data" | jq '.' 2>/dev/null || echo "$original_hook_data")
            
            original_data_section=$(cat << EOF

### **🔌 Claude Code 完整钩子数据**

\`\`\`json
${formatted_hook_data}
\`\`\`
EOF
)
        else
            # 如果没有钩子数据，但有原始输入数据，则显示原始数据
            local formatted_json
            formatted_json=$(echo "$INPUT_DATA" | jq '.' 2>/dev/null || echo "$INPUT_DATA")
            
            original_data_section=$(cat << EOF

### **📋 完整原始数据**

\`\`\`json
${formatted_json}
\`\`\`
EOF
)
        fi
    else
        original_data_section=""
    fi
    
    # 构建Markdown模板（不包含@提及，因为markdown格式中的mentions通过各自平台的at字段处理）
    markdown_content=$(cat << EOF
## **TaskSentinel 通知**

**事件类型**: ${EVENT_TYPE:-通知}

**消息内容**: 
${message}

**时间**: ${current_time}  
**目录**: \`${current_dir}\`${original_data_section}

---
*TaskSentinel 自动通知系统*
EOF
)
    
    echo "$markdown_content"
}


# 构建钉钉文本格式payload
build_dingtalk_text_payload() {
    local message="$1"
    local payload
    local mentions_text
    local final_message
    local mention_mobiles
    
    # 生成@提及字符串
    mentions_text=$(generate_mentions "${EVENT_TYPE:-default}")
    
    # 如果有@提及，在消息前加上提及内容
    if [[ -n "$mentions_text" ]]; then
        final_message="${mentions_text}\n\n${message}"
    else
        final_message="$message"
    fi
    
    # 转义JSON特殊字符
    local escaped_message
    escaped_message=$(echo "$final_message" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\x08/\\b/g; s/\x0c/\\f/g; s/\n/\\n/g; s/\r/\\r/g; s/\x09/\\t/g')
    
    # 构建钉钉API要求的JSON格式
    # 注意：钉钉需要在at字段中指定提及的用户
    local at_section=""
    if [[ -n "$mentions_text" ]]; then
        if [[ "$mentions_text" == "@all" ]]; then
            at_section='"at": {"isAtAll": true},'
        else
            # 提取手机号码用于at字段
            mention_mobiles=$(echo "$mentions_text" | grep -oE '@[0-9]+' | sed 's/@//g' | tr '\n' ',' | sed 's/,$//')
            if [[ -n "$mention_mobiles" ]]; then
                at_section='"at": {"atMobiles": ["'$(echo "$mention_mobiles" | sed 's/,/","/g')'"], "isAtAll": false},'
            fi
        fi
    fi
    
    payload=$(cat << EOF
{
  "msgtype": "text",
  "text": {
    "content": "$escaped_message"
  }$(if [[ -n "$at_section" ]]; then echo ","; fi)
  $(if [[ -n "$at_section" ]]; then echo "$at_section"; fi)
}
EOF
)
    
    echo "$payload"
}

# 构建钉钉Markdown格式payload
build_dingtalk_markdown_payload() {
    local message="$1"
    local payload
    local markdown_content
    local notification_title
    local mentions_text
    local mention_mobiles
    
    # 构建Markdown内容
    markdown_content=$(build_dingtalk_markdown_content "$message")
    
    # 构建通知标题
    notification_title="TaskSentinel - ${EVENT_TYPE:-通知}"
    
    # 生成@提及字符串用于at字段
    mentions_text=$(generate_mentions "${EVENT_TYPE:-default}")
    
    # 转义JSON特殊字符
    local escaped_content
    local escaped_title
    escaped_content=$(echo "$markdown_content" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\x08/\\b/g; s/\x0c/\\f/g; s/\n/\\n/g; s/\r/\\r/g; s/\x09/\\t/g')
    escaped_title=$(echo "$notification_title" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\x08/\\b/g; s/\x0c/\\f/g; s/\n/\\n/g; s/\r/\\r/g; s/\x09/\\t/g')
    
    # 构建at字段
    local at_section=""
    if [[ -n "$mentions_text" ]]; then
        if [[ "$mentions_text" == "@all" ]]; then
            at_section='"at": {"isAtAll": true},'
        else
            # 提取手机号码用于at字段
            mention_mobiles=$(echo "$mentions_text" | grep -oE '@[0-9]+' | sed 's/@//g' | tr '\n' ',' | sed 's/,$//')
            if [[ -n "$mention_mobiles" ]]; then
                at_section='"at": {"atMobiles": ["'$(echo "$mention_mobiles" | sed 's/,/","/g')'"], "isAtAll": false},'
            fi
        fi
    fi
    
    # 构建钉钉Markdown API要求的JSON格式
    payload=$(cat << EOF
{
  "msgtype": "markdown",
  "markdown": {
    "title": "$escaped_title",
    "text": "$escaped_content"
  }$(if [[ -n "$at_section" ]]; then echo ","; fi)
  $(if [[ -n "$at_section" ]]; then echo "$at_section"; fi)
}
EOF
)
    
    echo "$payload"
}

# 构建钉钉专用Markdown内容
build_dingtalk_markdown_content() {
    local message="$1"
    local markdown_content
    local current_time
    local current_dir
    local original_data_section
    
    # 获取当前时间
    current_time=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 获取当前工作目录（如果在事件处理模式中，使用JSON中的cwd字段）
    if [[ -n "$INPUT_DATA" ]]; then
        current_dir=$(echo "$INPUT_DATA" | jq -r '.cwd // empty' 2>/dev/null)
        if [[ -z "$current_dir" ]]; then
            current_dir=$(pwd)
        fi
    else
        current_dir=$(pwd)
    fi
    
    # 检查是否有原始钩子数据，如果有则显示完整信息
    local original_hook_data
    if [[ -n "$INPUT_DATA" ]]; then
        original_hook_data=$(echo "$INPUT_DATA" | jq -r '.original_hook_data // empty' 2>/dev/null)
        if [[ -n "$original_hook_data" && "$original_hook_data" != "null" ]]; then
            # 格式化原始钩子数据
            local formatted_hook_data
            formatted_hook_data=$(echo "$original_hook_data" | jq '.' 2>/dev/null || echo "$original_hook_data")
            
            original_data_section=$(cat << EOF

### 🔌 Claude Code 完整钩子数据

\`\`\`json
${formatted_hook_data}
\`\`\`
EOF
)
        else
            # 如果没有钩子数据，但有原始输入数据，则显示原始数据
            local formatted_json
            formatted_json=$(echo "$INPUT_DATA" | jq '.' 2>/dev/null || echo "$INPUT_DATA")
            
            original_data_section=$(cat << EOF

### 📋 完整原始数据

\`\`\`json
${formatted_json}
\`\`\`
EOF
)
        fi
    else
        original_data_section=""
    fi
    
    # 构建钉钉专用Markdown模板（不包含@提及，因为markdown格式中的mentions通过at字段处理）
    markdown_content=$(cat << EOF
# TaskSentinel 通知

**事件类型**: ${EVENT_TYPE:-通知}

**消息内容**:  
${message}

**详细信息**:
- **时间**: ${current_time}
- **目录**: \`${current_dir}\`${original_data_section}

---
> TaskSentinel 自动通知系统
EOF
)
    
    echo "$markdown_content"
}

# 构建企业微信专用Markdown内容
build_wechat_markdown_content() {
    local message="$1"
    local markdown_content
    local current_time
    local current_dir
    local original_data_section
    
    # 获取当前时间
    current_time=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 获取当前工作目录（如果在事件处理模式中，使用JSON中的cwd字段）
    if [[ -n "$INPUT_DATA" ]]; then
        current_dir=$(echo "$INPUT_DATA" | jq -r '.cwd // empty' 2>/dev/null)
        if [[ -z "$current_dir" ]]; then
            current_dir=$(pwd)
        fi
    else
        current_dir=$(pwd)
    fi
    
    # 检查是否有原始钩子数据，如果有则显示完整信息
    local original_hook_data
    if [[ -n "$INPUT_DATA" ]]; then
        original_hook_data=$(echo "$INPUT_DATA" | jq -r '.original_hook_data // empty' 2>/dev/null)
        if [[ -n "$original_hook_data" && "$original_hook_data" != "null" ]]; then
            # 格式化原始钩子数据
            local formatted_hook_data
            formatted_hook_data=$(echo "$original_hook_data" | jq '.' 2>/dev/null || echo "$original_hook_data")
            
            original_data_section=$(cat << EOF

### 🔌 Claude Code 完整钩子数据

\`\`\`json
${formatted_hook_data}
\`\`\`
EOF
)
        else
            # 如果没有钩子数据，但有原始输入数据，则显示原始数据
            local formatted_json
            formatted_json=$(echo "$INPUT_DATA" | jq '.' 2>/dev/null || echo "$INPUT_DATA")
            
            original_data_section=$(cat << EOF

### 📋 完整原始数据

\`\`\`json
${formatted_json}
\`\`\`
EOF
)
        fi
    else
        original_data_section=""
    fi
    
    # 构建企业微信专用Markdown模板（不包含@提及，因为markdown格式不支持mentions）
    markdown_content=$(cat << EOF
# TaskSentinel 通知

**事件类型**: ${EVENT_TYPE:-通知}

**消息内容**:  
${message}

**详细信息**:
- **时间**: ${current_time}
- **目录**: \`${current_dir}\`${original_data_section}

---
> TaskSentinel 自动通知系统
EOF
)
    
    echo "$markdown_content"
}

# 构建企业微信payload
build_wechat_payload() {
    local message="$1"
    local payload
    
    log_debug "开始构建企业微信消息payload，格式：$FORMAT"
    
    case "$FORMAT" in
        "text")
            payload=$(build_wechat_text_payload "$message")
            ;;
        "markdown")
            payload=$(build_wechat_markdown_payload "$message")
            ;;
        *)
            log_error "企业微信不支持的消息格式: $FORMAT"
            exit 1
            ;;
    esac
    
    log_debug "企业微信payload构建完成"
    echo "$payload"
}

# 构建企业微信文本消息payload
build_wechat_text_payload() {
    local message="$1"
    local mentioned_list=()
    local mentioned_mobile_list=()
    local full_message="$message"
    local current_time
    local current_dir
    local original_data_section=""
    
    # 获取当前时间和目录信息
    current_time=$(date '+%Y-%m-%d %H:%M:%S')
    if [[ -n "$INPUT_DATA" ]]; then
        current_dir=$(echo "$INPUT_DATA" | jq -r '.cwd // empty' 2>/dev/null)
        if [[ -z "$current_dir" ]]; then
            current_dir=$(pwd)
        fi
    else
        current_dir=$(pwd)
    fi
    
    # 检查是否有原始钩子数据，如果有则添加到消息中
    local original_hook_data
    if [[ -n "$INPUT_DATA" ]]; then
        original_hook_data=$(echo "$INPUT_DATA" | jq -r '.original_hook_data // empty' 2>/dev/null)
        if [[ -n "$original_hook_data" && "$original_hook_data" != "null" ]]; then
            # 格式化原始钩子数据
            local formatted_hook_data
            formatted_hook_data=$(echo "$original_hook_data" | jq '.' 2>/dev/null || echo "$original_hook_data")
            
            original_data_section="

🔌 Claude Code 完整钩子数据:
${formatted_hook_data}"
        fi
    fi
    
    # 构建完整消息内容（包含时间、目录和原始数据）
    full_message="${message}

📅 时间: ${current_time}
📁 目录: ${current_dir}${original_data_section}

---
TaskSentinel 自动通知系统"
    
    # 处理@提及功能
    if [[ "$MENTIONS_ENABLED" == "true" ]]; then
        local mention_result
        mention_result=$(build_wechat_mentions)
        mentioned_list=($(echo "$mention_result" | jq -r '.mentioned_list[]? // empty'))
        mentioned_mobile_list=($(echo "$mention_result" | jq -r '.mentioned_mobile_list[]? // empty'))
        log_debug "企业微信@提及用户ID: ${mentioned_list[*]}"
        log_debug "企业微信@提及手机号: ${mentioned_mobile_list[*]}"
    fi
    
    # 构建企业微信text格式的JSON payload
    local payload
    if [[ ${#mentioned_list[@]} -gt 0 || ${#mentioned_mobile_list[@]} -gt 0 ]]; then
        local mentioned_list_json
        local mentioned_mobile_list_json
        
        # 正确处理空数组
        if [[ ${#mentioned_list[@]} -gt 0 ]]; then
            mentioned_list_json=$(printf '%s\n' "${mentioned_list[@]}" | jq -R . | jq -s .)
        else
            mentioned_list_json="[]"
        fi
        
        if [[ ${#mentioned_mobile_list[@]} -gt 0 ]]; then
            mentioned_mobile_list_json=$(printf '%s\n' "${mentioned_mobile_list[@]}" | jq -R . | jq -s .)
        else
            mentioned_mobile_list_json="[]"
        fi
        
        payload=$(jq -n \
            --arg content "$full_message" \
            --argjson mentioned_list "$mentioned_list_json" \
            --argjson mentioned_mobile_list "$mentioned_mobile_list_json" \
            '{
                "msgtype": "text",
                "text": {
                    "content": $content,
                    "mentioned_list": $mentioned_list,
                    "mentioned_mobile_list": $mentioned_mobile_list
                }
            }')
    else
        payload=$(jq -n \
            --arg content "$full_message" \
            '{
                "msgtype": "text",
                "text": {
                    "content": $content
                }
            }')
    fi
    
    echo "$payload"
}

# 构建企业微信Markdown消息payload
build_wechat_markdown_payload() {
    local message="$1"
    local markdown_content
    
    # 构建Markdown内容
    markdown_content=$(build_wechat_markdown_content "$message")
    
    # 构建企业微信markdown格式的JSON payload
    local payload
    payload=$(jq -n \
        --arg content "$markdown_content" \
        '{
            "msgtype": "markdown",
            "markdown": {
                "content": $content
            }
        }')
    
    echo "$payload"
}

# 构建企业微信@提及信息
build_wechat_mentions() {
    local mention_users=""
    local mentioned_list=()
    local mentioned_mobile_list=()
    
    # 根据事件类型获取需要@的用户
    if [[ -n "$EVENT_TYPE" && "$EVENT_TYPE" != "null" ]]; then
        mention_users=$(echo "$MENTIONS_EVENT_MENTIONS" | jq -r ".$EVENT_TYPE[]?" 2>/dev/null || echo "")
        if [[ -z "$mention_users" ]]; then
            mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
        fi
    else
        mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
    fi
    
    # 构建@提及列表（企业微信使用mentioned_list和mentioned_mobile_list字段）
    if [[ -n "$mention_users" ]]; then
        while IFS= read -r user; do
            if [[ -n "$user" && "$user" != "null" ]]; then
                if [[ "$user" == "@all" ]]; then
                    mentioned_list+=("@all")
                else
                    # 从用户映射中获取用户信息
                    local user_userid
                    local user_mobile
                    user_userid=$(echo "$MENTIONS_USER_MAPPINGS" | jq -r ".$user.userid // empty" 2>/dev/null)
                    user_mobile=$(echo "$MENTIONS_USER_MAPPINGS" | jq -r ".$user.mobile // empty" 2>/dev/null)
                    
                    # 企业微信优先使用userid，如果没有userid则使用手机号
                    if [[ -n "$user_userid" && "$user_userid" != "null" ]]; then
                        # 使用企业微信userid
                        mentioned_list+=("$user_userid")
                    fi
                    if [[ -n "$user_mobile" && "$user_mobile" != "null" ]]; then
                        # 添加手机号作为备选或主要方式（如果没有userid）
                        mentioned_mobile_list+=("$user_mobile")
                    fi
                fi
            fi
        done <<< "$mention_users"
    fi
    
    # 返回JSON格式的结果
    local mentioned_list_json
    local mentioned_mobile_list_json
    
    # 正确处理空数组
    if [[ ${#mentioned_list[@]} -gt 0 ]]; then
        mentioned_list_json=$(printf '%s\n' "${mentioned_list[@]}" | jq -R . | jq -s .)
    else
        mentioned_list_json="[]"
    fi
    
    if [[ ${#mentioned_mobile_list[@]} -gt 0 ]]; then
        mentioned_mobile_list_json=$(printf '%s\n' "${mentioned_mobile_list[@]}" | jq -R . | jq -s .)
    else
        mentioned_mobile_list_json="[]"
    fi
    
    jq -n \
        --argjson mentioned_list "$mentioned_list_json" \
        --argjson mentioned_mobile_list "$mentioned_mobile_list_json" \
        '{
            "mentioned_list": $mentioned_list,
            "mentioned_mobile_list": $mentioned_mobile_list
        }'
}

# 构建钉钉payload
build_dingtalk_payload() {
    local message="$1"
    local payload
    
    log_debug "开始构建钉钉消息payload，格式：$FORMAT"
    
    case "$FORMAT" in
        "text")
            payload=$(build_dingtalk_text_payload "$message")
            ;;
        "markdown")
            payload=$(build_dingtalk_markdown_payload "$message")
            ;;
        *)
            log_error "钉钉不支持的消息格式: $FORMAT"
            exit 1
            ;;
    esac
    
    log_debug "钉钉payload构建完成"
    echo "$payload"
}

# 构建钉钉文本消息payload
build_dingtalk_text_payload() {
    local message="$1"
    local mentions_text=""
    local full_message
    local mentioned_mobiles=()
    local at_all=false
    
    # 处理@提及功能
    if [[ "$MENTIONS_ENABLED" == "true" ]]; then
        local mention_result
        mention_result=$(build_dingtalk_mentions)
        mentions_text=$(echo "$mention_result" | jq -r '.text')
        mentioned_mobiles=($(echo "$mention_result" | jq -r '.mobiles[]? // empty'))
        at_all=$(echo "$mention_result" | jq -r '.atAll')
        log_debug "钉钉@提及文本: $mentions_text"
    fi
    
    # 构建完整消息内容
    if [[ -n "$mentions_text" ]]; then
        full_message="$mentions_text

$message"
    else
        full_message="$message"
    fi
    
    # 构建钉钉text格式的JSON payload
    local payload
    if [[ ${#mentioned_mobiles[@]} -gt 0 || "$at_all" == "true" ]]; then
        local mobiles_json
        
        # 正确处理空数组
        if [[ ${#mentioned_mobiles[@]} -gt 0 ]]; then
            mobiles_json=$(printf '%s\n' "${mentioned_mobiles[@]}" | jq -R . | jq -s .)
        else
            mobiles_json="[]"
        fi
        
        payload=$(jq -n \
            --arg content "$full_message" \
            --argjson mobiles "$mobiles_json" \
            --argjson atAll "$at_all" \
            '{
                "msgtype": "text",
                "text": {
                    "content": $content
                },
                "at": {
                    "atMobiles": $mobiles,
                    "isAtAll": $atAll
                }
            }')
    else
        payload=$(jq -n \
            --arg content "$full_message" \
            '{
                "msgtype": "text",
                "text": {
                    "content": $content
                }
            }')
    fi
    
    echo "$payload"
}

# 构建钉钉Markdown消息payload
build_dingtalk_markdown_payload() {
    local message="$1"
    local markdown_content
    local mentions_text=""
    local mentioned_mobiles=()
    local at_all=false
    
    # 构建Markdown内容
    markdown_content=$(build_dingtalk_markdown_content "$message")
    
    # 处理@提及功能
    if [[ "$MENTIONS_ENABLED" == "true" ]]; then
        local mention_result
        mention_result=$(build_dingtalk_mentions)
        mentions_text=$(echo "$mention_result" | jq -r '.text')
        mentioned_mobiles=($(echo "$mention_result" | jq -r '.mobiles[]? // empty'))
        at_all=$(echo "$mention_result" | jq -r '.atAll')
        log_debug "钉钉Markdown@提及文本: $mentions_text"
    fi
    
    # 如果有@提及，在Markdown内容前加上提及内容
    if [[ -n "$mentions_text" ]]; then
        markdown_content="$mentions_text

$markdown_content"
    fi
    
    # 构建钉钉markdown格式的JSON payload
    local payload
    if [[ ${#mentioned_mobiles[@]} -gt 0 || "$at_all" == "true" ]]; then
        local mobiles_json
        
        # 正确处理空数组
        if [[ ${#mentioned_mobiles[@]} -gt 0 ]]; then
            mobiles_json=$(printf '%s\n' "${mentioned_mobiles[@]}" | jq -R . | jq -s .)
        else
            mobiles_json="[]"
        fi
        
        payload=$(jq -n \
            --arg title "TaskSentinel通知" \
            --arg content "$markdown_content" \
            --argjson mobiles "$mobiles_json" \
            --argjson atAll "$at_all" \
            '{
                "msgtype": "markdown",
                "markdown": {
                    "title": $title,
                    "text": $content
                },
                "at": {
                    "atMobiles": $mobiles,
                    "isAtAll": $atAll
                }
            }')
    else
        payload=$(jq -n \
            --arg title "TaskSentinel通知" \
            --arg content "$markdown_content" \
            '{
                "msgtype": "markdown",
                "markdown": {
                    "title": $title,
                    "text": $content
                }
            }')
    fi
    
    echo "$payload"
}

# 构建钉钉@提及信息
build_dingtalk_mentions() {
    local mentions_text=""
    local mention_users=""
    local mentioned_mobiles=()
    local at_all=false
    
    # 根据事件类型获取需要@的用户
    if [[ -n "$EVENT_TYPE" && "$EVENT_TYPE" != "null" ]]; then
        mention_users=$(echo "$MENTIONS_EVENT_MENTIONS" | jq -r ".$EVENT_TYPE[]?" 2>/dev/null || echo "")
        if [[ -z "$mention_users" ]]; then
            mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
        fi
    else
        mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
    fi
    
    # 构建@提及文本和手机号列表
    if [[ -n "$mention_users" ]]; then
        while IFS= read -r user; do
            if [[ -n "$user" && "$user" != "null" ]]; then
                if [[ "$user" == "@all" ]]; then
                    mentions_text="@所有人 "
                    at_all=true
                else
                    # 从用户映射中获取用户信息
                    local user_mobile
                    user_mobile=$(echo "$MENTIONS_USER_MAPPINGS" | jq -r ".$user.mobile // empty" 2>/dev/null)
                    
                    # 钉钉要求：text中的@内容必须与at字段中的手机号一致
                    if [[ -n "$user_mobile" ]]; then
                        mentions_text="$mentions_text@$user_mobile "
                        mentioned_mobiles+=("$user_mobile")
                    fi
                fi
            fi
        done <<< "$mention_users"
    fi
    
    # 返回JSON格式的结果
    local mobiles_json
    
    # 正确处理空数组
    if [[ ${#mentioned_mobiles[@]} -gt 0 ]]; then
        mobiles_json=$(printf '%s\n' "${mentioned_mobiles[@]}" | jq -R . | jq -s .)
    else
        mobiles_json="[]"
    fi
    
    jq -n \
        --arg text "$mentions_text" \
        --argjson mobiles "$mobiles_json" \
        --argjson atAll "$at_all" \
        '{
            "text": $text,
            "mobiles": $mobiles,
            "atAll": $atAll
        }'
}

# 发送钉钉通知
send_dingtalk_notification() {
    local message="$1"
    local payload
    local final_webhook_url
    local curl_command
    local response
    
    log_debug "开始发送钉钉通知..."
    enhanced_log_debug "开始钉钉通知发送过程"
    
    # 构建payload
    payload=$(build_dingtalk_payload "$message")
    
    # 检查是否需要签名
    if [[ -n "${SECRET:-}" ]]; then
        log_debug "检测到secret配置，启用钉钉签名机制"
        enhanced_log_debug "启用钉钉签名机制"
        final_webhook_url=$(sign_dingtalk_url "$WEBHOOK_URL" "$SECRET")
        log_debug "使用签名URL发送钉钉通知"
    else
        log_debug "未配置secret，使用原始URL发送钉钉通知"
        enhanced_log_debug "使用原始URL，未启用签名"
        final_webhook_url="$WEBHOOK_URL"
    fi
    
    # 构建curl命令字符串用于日志记录
    curl_command="curl -s -X POST -H 'Content-Type: application/json' -d '[payload]' '$final_webhook_url'"
    
    # 如果启用调试模式，显示详细信息
    if [[ "${DEBUG:-false}" == "true" ]]; then
        log_debug "钉钉通知URL: $final_webhook_url"
        log_debug "钉钉payload: $payload"
    fi
    
    # 记录curl命令（不包含实际payload以节省空间）
    log_curl_command "$curl_command"
    enhanced_log_debug "准备异步执行钉钉通知发送"
    
    # 安全地异步执行curl命令，避免shell注入
    log_debug "异步执行钉钉通知发送..."
    {
        response=$(timeout 30 curl -s -X POST \
            --connect-timeout 10 \
            --max-time 30 \
            -H 'Content-Type: application/json' \
            -d "$payload" \
            "$final_webhook_url" 2>&1) || true
        
        # 记录API响应到日志文件
        if [[ "${CONFIG_DEBUG:-false}" == "true" ]]; then
            log_curl_command "钉钉API响应" "$response"
        fi
    } &
    local curl_pid=$!
    
    # 只在调试模式下输出发送信息，否则保持静默
    if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
        log_info "钉钉通知已异步发送 (PID: $curl_pid)"
    fi
    log_debug "钉钉通知发送完成"
    enhanced_log_debug "钉钉通知发送过程完成"
}

# 发送企业微信通知
send_wechat_notification() {
    local message="$1"
    local payload
    local curl_command
    local response
    
    log_debug "开始发送企业微信通知..."
    enhanced_log_debug "开始企业微信通知发送过程"
    
    # 构建payload
    payload=$(build_wechat_payload "$message")
    
    # 构建curl命令字符串用于日志记录
    curl_command="curl -s -X POST -H 'Content-Type: application/json' -d '[payload]' '$WEBHOOK_URL'"
    
    # 如果启用调试模式，显示详细信息
    if [[ "${DEBUG:-false}" == "true" ]]; then
        log_debug "企业微信通知URL: $WEBHOOK_URL"
        log_debug "企业微信payload: $payload"
    fi
    
    # 记录curl命令（不包含实际payload以节省空间）
    log_curl_command "$curl_command"
    enhanced_log_debug "准备异步执行企业微信通知发送"
    
    # 安全地异步执行curl命令，避免shell注入
    log_debug "异步执行企业微信通知发送..."
    {
        response=$(timeout 30 curl -s -X POST \
            --connect-timeout 10 \
            --max-time 30 \
            -H 'Content-Type: application/json' \
            -d "$payload" \
            "$WEBHOOK_URL" 2>&1) || true
        
        # 记录API响应到日志文件
        if [[ "${CONFIG_DEBUG:-false}" == "true" ]]; then
            log_curl_command "企业微信API响应" "$response"
        fi
    } &
    local curl_pid=$!
    
    # 只在调试模式下输出发送信息，否则保持静默
    if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
        log_info "企业微信通知已异步发送 (PID: $curl_pid)"
    fi
    log_debug "企业微信通知发送完成"
    enhanced_log_debug "企业微信通知发送过程完成"
}

# 构建Slack payload
build_slack_payload() {
    local message="$1"
    local payload
    
    log_debug "开始构建Slack消息payload，格式：$FORMAT"
    
    case "$FORMAT" in
        "text")
            payload=$(build_slack_text_payload "$message")
            ;;
        "json")
            payload=$(build_slack_json_payload "$message")
            ;;
        *)
            log_error "Slack不支持的消息格式: $FORMAT"
            exit 1
            ;;
    esac
    
    log_debug "Slack payload构建完成"
    echo "$payload"
}

# 构建Slack文本消息payload
build_slack_text_payload() {
    local message="$1"
    local mentions_text=""
    local full_message
    
    # 处理@提及功能
    if [[ "$MENTIONS_ENABLED" == "true" ]]; then
        mentions_text=$(build_slack_mentions)
        log_debug "Slack@提及文本: $mentions_text"
    fi
    
    # 构建完整消息内容
    if [[ -n "$mentions_text" ]]; then
        full_message="$mentions_text

$message"
    else
        full_message="$message"
    fi
    
    # 构建Slack简单文本格式的JSON payload
    local payload
    payload=$(jq -n \
        --arg text "$full_message" \
        '{
            "text": $text
        }')
    
    echo "$payload"
}

# 构建Slack JSON消息payload（支持富格式）
build_slack_json_payload() {
    local message="$1"
    local mentions_text=""
    local current_time
    local current_dir
    
    current_time=$(get_timestamp)
    current_dir=$(pwd)
    
    # 处理@提及功能
    if [[ "$MENTIONS_ENABLED" == "true" ]]; then
        mentions_text=$(build_slack_mentions)
        log_debug "Slack@提及文本: $mentions_text"
    fi
    
    # 构建Slack Blocks格式的JSON payload
    local payload
    if [[ -n "$mentions_text" ]]; then
        payload=$(jq -n \
            --arg mentions "$mentions_text" \
            --arg message "$message" \
            --arg event_type "${EVENT_TYPE:-通知}" \
            --arg timestamp "$current_time" \
            --arg directory "$current_dir" \
            '{
                "blocks": [
                    {
                        "type": "section",
                        "text": {
                            "type": "mrkdwn",
                            "text": $mentions
                        }
                    },
                    {
                        "type": "header",
                        "text": {
                            "type": "plain_text",
                            "text": "TaskSentinel 通知"
                        }
                    },
                    {
                        "type": "section",
                        "fields": [
                            {
                                "type": "mrkdwn",
                                "text": ("*事件类型:*\n" + $event_type)
                            },
                            {
                                "type": "mrkdwn",
                                "text": ("*时间:*\n" + $timestamp)
                            }
                        ]
                    },
                    {
                        "type": "section",
                        "text": {
                            "type": "mrkdwn",
                            "text": ("*消息内容:*\n" + $message)
                        }
                    },
                    {
                        "type": "context",
                        "elements": [
                            {
                                "type": "mrkdwn",
                                "text": ("📁 " + $directory)
                            }
                        ]
                    }
                ]
            }')
    else
        payload=$(jq -n \
            --arg message "$message" \
            --arg event_type "${EVENT_TYPE:-通知}" \
            --arg timestamp "$current_time" \
            --arg directory "$current_dir" \
            '{
                "blocks": [
                    {
                        "type": "header",
                        "text": {
                            "type": "plain_text",
                            "text": "TaskSentinel 通知"
                        }
                    },
                    {
                        "type": "section",
                        "fields": [
                            {
                                "type": "mrkdwn",
                                "text": ("*事件类型:*\n" + $event_type)
                            },
                            {
                                "type": "mrkdwn",
                                "text": ("*时间:*\n" + $timestamp)
                            }
                        ]
                    },
                    {
                        "type": "section",
                        "text": {
                            "type": "mrkdwn",
                            "text": ("*消息内容:*\n" + $message)
                        }
                    },
                    {
                        "type": "context",
                        "elements": [
                            {
                                "type": "mrkdwn",
                                "text": ("📁 " + $directory)
                            }
                        ]
                    }
                ]
            }')
    fi
    
    echo "$payload"
}

# 构建Slack@提及文本
build_slack_mentions() {
    local mentions_text=""
    local mention_users=""
    
    # 根据事件类型获取需要@的用户
    if [[ -n "$EVENT_TYPE" && "$EVENT_TYPE" != "null" ]]; then
        mention_users=$(echo "$MENTIONS_EVENT_MENTIONS" | jq -r ".$EVENT_TYPE[]?" 2>/dev/null || echo "")
        if [[ -z "$mention_users" ]]; then
            mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
        fi
    else
        mention_users=$(echo "$MENTIONS_DEFAULT_MENTION" | jq -r '.[]?' 2>/dev/null || echo "")
    fi
    
    # 构建@提及文本（Slack使用 <!channel> 或 <@userid> 格式）
    if [[ -n "$mention_users" ]]; then
        while IFS= read -r user; do
            if [[ -n "$user" && "$user" != "null" ]]; then
                if [[ "$user" == "@channel" || "$user" == "@all" ]]; then
                    mentions_text="<!channel> "
                else
                    # 从用户映射中获取用户信息
                    local user_info
                    user_info=$(echo "$MENTIONS_USER_MAPPINGS" | jq -r ".$user.name // empty" 2>/dev/null)
                    if [[ -n "$user_info" ]]; then
                        mentions_text="$mentions_text$user_info "
                    fi
                fi
            fi
        done <<< "$mention_users"
    fi
    
    echo "$mentions_text"
}

# 发送Slack通知
send_slack_notification() {
    local message="$1"
    local payload
    local curl_command
    local response
    
    log_debug "开始发送Slack通知..."
    enhanced_log_debug "开始Slack通知发送过程"
    
    # 构建payload
    payload=$(build_slack_payload "$message")
    
    # 构建curl命令字符串用于日志记录
    curl_command="curl -s -X POST -H 'Content-Type: application/json' -d '[payload]' '$WEBHOOK_URL'"
    
    # 如果启用调试模式，显示详细信息
    if [[ "${DEBUG:-false}" == "true" ]]; then
        log_debug "Slack通知URL: $WEBHOOK_URL"
        log_debug "Slack payload: $payload"
    fi
    
    # 记录curl命令（不包含实际payload以节省空间）
    log_curl_command "$curl_command"
    enhanced_log_debug "准备异步执行Slack通知发送"
    
    # 安全地异步执行curl命令，避免shell注入
    log_debug "异步执行Slack通知发送..."
    {
        response=$(timeout 30 curl -s -X POST \
            --connect-timeout 10 \
            --max-time 30 \
            -H 'Content-Type: application/json' \
            -d "$payload" \
            "$WEBHOOK_URL" 2>&1) || true
        
        # 记录API响应到日志文件
        if [[ "${CONFIG_DEBUG:-false}" == "true" ]]; then
            log_curl_command "Slack API响应" "$response"
        fi
    } &
    local curl_pid=$!
    
    # 只在调试模式下输出发送信息，否则保持静默
    if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
        log_info "Slack通知已异步发送 (PID: $curl_pid)"
    fi
    log_debug "Slack通知发送完成"
    enhanced_log_debug "Slack通知发送过程完成"
}

# 发送单个平台通知
send_single_platform_notification() {
    local platform="$1"
    local message="$2"
    
    log_debug "开始发送 $platform 平台通知..."
    
    # 加载该平台的配置
    if ! get_platform_config "$platform"; then
        log_error "无法加载平台 $platform 的配置"
        return 1
    fi
    
    log_debug "成功加载 $platform 平台配置"
    
    # 根据平台类型发送通知
    case "$platform" in
        "wechat")
            log_debug "发送企业微信通知"
            send_wechat_notification "$message"
            log_debug "企业微信通知发送函数返回"
            ;;
        "dingtalk")
            log_debug "发送钉钉通知"
            send_dingtalk_notification "$message"
            log_debug "钉钉通知发送函数返回"
            ;;
        "slack")
            log_debug "发送Slack通知"
            send_slack_notification "$message"
            log_debug "Slack通知发送函数返回"
            ;;
        *)
            log_error "不支持的平台类型: $platform"
            return 1
            ;;
    esac
    
    log_debug "$platform 平台通知发送完成，准备返回"
    return 0
}

# 通用通知发送函数（支持多平台）
send_notification() {
    local message="$1"
    local timestamp
    local content_hash
    local success_count=0
    local total_count=${#ENABLED_PLATFORMS[@]}
    
    log_debug "开始多平台通知发送流程..."
    log_debug "启用的平台: ${ENABLED_PLATFORMS[*]}"
    
    # 向所有启用的平台发送通知
    for platform in "${ENABLED_PLATFORMS[@]}"; do
        log_debug "正在向 $platform 平台发送通知..."
        log_debug "循环中: platform=$platform, success_count=$success_count"
        if send_single_platform_notification "$platform" "$message"; then
            ((success_count++))
            log_debug "$platform 平台通知发送成功，success_count=$success_count"
        else
            log_error "$platform 平台通知发送失败"
        fi
        log_debug "完成 $platform 平台处理，继续下一个平台..."
    done
    
    log_debug "多平台通知发送完成: 成功 $success_count/$total_count 个平台"
    
    # 如果至少有一个平台发送成功，则更新节流记录
    if [[ $success_count -gt 0 ]]; then
        timestamp=$(date +%s)
        content_hash=$(generate_content_hash "$message")
        
        if [[ -n "$content_hash" ]]; then
            if save_notification_record "$timestamp" "$content_hash"; then
                log_debug "节流记录更新成功"
            else
                log_debug "节流记录更新失败（但不影响通知发送）"
            fi
        else
            log_debug "无法生成消息哈希，跳过节流记录更新"
        fi
        
        log_debug "多平台通知发送流程完成"
        return 0
    else
        log_error "所有平台通知发送失败"
        return 1
    fi
}


# 主函数
main() {
    log_debug "启动 $SCRIPT_NAME"
    
    # 先检查基本依赖（jq和curl）
    local missing_deps=()
    local required_commands=("jq" "curl")
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
            missing_deps+=("$cmd")
        fi
    done
    
    if [[ ${#missing_deps[@]} -gt 0 ]]; then
        log_error "缺少必需的依赖: ${missing_deps[*]}"
        log_error "请安装以下工具后重试:"
        for dep in "${missing_deps[@]}"; do
            echo "  - $dep" >&2
        done
        exit 1
    fi
    
    # 先进行参数解析（这样--help和--version可以在配置加载前工作）
    parse_arguments "$@"
    
    # 检查是否有stdin输入（优先级高于命令行参数）
    # 只有在没有提供命令行消息参数时才尝试读取stdin
    local has_stdin_input=false
    if [[ -z "${MESSAGE:-}" && ! -t 0 ]]; then
        # stdin不是终端且没有命令行消息，尝试读取输入
        log_debug "检测到非终端标准输入且无命令行消息，尝试读取数据"
        
        if read_input; then
            has_stdin_input=true
            log_debug "检测到标准输入数据，切换到事件处理模式"
            
            # 解析事件数据
            parse_event_data
            process_event
            
            # 使用处理后的消息替换MESSAGE变量
            MESSAGE="$PROCESSED_MESSAGE"
            
            # 只在调试模式下输出事件处理信息
            if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
                log_info "事件处理完成: event=$EVENT_TYPE"
            fi
        else
            log_debug "未检测到有效的标准输入数据，使用命令行模式"
        fi
    elif [[ -n "${MESSAGE:-}" ]]; then
        log_debug "使用命令行提供的消息参数"
    fi
    
    # 如果没有stdin输入且没有提供命令行消息，显示帮助
    if [[ "$has_stdin_input" == "false" && -z "${MESSAGE:-}" ]]; then
        log_error "错误: 必须提供消息内容（通过 --message 参数或标准输入）"
        echo >&2
        show_help
        exit 1
    fi
    
    # 确定需要发送消息后，再加载配置文件
    load_config
    
    # 在配置加载后检查所有依赖（包括openssl）
    check_dependencies
    
    # 执行节流检查
    log_debug "执行节流检查..."
    if is_throttled "$MESSAGE"; then
        log_debug "节流触发，抑制通知发送（exit code 0）"
        if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
            log_info "通知被节流抑制（距离上次发送时间过短且内容相同）"
        fi
        exit 0
    fi
    log_debug "节流检查通过，继续发送通知"
    
    # 只在调试模式下输出详细信息，否则保持静默
    if [[ "${DEBUG:-false}" == "true" || "${CONFIG_DEBUG:-false}" == "true" ]]; then
        log_info "启用的平台: ${ENABLED_PLATFORMS[*]} (共 ${#ENABLED_PLATFORMS[@]} 个)"
        log_info "消息内容: $MESSAGE"
        
        if [[ -n "${TITLE:-}" ]]; then
            log_info "消息标题: $TITLE"
        fi
    fi
    
    # 发送通知（包含节流记录更新）
    send_notification "$MESSAGE"
    
    log_debug "$SCRIPT_NAME 执行完成"
    return 0
}

# 只有在直接执行时才运行主函数
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi