package shop.alien.store.aspect;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.annotation.Order;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import shop.alien.entity.store.*;
import shop.alien.mapper.*;
import shop.alien.store.annotation.TrackEvent;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.util.LifeDynamicsIdentityHelper;
import shop.alien.store.util.UserAgentParserUtil;
import shop.alien.util.common.JwtUtil;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 埋点事件切面
 * 拦截标注了@TrackEvent注解的方法，自动收集埋点数据并写入Redis List
 *
 * @author system
 * @since 2026-01-14
 */
@Slf4j
@Aspect
@Component
@Order(2)
@RequiredArgsConstructor
public class TrackEventAspect {

    private final BaseRedisService baseRedisService;
    private final ObjectMapper objectMapper;
    private final LifeUserDynamicsMapper lifeUserDynamicsMapper;
    private final CommonRatingMapper commonRatingMapper;
    private final StoreUserMapper storeUserMapper;
    private final StorePriceMapper storePriceMapper;
    private final StoreCuisineMapper storeCuisineMapper;
    private final LifeUserMapper lifeUserMapper;

    private final LifeDynamicsIdentityHelper dynamicsIdentityHelper;
    
    private final SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
    private final DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
    
    /**
     * Redis List Key
     */
    private static final String REDIS_QUEUE_KEY = "track:event:queue";

    /**
     * 定义切点：所有标注了@TrackEvent注解的方法
     */
    @Pointcut("@annotation(shop.alien.store.annotation.TrackEvent)")
    public void trackEventPointcut() {
    }

    /**
     * 环绕通知：收集埋点数据并写入Redis List
     */
    @Around("trackEventPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        TrackEvent annotation = method.getAnnotation(TrackEvent.class);

        if (annotation == null) {
            return joinPoint.proceed();
        }

        // 执行目标方法
        Object result = joinPoint.proceed();

        try {
            // 特殊处理：搜索接口需要为每个搜索结果中的店铺记录一条埋点
            String methodName = signature.getMethod().getName();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            
            if ("AiSearchController".equals(className) && "search".equals(methodName)) {
                // 搜索接口：为每个搜索结果中的店铺记录埋点
                handleSearchEventTracking(joinPoint, annotation, result);
            } else {
                // 其他接口：正常处理
                StoreTrackEvent trackEvent = buildTrackEvent(joinPoint, annotation, result);
                
                // 异步写入Redis List
                if (annotation.async()) {
                    String eventJson = objectMapper.writeValueAsString(trackEvent);
                    baseRedisService.setListRight(REDIS_QUEUE_KEY, eventJson);
                }
            }
        } catch (Exception e) {
            // 埋点失败不应该影响主流程
            log.error("收集埋点数据失败", e);
        }

        return result;
    }

    /**
     * 构建埋点事件对象
     */
    private StoreTrackEvent buildTrackEvent(ProceedingJoinPoint joinPoint, TrackEvent annotation, Object result) {
        StoreTrackEvent trackEvent = new StoreTrackEvent();
        
        // 设置基本事件信息
        trackEvent.setEventType(annotation.eventType());
        trackEvent.setEventCategory(annotation.eventCategory());
        trackEvent.setTargetType(StringUtils.isNotBlank(annotation.targetType()) ? annotation.targetType() : null);
        trackEvent.setEventTime(new Date());

        // 创建SpEL表达式上下文
        EvaluationContext context = createEvaluationContext(joinPoint, result);

        // 解析SpEL表达式获取storeId
        Integer storeId = null;
        if (StringUtils.isNotBlank(annotation.storeId())) {
            storeId = parseSpEL(annotation.storeId(), context, Integer.class);
            if (storeId == null) {
                // SpEL解析失败，记录详细信息用于调试
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                String methodName = signature.getMethod().getName();
                String className = joinPoint.getTarget().getClass().getSimpleName();
                log.warn("SpEL表达式解析失败: className={}, methodName={}, storeId表达式={}, 参数={}", 
                        className, methodName, annotation.storeId(), 
                        java.util.Arrays.toString(joinPoint.getArgs()));
            }
        }
        
        // 如果SpEL解析失败，尝试从方法参数中查找storeId
        if (storeId == null) {
            storeId = extractStoreIdFromArgs(joinPoint);
        }
        
        // 如果仍然为空，根据接口类型和参数查询店铺ID（业务逻辑查询）
        if (storeId == null) {
            storeId = queryStoreIdByBusinessLogic(joinPoint, annotation, context);
        }
        
        // 如果storeId仍为空，记录警告日志
        if (storeId == null) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            String methodName = signature.getMethod().getName();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            log.warn("无法获取storeId: className={}, methodName={}, storeId表达式={}", 
                    className, methodName, annotation.storeId());
        }
        
        trackEvent.setStoreId(storeId);

        // 解析SpEL表达式获取userId
        Integer userId = parseSpEL(annotation.userId(), context, Integer.class);
        if (userId == null) {
            // SpEL解析失败，尝试从phoneId格式的字符串中解析用户ID
            if (StringUtils.isNotBlank(annotation.userId())) {
                userId = queryUserIdByPhoneId(context, annotation.userId());
            }
            // 如果仍然为空，尝试从JWT中获取用户ID
            if (userId == null) {
                userId = getUserIdFromJWT();
            }
        }
        trackEvent.setUserId(userId);

        // 解析SpEL表达式获取targetId
        Integer targetId = parseSpEL(annotation.targetId(), context, Integer.class);
        trackEvent.setTargetId(targetId);

        // 获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            trackEvent.setIpAddress(getIpAddress(request));
            String userAgent = request.getHeader("User-Agent");
            trackEvent.setUserAgent(userAgent);
            // 根据User-Agent解析设备类型
            trackEvent.setDeviceType(shop.alien.store.util.UserAgentParserUtil.parseDeviceType(userAgent));
        }

        return trackEvent;
    }

    /**
     * 创建SpEL表达式上下文
     */
    private EvaluationContext createEvaluationContext(ProceedingJoinPoint joinPoint, Object result) {
        StandardEvaluationContext context = new StandardEvaluationContext();
        
        // 添加方法参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Object[] args = joinPoint.getArgs();
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        
        if (args != null) {
            if (parameterNames != null && parameterNames.length == args.length) {
                // 使用真实的参数名
                for (int i = 0; i < parameterNames.length; i++) {
                    context.setVariable(parameterNames[i], args[i]);
                }
            } else {
                // 如果参数名获取失败（可能是编译时没有保留参数名），使用类型推断
                Class<?>[] paramTypes = method.getParameterTypes();
                for (int i = 0; i < args.length && i < paramTypes.length; i++) {
                    Object arg = args[i];
                    if (arg != null) {
                        // 尝试使用类型名作为变量名（首字母小写）
                        String typeName = paramTypes[i].getSimpleName();
                        String varName = Character.toLowerCase(typeName.charAt(0)) + typeName.substring(1);
                        context.setVariable(varName, arg);
                        
                        // 同时尝试使用常见的参数名
                        if (arg instanceof StoreClockIn) {
                            context.setVariable("storeClockIn", arg);
                        } else if (arg instanceof StorePrice) {
                            context.setVariable("storePrice", arg);
                        } else if (arg instanceof StoreCuisine) {
                            context.setVariable("storeCuisine", arg);
                        }
                        
                        // 如果参数名存在，也设置
                        if (parameterNames != null && i < parameterNames.length) {
                            context.setVariable(parameterNames[i], arg);
                        }
                    }
                }
            }
        }
        
        // 添加返回值
        if (result != null) {
            context.setVariable("result", result);
        }

        return context;
    }

    /**
     * 解析SpEL表达式
     * 支持多种格式：
     * 1. #{#xxx} -> #xxx
     * 2. #{xxx} -> xxx
     * 3. #xxx -> #xxx
     * 4. 嵌套属性访问：#{#obj.field} -> #obj.field
     */
    private <T> T parseSpEL(String expression, EvaluationContext context, Class<T> clazz) {
        if (StringUtils.isBlank(expression)) {
            return null;
        }

        try {
            // 如果表达式不包含#，直接作为字符串处理
            if (!expression.contains("#")) {
                if (clazz == String.class) {
                    return clazz.cast(expression);
                }
                return null;
            }

            // 标准化SpEL表达式
            String normalizedExpression = normalizeSpELExpression(expression);
            
            // 解析SpEL表达式
            Object value = spelExpressionParser.parseExpression(normalizedExpression).getValue(context);
            if (value == null) {
                log.debug("SpEL表达式解析结果为null: 表达式={}, 标准化后={}", expression, normalizedExpression);
                return null;
            }

            // 类型转换
            return convertValue(value, clazz, expression);
        } catch (Exception e) {
            log.warn("解析SpEL表达式失败: 表达式={}, 错误={}", expression, e.getMessage());
            return null;
        }
    }
    
    /**
     * 标准化SpEL表达式
     */
    private String normalizeSpELExpression(String expression) {
        // 处理 #{#xxx} 格式，转换为 #xxx
        if (expression.startsWith("#{#") && expression.endsWith("}")) {
            return expression.substring(2, expression.length() - 1);
        }
        // 处理 #{xxx} 格式，转换为 xxx
        if (expression.startsWith("#{") && expression.endsWith("}")) {
            return expression.substring(2, expression.length() - 1);
        }
        // 如果已经是 #xxx 格式，直接返回
        return expression;
    }
    
    /**
     * 类型转换
     */
    @SuppressWarnings("unchecked")
    private <T> T convertValue(Object value, Class<T> clazz, String expression) {
        if (value == null) {
            return null;
        }
        
        if (clazz.isInstance(value)) {
            return (T) value;
        }
        
        // 类型转换
        if (clazz == Integer.class) {
            if (value instanceof Number) {
                return (T) Integer.valueOf(((Number) value).intValue());
            } else if (value instanceof String) {
                try {
                    return (T) Integer.valueOf((String) value);
                } catch (NumberFormatException e) {
                    log.debug("无法将字符串转换为Integer: {}", value);
                    return null;
                }
            }
        } else if (clazz == String.class) {
            return (T) value.toString();
        }
        
        return null;
    }

    /**
     * 从方法参数中提取storeId
     */
    private Integer extractStoreIdFromArgs(ProceedingJoinPoint joinPoint) {
        try {
            Object[] args = joinPoint.getArgs();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());

            if (args != null && parameterNames != null) {
                for (int i = 0; i < parameterNames.length; i++) {
                    // 查找名为storeId的参数
                    if ("storeId".equals(parameterNames[i]) && args[i] != null) {
                        if (args[i] instanceof Integer) {
                            return (Integer) args[i];
                        } else if (args[i] instanceof String) {
                            return Integer.parseInt((String) args[i]);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.debug("从方法参数中提取storeId失败", e);
        }
        return null;
    }

    /**
     * 根据业务逻辑查询店铺ID
     */
    private Integer queryStoreIdByBusinessLogic(ProceedingJoinPoint joinPoint, TrackEvent annotation, EvaluationContext context) {
        try {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            String methodName = signature.getMethod().getName();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            
            // 处理 /comment/like 接口（动态点赞）
            if ("LifeCommentController".equals(className) && "like".equals(methodName)) {
                return queryStoreIdForLike(context);
            }
            
            // 处理 /commonComment/addComment 接口（动态回复）
            if ("CommonCommentController".equals(className) && "addComment".equals(methodName)) {
                return queryStoreIdForAddComment(context);
            }
            
            // 处理 /user-violation/reporting 接口（举报）
            if ("UserViolationController".equals(className) && "reporting".equals(methodName)) {
                return queryStoreIdForReporting(context);
            }
            
            // 处理 /life-blacklist/blackList 接口（拉黑）
            if ("LifeBlacklistController".equals(className) && "blackList".equals(methodName)) {
                return queryStoreIdForBlackList(context);
            }
            
            // 处理 /userDynamics/addOrUpdate 接口（发布动态）
            if ("LifeUserDynamicsController".equals(className) && "addOrUpdate".equals(methodName)) {
                return queryStoreIdForAddOrUpdate(context);
            }
            
            // 处理 /store/price/getById 接口（查询通用价目详情）
            if ("StorePriceController".equals(className) && "getById".equals(methodName)) {
                return queryStoreIdForGetPriceById(context);
            }
            
            // 处理 /store/cuisine/getByCuisineType 接口（查询美食价目详情）
            if ("StoreCuisineController".equals(className) && "getByCuisineType".equals(methodName)) {
                return queryStoreIdForGetByCuisineType(context);
            }
            
            // 处理 /userDynamics/addTransferCount 接口（动态转发）
            if ("LifeUserDynamicsController".equals(className) && "addTransferCount".equals(methodName)) {
                return queryStoreIdForAddTransferCount(context);
            }
        } catch (Exception e) {
            log.debug("根据业务逻辑查询店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为点赞接口查询店铺ID
     */
    private Integer queryStoreIdForLike(EvaluationContext context) {
        try {
            // 获取type和huifuId参数
            Object typeObj = context.lookupVariable("type");
            Object huifuIdObj = context.lookupVariable("huifuId");
            
            if (typeObj == null || huifuIdObj == null) {
                return null;
            }
            
            String type = String.valueOf(typeObj);
            String huifuId = String.valueOf(huifuIdObj);
            
            // type=2 表示社区动态
            if ("2".equals(type)) {
                LifeUserDynamics dynamics = lifeUserDynamicsMapper.selectById(Integer.parseInt(huifuId));
                Integer storeId = dynamicsIdentityHelper.resolveStoreIdForTrack(dynamics);
                if (storeId != null) {
                    return storeId;
                }
            }
        } catch (Exception e) {
            log.debug("查询点赞接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为添加评论接口查询店铺ID
     */
    private Integer queryStoreIdForAddComment(EvaluationContext context) {
        try {
            // 获取commonComment参数
            Object commonCommentObj = context.lookupVariable("commonComment");
            if (commonCommentObj == null || !(commonCommentObj instanceof CommonComment)) {
                return null;
            }
            
            CommonComment commonComment = (CommonComment) commonCommentObj;
            
            // sourceType=1 表示评价的评论
            if (commonComment.getSourceType() != null && commonComment.getSourceType() == 1) {
                // sourceId是rating.id，通过CommonRating查询businessId（店铺ID）
                if (commonComment.getSourceId() != null) {
                    CommonRating rating = commonRatingMapper.selectById(commonComment.getSourceId());
                    if (rating != null && rating.getBusinessId() != null) {
                        return rating.getBusinessId();
                    }
                }
            }
            // sourceType=2 表示社区动态
            else if (commonComment.getSourceType() != null && commonComment.getSourceType() == 2) {
                // sourceId是动态ID，通过LifeUserDynamics查询店铺ID
                if (commonComment.getSourceId() != null) {
                    LifeUserDynamics dynamics = lifeUserDynamicsMapper.selectById(commonComment.getSourceId().intValue());
                    Integer storeId = dynamicsIdentityHelper.resolveStoreIdForTrack(dynamics);
                    if (storeId != null) {
                        return storeId;
                    }
                }
            }
        } catch (Exception e) {
            log.debug("查询添加评论接口的店铺ID失败", e);
        }
        return null;
    }

    /**
     * 为举报接口查询店铺ID
     */
    private Integer queryStoreIdForReporting(EvaluationContext context) {
        try {
            // 获取lifeUserViolation参数
            Object violationObj = context.lookupVariable("lifeUserViolation");
            if (violationObj == null || !(violationObj instanceof LifeUserViolation)) {
                return null;
            }
            
            LifeUserViolation violation = (LifeUserViolation) violationObj;
            
            // 根据reportContextType查询店铺ID
            String reportContextType = violation.getReportContextType();
            
            // reportContextType=2 表示动态
            if ("2".equals(reportContextType) && violation.getDynamicsId() != null) {
                LifeUserDynamics dynamics = lifeUserDynamicsMapper.selectById(Integer.parseInt(violation.getDynamicsId()));
                Integer storeId = dynamicsIdentityHelper.resolveStoreIdForTrack(dynamics);
                if (storeId != null) {
                    return storeId;
                }
            }
            // reportContextType=0 表示商户
            else if ("0".equals(reportContextType) && violation.getBusinessId() != null) {
                // businessId就是店铺ID
                return violation.getBusinessId();
            }
        } catch (Exception e) {
            log.debug("查询举报接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为发布动态接口查询店铺ID
     */
    private Integer queryStoreIdForAddOrUpdate(EvaluationContext context) {
        try {
            // 获取lifeUserDynamics参数
            Object dynamicsObj = context.lookupVariable("lifeUserDynamics");
            if (dynamicsObj == null || !(dynamicsObj instanceof LifeUserDynamics)) {
                return null;
            }
            
            LifeUserDynamics dynamics = (LifeUserDynamics) dynamicsObj;
            Integer storeId = dynamicsIdentityHelper.resolveStoreIdForTrack(dynamics);
            if (storeId != null) {
                return storeId;
            }
        } catch (Exception e) {
            log.debug("查询发布动态接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为拉黑接口查询店铺ID
     */
    private Integer queryStoreIdForBlackList(EvaluationContext context) {
        try {
            // 获取lifeBlacklist参数
            Object blacklistObj = context.lookupVariable("lifeBlacklist");
            if (blacklistObj == null || !(blacklistObj instanceof LifeBlacklist)) {
                return null;
            }
            
            LifeBlacklist blacklist = (LifeBlacklist) blacklistObj;
            
            // 如果拉黑方是商户（blockerType=1），通过blockerId查询店铺ID
            if ("1".equals(blacklist.getBlockerType()) && blacklist.getBlockerId() != null) {
                try {
                    Integer blockerId = Integer.parseInt(blacklist.getBlockerId());
                    StoreUser storeUser = storeUserMapper.selectById(blockerId);
                    if (storeUser != null && storeUser.getStoreId() != null) {
                        return storeUser.getStoreId();
                    }
                } catch (NumberFormatException e) {
                    log.debug("blockerId无法转换为Integer: {}", blacklist.getBlockerId());
                }
            }
            
            // 如果被拉黑方是商户（blockedType=1），通过blockedId查询店铺ID
            if ("1".equals(blacklist.getBlockedType()) && blacklist.getBlockedId() != null) {
                try {
                    Integer blockedId = Integer.parseInt(blacklist.getBlockedId());
                    StoreUser storeUser = storeUserMapper.selectById(blockedId);
                    if (storeUser != null && storeUser.getStoreId() != null) {
                        return storeUser.getStoreId();
                    }
                } catch (NumberFormatException e) {
                    log.debug("blockedId无法转换为Integer: {}", blacklist.getBlockedId());
                }
            }
        } catch (Exception e) {
            log.debug("查询拉黑接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为查询通用价目详情接口查询店铺ID
     */
    private Integer queryStoreIdForGetPriceById(EvaluationContext context) {
        try {
            // 获取id参数
            Object idObj = context.lookupVariable("id");
            if (idObj == null) {
                return null;
            }
            
            Integer id = null;
            if (idObj instanceof Integer) {
                id = (Integer) idObj;
            } else if (idObj instanceof Number) {
                id = ((Number) idObj).intValue();
            } else if (idObj instanceof String) {
                try {
                    id = Integer.parseInt((String) idObj);
                } catch (NumberFormatException e) {
                    log.debug("无法将id转换为Integer: {}", idObj);
                    return null;
                }
            }
            
            if (id != null) {
                // 通过id查询StorePrice表获取storeId
                StorePrice price = storePriceMapper.selectById(id);
                if (price != null && price.getStoreId() != null) {
                    return price.getStoreId();
                }
            }
        } catch (Exception e) {
            log.debug("查询通用价目详情接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为查询美食价目详情接口查询店铺ID
     */
    private Integer queryStoreIdForGetByCuisineType(EvaluationContext context) {
        try {
            // 获取id参数
            Object idObj = context.lookupVariable("id");
            if (idObj == null) {
                return null;
            }
            
            Integer id = null;
            if (idObj instanceof Integer) {
                id = (Integer) idObj;
            } else if (idObj instanceof Number) {
                id = ((Number) idObj).intValue();
            } else if (idObj instanceof String) {
                try {
                    id = Integer.parseInt((String) idObj);
                } catch (NumberFormatException e) {
                    log.debug("无法将id转换为Integer: {}", idObj);
                    return null;
                }
            }
            
            if (id != null) {
                // 通过id查询StoreCuisine表获取storeId
                StoreCuisine cuisine = storeCuisineMapper.selectById(id);
                if (cuisine != null && cuisine.getStoreId() != null) {
                    return cuisine.getStoreId();
                }
            }
        } catch (Exception e) {
            log.debug("查询美食价目详情接口的店铺ID失败", e);
        }
        return null;
    }
    
    /**
     * 为动态转发接口查询店铺ID
     */
    private Integer queryStoreIdForAddTransferCount(EvaluationContext context) {
        try {
            // 获取id参数（动态ID）
            Object idObj = context.lookupVariable("id");
            if (idObj == null) {
                return null;
            }
            
            Integer dynamicsId = null;
            if (idObj instanceof Integer) {
                dynamicsId = (Integer) idObj;
            } else if (idObj instanceof Number) {
                dynamicsId = ((Number) idObj).intValue();
            } else if (idObj instanceof String) {
                try {
                    dynamicsId = Integer.parseInt((String) idObj);
                } catch (NumberFormatException e) {
                    log.debug("无法将id转换为Integer: {}", idObj);
                    return null;
                }
            }
            
            if (dynamicsId != null) {
                LifeUserDynamics dynamics = lifeUserDynamicsMapper.selectById(dynamicsId);
                Integer storeId = dynamicsIdentityHelper.resolveStoreIdForTrack(dynamics);
                if (storeId != null) {
                    return storeId;
                }
            }
        } catch (Exception e) {
            log.debug("查询动态转发接口的店铺ID失败", e);
        }
        return null;
    }

    /**
     * 从phoneId格式的字符串中解析用户ID
     * phoneId格式：user_手机号 或 store_手机号
     */
    private Integer queryUserIdByPhoneId(EvaluationContext context, String userIdExpression) {
        try {
            // 先尝试从SpEL表达式中获取原始值（String类型）
            String phoneId = parseSpEL(userIdExpression, context, String.class);
            if (phoneId == null) {
                return null;
            }
            
            // 判断是普通用户还是店铺用户
            if (phoneId.startsWith("user_")) {
                // 普通用户：user_手机号
                String phone = phoneId.substring(5); // 去掉 "user_" 前缀
                LambdaQueryWrapper<LifeUser> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(LifeUser::getUserPhone, phone)
                        .eq(LifeUser::getDeleteFlag, 0);
                LifeUser lifeUser = lifeUserMapper.selectOne(wrapper);
                if (lifeUser != null && lifeUser.getId() != null) {
                    return lifeUser.getId();
                }
            } else if (phoneId.startsWith("store_")) {
                // 店铺用户：store_手机号
                String phone = phoneId.substring(6); // 去掉 "store_" 前缀
                LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StoreUser::getPhone, phone)
                        .eq(StoreUser::getDeleteFlag, 0);
                StoreUser storeUser = storeUserMapper.selectOne(wrapper);
                if (storeUser != null && storeUser.getId() != null) {
                    return storeUser.getId();
                }
            } else {
                // 如果不是phoneId格式，尝试直接转换为Integer
                try {
                    return Integer.parseInt(phoneId);
                } catch (NumberFormatException e) {
                    log.debug("无法将userId转换为Integer: {}", phoneId);
                }
            }
        } catch (Exception e) {
            log.debug("从phoneId解析用户ID失败: expression={}", userIdExpression, e);
        }
        return null;
    }
    
    /**
     * 从JWT中获取用户ID
     */
    private Integer getUserIdFromJWT() {
        try {
            JSONObject userInfo = JwtUtil.getCurrentUserInfo();
            if (userInfo != null && userInfo.get("userId") != null) {
                Object userIdObj = userInfo.get("userId");
                if (userIdObj instanceof Integer) {
                    return (Integer) userIdObj;
                } else if (userIdObj instanceof String) {
                    return Integer.parseInt((String) userIdObj);
                }
            }
        } catch (Exception e) {
            log.debug("从JWT获取用户ID失败", e);
        }
        return null;
    }

    /**
     * 获取客户端IP地址
     */
    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 如果是多级代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
    
    /**
     * 处理搜索接口的埋点：为每个搜索结果中的店铺记录一条埋点
     */
    private void handleSearchEventTracking(ProceedingJoinPoint joinPoint, TrackEvent annotation, Object result) {
        try {
            // 获取返回结果
            if (!(result instanceof shop.alien.entity.result.R)) {
                log.debug("搜索接口返回结果不是R类型，跳过埋点");
                return;
            }
            
            @SuppressWarnings("unchecked")
            shop.alien.entity.result.R<Object> r = (shop.alien.entity.result.R<Object>) result;
            
            if (r.getData() == null) {
                log.debug("搜索接口返回结果data为空，跳过埋点");
                return;
            }
            
            // 处理 fastjson2 的 JSONObject
            com.alibaba.fastjson2.JSONObject data;
            if (r.getData() instanceof com.alibaba.fastjson2.JSONObject) {
                data = (com.alibaba.fastjson2.JSONObject) r.getData();
            } else {
                // 如果不是 JSONObject，尝试转换
                log.debug("搜索接口返回结果data不是JSONObject类型，跳过埋点");
                return;
            }
            
            // 提取所有店铺ID
            java.util.Set<Integer> storeIds = new java.util.HashSet<>();
            
            // 从matchedRecords中提取店铺ID
            JSONArray matchedRecords = data.getJSONArray("matchedRecords");
            if (matchedRecords != null) {
                for (int i = 0; i < matchedRecords.size(); i++) {
                    com.alibaba.fastjson2.JSONObject store = matchedRecords.getJSONObject(i);
                    if (store != null) {
                        // id可能是字符串或数字，需要处理
                        Object idObj = store.get("id");
                        Integer storeId = parseStoreId(idObj);
                        if (storeId != null) {
                            storeIds.add(storeId);
                        }
                    }
                }
            }
            
            // 从relatedRecords中提取店铺ID
            JSONArray relatedRecords = data.getJSONArray("relatedRecords");
            if (relatedRecords != null) {
                for (int i = 0; i < relatedRecords.size(); i++) {
                    com.alibaba.fastjson2.JSONObject store = relatedRecords.getJSONObject(i);
                    if (store != null) {
                        // id可能是字符串或数字，需要处理
                        Object idObj = store.get("id");
                        Integer storeId = parseStoreId(idObj);
                        if (storeId != null) {
                            storeIds.add(storeId);
                        }
                    }
                }
            }
            
            // 为每个店铺创建一条埋点事件
            if (storeIds.isEmpty()) {
                log.debug("搜索接口未找到店铺ID，跳过埋点");
                return;
            }
            
            // 获取基础信息（用户ID、IP、User-Agent等）
            EvaluationContext context = createEvaluationContext(joinPoint, result);
            Integer userId = parseSpEL(annotation.userId(), context, Integer.class);
            if (userId == null && StringUtils.isBlank(annotation.userId())) {
                userId = getUserIdFromJWT();
            }
            
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String ipAddress = null;
            String userAgent = null;
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                ipAddress = getIpAddress(request);
                userAgent = request.getHeader("User-Agent");
            }
            
            // 为每个店铺创建埋点事件
            for (Integer storeId : storeIds) {
                StoreTrackEvent trackEvent = new StoreTrackEvent();
                trackEvent.setEventType(annotation.eventType());
                trackEvent.setEventCategory(annotation.eventCategory());
                trackEvent.setTargetType(StringUtils.isNotBlank(annotation.targetType()) ? annotation.targetType() : null);
                trackEvent.setEventTime(new Date());
                trackEvent.setStoreId(storeId);
                trackEvent.setUserId(userId);
                trackEvent.setTargetId(storeId); // 搜索的店铺ID作为targetId
                trackEvent.setIpAddress(ipAddress);
                trackEvent.setUserAgent(userAgent);
                trackEvent.setDeviceType(UserAgentParserUtil.parseDeviceType(userAgent));
                
                // 异步写入Redis List
                if (annotation.async()) {
                    String eventJson = objectMapper.writeValueAsString(trackEvent);
                    baseRedisService.setListRight(REDIS_QUEUE_KEY, eventJson);
                }
            }
            
            log.debug("搜索接口埋点完成，共记录{}个店铺的埋点数据", storeIds.size());
        } catch (Exception e) {
            log.error("处理搜索接口埋点失败", e);
        }
    }
    
    /**
     * 解析店铺ID（支持字符串和数字类型）
     */
    private Integer parseStoreId(Object idObj) {
        if (idObj == null) {
            return null;
        }
        if (idObj instanceof Integer) {
            return (Integer) idObj;
        }
        if (idObj instanceof Number) {
            return ((Number) idObj).intValue();
        }
        if (idObj instanceof String) {
            try {
                return Integer.parseInt((String) idObj);
            } catch (NumberFormatException e) {
                log.debug("无法将字符串转换为店铺ID: {}", idObj);
                return null;
            }
        }
        return null;
    }
}