package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.*;
import shop.alien.mapper.*;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.service.TrackEventService;
import shop.alien.store.util.LifeDynamicsIdentityHelper;
import shop.alien.util.type.LifeFansIdentityQuery;
import shop.alien.util.type.TypeUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 埋点事件服务实现类
 *
 * @author system
 * @since 2026-01-14
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class TrackEventServiceImpl extends ServiceImpl<StoreTrackEventMapper, StoreTrackEvent> implements TrackEventService {

    private final BaseRedisService baseRedisService;
    private final StoreTrackStatisticsMapper trackStatisticsMapper;
    private final ObjectMapper objectMapper;
    
    // 新增依赖：用于查询其他表数据
    private final StoreUserMapper storeUserMapper;
    private final LifeFansMapper lifeFansMapper;
    private final TypeUtil typeUtil;
    private final LifeUserDynamicsMapper lifeUserDynamicsMapper;

    private final LifeDynamicsIdentityHelper dynamicsIdentityHelper;
    private final CommonRatingMapper commonRatingMapper;
    private final StoreCommentAppealMapper storeCommentAppealMapper;
    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
    private final LifeDiscountCouponStoreFriendMapper lifeDiscountCouponStoreFriendMapper;
    private final LifeBlacklistMapper lifeBlacklistMapper;
    private final LifeUserMapper lifeUserMapper;
    private final StoreInfoMapper storeInfoMapper;
    
    private static final String REDIS_QUEUE_KEY = "track:event:queue";

    @Override
    public void saveTrackEvent(StoreTrackEvent trackEvent) {
        try {
            String eventJson = objectMapper.writeValueAsString(trackEvent);
            baseRedisService.setListRight(REDIS_QUEUE_KEY, eventJson);
        } catch (Exception e) {
            log.error("写入Redis List失败", e);
            throw new RuntimeException("写入Redis List失败", e);
        }
    }

    @Override
    public void batchSaveTrackEvents(List<StoreTrackEvent> trackEvents) {
        if (trackEvents == null || trackEvents.isEmpty()) {
            return;
        }

        try {
            boolean result = this.saveBatch(trackEvents, 100);
            log.info("批量保存埋点事件: 总数={}, 成功={}", trackEvents.size(), result);
        } catch (Exception e) {
            log.error("批量保存埋点事件失败", e);
            throw new RuntimeException("批量保存埋点事件失败", e);
        }
    }

    @Override
    public void calculateAndSaveStatistics(Integer storeId, Date statDate, String statType) {
        log.info("开始计算统计数据: storeId={}, statDate={}, statType={}", storeId, statDate, statType);

        try {
            // 计算统计日期范围
            java.util.Calendar cal = java.util.Calendar.getInstance();
            Date startDate;
            Date endDate;
            
            // 根据统计类型确定日期范围
            if ("DAILY".equals(statType)) {
                // 日统计：从当天 00:00:00 到 23:59:59
                cal.setTime(statDate);
                cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
                cal.set(java.util.Calendar.MINUTE, 0);
                cal.set(java.util.Calendar.SECOND, 0);
                cal.set(java.util.Calendar.MILLISECOND, 0);
                startDate = cal.getTime();
                
                cal.add(java.util.Calendar.DAY_OF_MONTH, 1);
                endDate = cal.getTime(); // 下一天的 00:00:00，使用 .lt() 查询
            } else if ("WEEKLY".equals(statType)) {
                // 周统计：从周一（statDate）00:00:00 到周日 23:59:59
                cal.setTime(statDate);
                cal.set(java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.MONDAY);
                cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
                cal.set(java.util.Calendar.MINUTE, 0);
                cal.set(java.util.Calendar.SECOND, 0);
                cal.set(java.util.Calendar.MILLISECOND, 0);
                startDate = cal.getTime();
                
                cal.add(java.util.Calendar.DAY_OF_WEEK, 7);
                endDate = cal.getTime(); // 下周一的 00:00:00，使用 .lt() 查询
            } else if ("MONTHLY".equals(statType)) {
                // 月统计：从月初 00:00:00 到月末 23:59:59
                cal.setTime(statDate);
                cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
                cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
                cal.set(java.util.Calendar.MINUTE, 0);
                cal.set(java.util.Calendar.SECOND, 0);
                cal.set(java.util.Calendar.MILLISECOND, 0);
                startDate = cal.getTime();
                
                cal.add(java.util.Calendar.MONTH, 1);
                endDate = cal.getTime(); // 下个月1号的 00:00:00，使用 .lt() 查询
            } else {
                // 默认：日统计
                cal.setTime(statDate);
                cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
                cal.set(java.util.Calendar.MINUTE, 0);
                cal.set(java.util.Calendar.SECOND, 0);
                cal.set(java.util.Calendar.MILLISECOND, 0);
                startDate = cal.getTime();
                
                cal.add(java.util.Calendar.DAY_OF_MONTH, 1);
                endDate = cal.getTime();
            }
            
            log.info("统计日期范围: startDate={}, endDate={}", startDate, endDate);
        
        // 查询或创建统计记录
        LambdaQueryWrapper<StoreTrackStatistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreTrackStatistics::getStoreId, storeId)
                .eq(StoreTrackStatistics::getStatDate, statDate)
                .eq(StoreTrackStatistics::getStatType, statType);
        
        StoreTrackStatistics statistics = trackStatisticsMapper.selectOne(queryWrapper);
        if (statistics == null) {
            statistics = new StoreTrackStatistics();
            statistics.setStoreId(storeId);
            statistics.setStatDate(statDate);
            statistics.setStatType(statType);
        }
        
            // 优化：直接使用数据库聚合查询，不再加载所有事件到内存
            // 按事件分类统计（符合文档格式）
            Map<String, Object> trafficData = calculateTrafficData(storeId, startDate, endDate);
            Map<String, Object> interactionData = calculateInteractionData(storeId, startDate, endDate);
            Map<String, Object> couponData = calculateCouponData(storeId, startDate, endDate);
            Map<String, Object> voucherData = calculateVoucherData(storeId, startDate, endDate);
            Map<String, Object> serviceData = calculateServiceData(storeId, startDate, endDate);
            List<Map<String, Object>> priceData = calculatePriceRankingData(storeId, startDate, endDate);

            // 设置统计数据（JSON格式）
            statistics.setTrafficData(objectMapper.writeValueAsString(trafficData));
            statistics.setInteractionData(objectMapper.writeValueAsString(interactionData));
            statistics.setCouponData(objectMapper.writeValueAsString(couponData));
            statistics.setVoucherData(objectMapper.writeValueAsString(voucherData));
            statistics.setServiceData(objectMapper.writeValueAsString(serviceData));
            statistics.setPriceRankingData(objectMapper.writeValueAsString(priceData));
            
            // 输出统计结果（用于调试）
            log.info("统计结果 - trafficData: {}", objectMapper.writeValueAsString(trafficData));
            log.info("统计结果 - interactionData: {}", objectMapper.writeValueAsString(interactionData));
            log.info("统计结果 - voucherData: {}", objectMapper.writeValueAsString(voucherData));
            log.info("统计结果 - serviceData: {}", objectMapper.writeValueAsString(serviceData));
            log.info("统计结果 - priceRankingData: {}", objectMapper.writeValueAsString(priceData));
        
        // 保存统计记录
        if (statistics.getId() == null) {
            trackStatisticsMapper.insert(statistics);
                log.info("统计数据保存成功: storeId={}, statDate={}, statType={}", storeId, statDate, statType);
        } else {
            trackStatisticsMapper.updateById(statistics);
                log.info("统计数据更新成功: storeId={}, statDate={}, statType={}", storeId, statDate, statType);
            }
        } catch (Exception e) {
            log.error("计算统计数据失败: storeId={}, statDate={}, statType={}", storeId, statDate, statType, e);
            throw new RuntimeException("计算统计数据失败", e);
        }
    }

    /**
     * 计算流量数据- 优化：使用数据库聚合查询
     */
    private Map<String, Object> calculateTrafficData(Integer storeId, Date startDate, Date endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            StoreTrackEventMapper mapper = this.getBaseMapper();
        
            // 使用数据库聚合查询统计流量数据（累计数据，截至到endDate）
            Map<String, Object> trafficStats = mapper.calculateTrafficStatistics(storeId, endDate);
        
        // 搜索量
            Object searchCountObj = trafficStats.get("searchCount");
            long searchCount = searchCountObj != null ? ((Number) searchCountObj).longValue() : 0L;
        result.put("searchCount", searchCount);
        
        // 浏览量
            Object viewCountObj = trafficStats.get("viewCount");
            long viewCount = viewCountObj != null ? ((Number) viewCountObj).longValue() : 0L;
        result.put("viewCount", viewCount);
            
            // 访客数（去重userId）- 累计数据，截至到endDate
            Long visitorCount = mapper.countDistinctVisitors(storeId, endDate);
            result.put("visitorCount", visitorCount != null ? visitorCount : 0L);
            
            // 新增访客数（统计时间段内首次访问的用户，即在startDate之前没有访问记录的用户）
            Long newVisitorCount = mapper.countNewVisitors(storeId, startDate, endDate);
            result.put("newVisitorCount", newVisitorCount != null ? newVisitorCount : 0L);
            
            // 总访问时长
            Object totalDurationObj = trafficStats.get("totalDuration");
            long totalDuration = totalDurationObj != null ? ((Number) totalDurationObj).longValue() : 0L;
        result.put("totalDuration", totalDuration);
        
        // 平均访问时长
            Object avgDurationObj = trafficStats.get("avgDuration");
            long avgDuration = avgDurationObj != null ? ((Number) avgDurationObj).longValue() : 0L;
        result.put("avgDuration", avgDuration);
            
            log.debug("流量数据统计完成: searchCount={}, viewCount={}, visitorCount={}, newVisitorCount={}", 
                    searchCount, viewCount, visitorCount, newVisitorCount);
        } catch (Exception e) {
            log.error("计算流量数据失败: storeId={}", storeId, e);
            // 返回默认值，避免统计失败
            result.put("searchCount", 0L);
            result.put("viewCount", 0L);
            result.put("visitorCount", 0L);
            result.put("newVisitorCount", 0L);
            result.put("totalDuration", 0L);
            result.put("avgDuration", 0L);
        }
        
        return result;
    }
    
    /**
     * 计算互动数据- 优化：使用数据库聚合查询
     */
    private Map<String, Object> calculateInteractionData(Integer storeId, Date startDate, Date endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            StoreTrackEventMapper mapper = this.getBaseMapper();
            
            // 使用数据库聚合查询统计互动事件（累计数据，截至到endDate）
            List<Map<String, Object>> interactionStats = mapper.calculateInteractionStatistics(storeId, endDate);
            
            // 将查询结果转换为Map，便于查找
            // 注意：SQL返回的字段名是下划线命名(event_type)，而非驼峰命名
            Map<String, Long> eventTypeCountMap = new HashMap<>();
            for (Map<String, Object> stat : interactionStats) {
                String eventType = (String) stat.get("event_type");
                Object countObj = stat.get("count");
                long count = countObj != null ? ((Number) countObj).longValue() : 0L;
                if (eventType != null) {
                    eventTypeCountMap.put(eventType, count);
                }
            }
            
            // 从聚合查询结果中获取各类型事件数量（从埋点事件表store_track_event中统计）
            result.put("collectCount", eventTypeCountMap.getOrDefault("COLLECT", 0L));
            result.put("shareCount", eventTypeCountMap.getOrDefault("SHARE", 0L));
            result.put("checkinCount", eventTypeCountMap.getOrDefault("CHECKIN", 0L));
            result.put("consultCount", eventTypeCountMap.getOrDefault("CONSULT", 0L));
            result.put("postLikeCount", eventTypeCountMap.getOrDefault("POST_LIKE", 0L));
            result.put("postCommentCount", eventTypeCountMap.getOrDefault("POST_COMMENT", 0L));
            result.put("postRepostCount", eventTypeCountMap.getOrDefault("POST_REPOST", 0L));
            result.put("reportCount", eventTypeCountMap.getOrDefault("REPORT", 0L));
            result.put("blockCount", eventTypeCountMap.getOrDefault("BLOCK", 0L));
            
            // 记录调试日志
            log.debug("互动数据统计结果: storeId={}, 统计到的事件类型={}, 各类型数量={}", 
                    storeId, eventTypeCountMap.keySet(), eventTypeCountMap);
            
            // 从其他表查询的数据（life_fans表使用phoneId关联）
            String storePhoneId = getStorePhoneId(storeId);
            log.debug("获取店铺phoneId: storeId={}, storePhoneId={}", storeId, storePhoneId);
            if (storePhoneId != null) {
                long friendCount = calculateFriendCount(storePhoneId, startDate, endDate);
                long followCount = calculateFollowCount(storePhoneId, startDate, endDate);
                long fansCount = calculateFansCount(storePhoneId, startDate, endDate);
                result.put("friendCount", friendCount);
                result.put("followCount", followCount);
                result.put("fansCount", fansCount);
                log.debug("好友/关注/粉丝数量: storeId={}, phoneId={}, friendCount={}, followCount={}, fansCount={}", 
                        storeId, storePhoneId, friendCount, followCount, fansCount);
            } else {
                log.warn("无法获取店铺phoneId: storeId={}", storeId);
                result.put("friendCount", 0L);
                result.put("followCount", 0L);
                result.put("fansCount", 0L);
            }
            result.put("postCount", calculatePostCount(storeId, startDate, endDate));
        } catch (Exception e) {
            log.error("计算互动数据失败: storeId={}", storeId, e);
            // 返回默认值
            result.put("collectCount", 0L);
            result.put("shareCount", 0L);
            result.put("checkinCount", 0L);
            result.put("consultCount", 0L);
            result.put("postLikeCount", 0L);
            result.put("postCommentCount", 0L);
            result.put("postRepostCount", 0L);
            result.put("reportCount", 0L);
            result.put("blockCount", 0L);
        result.put("friendCount", 0L);
        result.put("followCount", 0L);
        result.put("fansCount", 0L);
        result.put("postCount", 0L);
        }
        
        return result;
    }
    
    /**
     * 获取店铺的phoneId（格式：store_手机号）
     */
    private String getStorePhoneId(Integer storeId) {
        try {
            LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreUser::getStoreId, storeId)
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1");
            StoreUser storeUser = storeUserMapper.selectOne(wrapper);
            if (storeUser != null && storeUser.getPhone() != null) {
                return "store_" + storeUser.getPhone();
            }
        } catch (Exception e) {
            log.error("获取店铺phoneId失败: storeId={}", storeId, e);
        }
        return null;
    }
    
    /**
     * 计算好友数量（互相关注的用户数）
     * 注意：好友数量是累计数据，统计截止到endDate的所有互相关注关系
     * 需要过滤被拉黑的用户，与用户资料页面保持一致
     */
    private long calculateFriendCount(String storePhoneId, Date startDate, Date endDate) {
        try {
            // 获取店铺的拉黑信息（用于过滤被拉黑的用户）
            StoreUser storeUser = getStoreUserByPhoneId(storePhoneId);
            if (storeUser == null) {
                return 0L;
            }
            String blockerType = "1"; // 店铺类型
            String blockerId = String.valueOf(storeUser.getId());
            
            // 获取被拉黑的用户ID集合
            Set<String> blockedUserIds = getBlockedUserIds(blockerType, blockerId);
            
            // 查询店铺关注的所有用户（截止到统计日期）
            LifeFansIdentityQuery.Scope storeScope = LifeFansIdentityQuery.resolve(storePhoneId, typeUtil);
            LambdaQueryWrapper<LifeFans> followWrapper = new LambdaQueryWrapper<>();
            followWrapper.lt(LifeFans::getCreatedTime, endDate).eq(LifeFans::getDeleteFlag, 0);
            LifeFansIdentityQuery.applyFansSide(followWrapper, storeScope);
            Set<String> followedIds = lifeFansMapper.selectList(followWrapper).stream()
                    .map(LifeFans::getFollowedId)
                    .filter(id -> isUserValid(id) && !isBlocked(id, blockedUserIds))
                    .collect(Collectors.toSet());
            
            if (followedIds.isEmpty()) {
                return 0L;
            }
            
            // 查询关注店铺的所有用户（截止到统计日期）
            LambdaQueryWrapper<LifeFans> fansWrapper = new LambdaQueryWrapper<>();
            fansWrapper.lt(LifeFans::getCreatedTime, endDate).eq(LifeFans::getDeleteFlag, 0);
            LifeFansIdentityQuery.applyFollowedSide(fansWrapper, storeScope);
            Set<String> fansIds = lifeFansMapper.selectList(fansWrapper).stream()
                    .map(LifeFans::getFansId)
                    .filter(id -> isUserValid(id) && !isBlocked(id, blockedUserIds))
                    .collect(Collectors.toSet());
            
            // 互相关注的用户数 = 交集
            followedIds.retainAll(fansIds);
            return followedIds.size();
        } catch (Exception e) {
            log.error("计算好友数量失败: storePhoneId={}", storePhoneId, e);
            return 0L;
        }
    }
    
    /**
     * 计算关注数量（店铺用户关注的人数）
     * 注意：关注数量是累计数据，统计截止到endDate的所有关注关系
     * 需要过滤被拉黑的用户，与用户资料页面保持一致
     */
    private long calculateFollowCount(String storePhoneId, Date startDate, Date endDate) {
        try {
            // 获取店铺的拉黑信息（用于过滤被拉黑的用户）
            StoreUser storeUser = getStoreUserByPhoneId(storePhoneId);
            if (storeUser == null) {
                return 0L;
            }
            String blockerType = "1"; // 店铺类型
            String blockerId = String.valueOf(storeUser.getId());
            
            // 获取被拉黑的用户ID集合
            Set<String> blockedUserIds = getBlockedUserIds(blockerType, blockerId);
            
            // 查询店铺关注的所有用户（截止到统计日期），并过滤被拉黑的用户
            LifeFansIdentityQuery.Scope storeScope = LifeFansIdentityQuery.resolve(storePhoneId, typeUtil);
            LambdaQueryWrapper<LifeFans> wrapper = new LambdaQueryWrapper<>();
            wrapper.lt(LifeFans::getCreatedTime, endDate).eq(LifeFans::getDeleteFlag, 0);
            LifeFansIdentityQuery.applyFansSide(wrapper, storeScope);
            List<LifeFans> fansList = lifeFansMapper.selectList(wrapper);

            // 过滤被拉黑的用户和已删除的用户
            long count = fansList.stream()
                    .map(LifeFans::getFollowedId)
                    .filter(id -> isUserValid(id) && !isBlocked(id, blockedUserIds))
                    .count();

            return count;
        } catch (Exception e) {
            log.error("计算关注数量失败: storePhoneId={}", storePhoneId, e);
            return 0L;
        }
    }

    /**
     * 计算粉丝数量（关注店铺用户的人数）
     * 注意：粉丝数量是累计数据，统计截止到endDate的所有粉丝关系
     * 需要过滤被拉黑的用户，与用户资料页面保持一致
     */
    private long calculateFansCount(String storePhoneId, Date startDate, Date endDate) {
        try {
            // 获取店铺的拉黑信息（用于过滤被拉黑的用户）
            StoreUser storeUser = getStoreUserByPhoneId(storePhoneId);
            if (storeUser == null) {
                return 0L;
            }
            String blockerType = "1"; // 店铺类型
            String blockerId = String.valueOf(storeUser.getId());
            
            // 获取被拉黑的用户ID集合
            Set<String> blockedUserIds = getBlockedUserIds(blockerType, blockerId);
            
            // 查询关注店铺的所有用户（截止到统计日期），并过滤被拉黑的用户
            LifeFansIdentityQuery.Scope storeScope = LifeFansIdentityQuery.resolve(storePhoneId, typeUtil);
            LambdaQueryWrapper<LifeFans> wrapper = new LambdaQueryWrapper<>();
            wrapper.lt(LifeFans::getCreatedTime, endDate).eq(LifeFans::getDeleteFlag, 0);
            LifeFansIdentityQuery.applyFollowedSide(wrapper, storeScope);
            List<LifeFans> fansList = lifeFansMapper.selectList(wrapper);
            
            // 过滤被拉黑的用户和已删除的用户
            long count = fansList.stream()
                    .map(LifeFans::getFansId)
                    .filter(id -> isUserValid(id) && !isBlocked(id, blockedUserIds))
                    .count();
            
            return count;
        } catch (Exception e) {
            log.error("计算粉丝数量失败: storePhoneId={}", storePhoneId, e);
            return 0L;
        }
    }
    
    /**
     * 计算发布动态数量（从life_user_dynamics表查询，type=2商家社区）
     */
    private long calculatePostCount(Integer storeId, Date startDate, Date endDate) {
        try {
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
                    .eq(StoreUser::getStoreId, storeId)
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1"));
            if (storeUser == null || storeUser.getId() == null) {
                return 0L;
            }

            LambdaQueryWrapper<LifeUserDynamics> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(LifeUserDynamics::getPhoneUserType, LifeDynamicsIdentityHelper.TYPE_STORE)
                    .eq(LifeUserDynamics::getPhoneRefId, storeUser.getId())
                    .eq(LifeUserDynamics::getType, "2")
                    .eq(LifeUserDynamics::getDraft, 0)
                    .lt(LifeUserDynamics::getCreatedTime, endDate)
                    .eq(LifeUserDynamics::getDeleteFlag, 0);
            return lifeUserDynamicsMapper.selectCount(wrapper);
        } catch (Exception e) {
            log.error("计算发布动态数量失败: storeId={}", storeId, e);
            return 0L;
        }
    }
    
    /**
     * 计算优惠券数据
     */
    private Map<String, Object> calculateCouponData(Integer storeId, Date startDate, Date endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 赠送好友数量：从 LifeDiscountCoupon 查店铺优惠券 id，再按优惠券 id 查 LifeDiscountCouponStoreFriend 记录数

            List<LifeDiscountCouponStoreFriend> giveToFriendRecords = queryGiveToFriendRecordsByStore(storeId, endDate);
            long giveToFriendCount = giveToFriendRecords.size();
            result.put("giveToFriendCount", giveToFriendCount);

            // 赠送好友金额合计：用 LifeDiscountCouponStoreFriend 的券 id 和数量(singleQty)，从 LifeDiscountCoupon 取面值，计算面值金额合计

            BigDecimal giveToFriendAmount = giveToFriendRecords.stream()
                    .map(record -> {
                        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(record.getCouponId());
                        BigDecimal faceValue = coupon != null && coupon.getNominalValue() != null ? coupon.getNominalValue() : BigDecimal.ZERO;
                        int qty = record.getSingleQty() != null && record.getSingleQty() > 0 ? record.getSingleQty() : 0;
                        return faceValue.multiply(BigDecimal.valueOf(qty));
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            result.put("giveToFriendAmount", giveToFriendAmount);

            // 赠送好友使用数/使用金额：从 life_discount_coupon_user 统计
            String storeIdStr = String.valueOf(storeId);
            List<LifeDiscountCouponUser> couponUsers = queryCouponUsersByStore(storeIdStr, endDate);
            
            // 赠送好友使用数量（status=1已使用的数量）
            long giveToFriendUseCount = couponUsers.stream()
                    .filter(cu -> cu.getStatus() != null && cu.getStatus() == 1)
                    .count();
            result.put("giveToFriendUseCount", giveToFriendUseCount);
            
            // 赠送好友使用金额合计（已使用优惠券的面值总和）
            BigDecimal giveToFriendUseAmount = couponUsers.stream()
                    .filter(cu -> cu.getStatus() != null && cu.getStatus() == 1)
                    .map(cu -> {
                        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(cu.getCouponId());
                        return coupon != null && coupon.getNominalValue() != null ? coupon.getNominalValue() : BigDecimal.ZERO;
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            result.put("giveToFriendUseAmount", giveToFriendUseAmount);
            
            // 赠送好友使用金额占比
            double giveToFriendUseAmountPercent = 0.0;
            if (giveToFriendAmount.compareTo(BigDecimal.ZERO) > 0) {
                giveToFriendUseAmountPercent = giveToFriendUseAmount
                        .divide(giveToFriendAmount, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100))
                        .doubleValue();
            }
            result.put("giveToFriendUseAmountPercent", giveToFriendUseAmountPercent);
            
            // 好友赠送相关数据（累计数据，从life_discount_coupon_store_friend表统计，type=1优惠券）
            List<LifeDiscountCouponStoreFriend> friendCoupons = queryFriendCouponsByStore(storeId, endDate, 1);
            
            // 好友赠送数量
            long friendGiveCount = friendCoupons.size();
            result.put("friendGiveCount", friendGiveCount);
            
            // 好友赠送金额合计（好友赠送的优惠券面值总和）
            BigDecimal friendGiveAmount = friendCoupons.stream()
                    .map(fc -> {
                        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(fc.getCouponId());
                        return coupon != null && coupon.getNominalValue() != null ? coupon.getNominalValue() : BigDecimal.ZERO;
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            result.put("friendGiveAmount", friendGiveAmount);
            
            // 好友赠送使用数量（累计数据）
            long friendGiveUseCount = calculateFriendCouponUseCount(friendCoupons, endDate);
            result.put("friendGiveUseCount", friendGiveUseCount);
            
            // 好友赠送使用金额合计（累计数据）
            BigDecimal friendGiveUseAmount = calculateFriendCouponUseAmount(friendCoupons, endDate);
            result.put("friendGiveUseAmount", friendGiveUseAmount);
            
            // 好友赠送使用金额占比
            double friendGiveUseAmountPercent = 0.0;
            if (friendGiveAmount.compareTo(BigDecimal.ZERO) > 0) {
                friendGiveUseAmountPercent = friendGiveUseAmount
                        .divide(friendGiveAmount, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100))
                        .doubleValue();
            }
            result.put("friendGiveUseAmountPercent", friendGiveUseAmountPercent);
        } catch (Exception e) {
            log.error("计算优惠券数据失败: storeId={}", storeId, e);
            // 返回默认值，避免统计失败
            result.put("giveToFriendCount", 0L);
            result.put("giveToFriendAmount", BigDecimal.ZERO);
            result.put("giveToFriendUseCount", 0L);
            result.put("giveToFriendUseAmount", BigDecimal.ZERO);
            result.put("giveToFriendUseAmountPercent", 0.0);
            result.put("friendGiveCount", 0L);
            result.put("friendGiveAmount", BigDecimal.ZERO);
            result.put("friendGiveUseCount", 0L);
            result.put("friendGiveUseAmount", BigDecimal.ZERO);
            result.put("friendGiveUseAmountPercent", 0.0);
        }
        
        return result;
    }
    
    /**
     * 根据店铺优惠券 id 查询 LifeDiscountCouponStoreFriend 赠送好友记录（累计数据，截至 endDate）
     * 从 LifeDiscountCoupon 查店铺优惠券 id，再按优惠券 id 查 LifeDiscountCouponStoreFriend
     */
    private List<LifeDiscountCouponStoreFriend> queryGiveToFriendRecordsByStore(Integer storeId, Date endDate) {
        try {
            LambdaQueryWrapper<LifeDiscountCoupon> couponWrapper = new LambdaQueryWrapper<>();
            couponWrapper.eq(LifeDiscountCoupon::getStoreId, String.valueOf(storeId))
                    .eq(LifeDiscountCoupon::getType, 1)
                    .eq(LifeDiscountCoupon::getDeleteFlag, 0);
            List<LifeDiscountCoupon> coupons = lifeDiscountCouponMapper.selectList(couponWrapper);
            if (coupons == null || coupons.isEmpty()) {
                return Collections.emptyList();
            }
            List<Integer> couponIds = coupons.stream()
                    .map(LifeDiscountCoupon::getId)
                    .collect(Collectors.toList());
            LambdaQueryWrapper<LifeDiscountCouponStoreFriend> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(LifeDiscountCouponStoreFriend::getCouponId, couponIds)
                    .lt(LifeDiscountCouponStoreFriend::getCreatedTime, endDate);
            return lifeDiscountCouponStoreFriendMapper.selectList(wrapper);
        } catch (Exception e) {
            log.error("查询店铺赠送好友记录失败: storeId={}", storeId, e);
            return Collections.emptyList();
        }
    }

    /**
     * 查询店铺关联的优惠券用户数据（累计数据，截至到endDate）
     */
    private List<LifeDiscountCouponUser> queryCouponUsersByStore(String storeId, Date endDate) {
        try {
            // 先查询店铺的优惠券（type=1优惠券）
            LambdaQueryWrapper<LifeDiscountCoupon> couponWrapper = new LambdaQueryWrapper<>();
            couponWrapper.eq(LifeDiscountCoupon::getStoreId, storeId)
                    .eq(LifeDiscountCoupon::getType, 1) // 优惠券
                    .eq(LifeDiscountCoupon::getDeleteFlag, 0);
            List<LifeDiscountCoupon> coupons = lifeDiscountCouponMapper.selectList(couponWrapper);
            
            if (coupons.isEmpty()) {
                return Collections.emptyList();
            }
            
            List<Integer> couponIds = coupons.stream()
                    .map(LifeDiscountCoupon::getId)
                    .collect(Collectors.toList());
            
            // 查询优惠券用户数据（累计数据）
            LambdaQueryWrapper<LifeDiscountCouponUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(LifeDiscountCouponUser::getCouponId, couponIds)
                    .lt(LifeDiscountCouponUser::getReceiveTime, endDate)
                    .eq(LifeDiscountCouponUser::getDeleteFlag, 0);
            return lifeDiscountCouponUserMapper.selectList(wrapper);
        } catch (Exception e) {
            log.error("查询店铺优惠券用户数据失败: storeId={}", storeId, e);
            return Collections.emptyList();
        }
    }
    
    /**
     * 查询好友赠送的优惠券/代金券数据（累计数据，截至到endDate）
     */
    private List<LifeDiscountCouponStoreFriend> queryFriendCouponsByStore(Integer storeId, Date endDate, Integer type) {
        try {
            // 先查询店铺用户
            LambdaQueryWrapper<StoreUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(StoreUser::getStoreId, storeId)
                    .eq(StoreUser::getDeleteFlag, 0);
            List<StoreUser> storeUsers = storeUserMapper.selectList(userWrapper);
            
            if (storeUsers.isEmpty()) {
                return Collections.emptyList();
            }
            
            List<Integer> storeUserIds = storeUsers.stream()
                    .map(StoreUser::getId)
                    .collect(Collectors.toList());
            
            // 查询好友赠送的优惠券/代金券（累计数据）
            LambdaQueryWrapper<LifeDiscountCouponStoreFriend> wrapper = new LambdaQueryWrapper<>();
            wrapper.and(w -> w.in(LifeDiscountCouponStoreFriend::getSenderUserId, storeUserIds)
                            .or(sub -> sub.isNull(LifeDiscountCouponStoreFriend::getSenderUserId)
                                    .in(LifeDiscountCouponStoreFriend::getFriendStoreUserId, storeUserIds)))
                    .lt(LifeDiscountCouponStoreFriend::getCreatedTime, endDate)
                    .eq(LifeDiscountCouponStoreFriend::getDeleteFlag, 0);
            List<LifeDiscountCouponStoreFriend> storeFriends = lifeDiscountCouponStoreFriendMapper.selectList(wrapper);
            
            // 过滤指定类型的优惠券
            return storeFriends.stream()
                    .filter(sf -> {
                        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(sf.getCouponId());
                        return coupon != null && coupon.getType() != null && coupon.getType().equals(type);
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询好友赠送优惠券/代金券数据失败: storeId={}, type={}", storeId, type, e);
            return Collections.emptyList();
        }
    }
    
    /**
     * 计算好友赠送优惠券使用数量（累计数据，截至到endDate）
     */
    private long calculateFriendCouponUseCount(List<LifeDiscountCouponStoreFriend> friendCoupons, Date endDate) {
        if (friendCoupons == null || friendCoupons.isEmpty()) {
            return 0L;
        }
        
        try {
            List<Integer> couponIds = friendCoupons.stream()
                    .map(LifeDiscountCouponStoreFriend::getCouponId)
                    .distinct()
                    .collect(Collectors.toList());
            
            LambdaQueryWrapper<LifeDiscountCouponUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(LifeDiscountCouponUser::getCouponId, couponIds)
                    .eq(LifeDiscountCouponUser::getStatus, 1) // 已使用
                    .lt(LifeDiscountCouponUser::getUseTime, endDate)
                    .eq(LifeDiscountCouponUser::getDeleteFlag, 0);
            return lifeDiscountCouponUserMapper.selectCount(wrapper);
        } catch (Exception e) {
            log.error("计算好友赠送优惠券使用数量失败", e);
            return 0L;
        }
    }
    
    /**
     * 计算好友赠送优惠券使用金额（累计数据，截至到endDate）
     */
    private BigDecimal calculateFriendCouponUseAmount(List<LifeDiscountCouponStoreFriend> friendCoupons, Date endDate) {
        if (friendCoupons == null || friendCoupons.isEmpty()) {
            return BigDecimal.ZERO;
        }
        
        try {
            List<Integer> couponIds = friendCoupons.stream()
                    .map(LifeDiscountCouponStoreFriend::getCouponId)
                    .distinct()
                    .collect(Collectors.toList());
            
            LambdaQueryWrapper<LifeDiscountCouponUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(LifeDiscountCouponUser::getCouponId, couponIds)
                    .eq(LifeDiscountCouponUser::getStatus, 1) // 已使用
                    .lt(LifeDiscountCouponUser::getUseTime, endDate)
                    .eq(LifeDiscountCouponUser::getDeleteFlag, 0);
            List<LifeDiscountCouponUser> usedCoupons = lifeDiscountCouponUserMapper.selectList(wrapper);
            
            return usedCoupons.stream()
                    .map(cu -> {
                        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(cu.getCouponId());
                        return coupon != null && coupon.getNominalValue() != null ? coupon.getNominalValue() : BigDecimal.ZERO;
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        } catch (Exception e) {
            log.error("计算好友赠送优惠券使用金额失败", e);
            return BigDecimal.ZERO;
        }
    }
    
    /**
     * 计算代金券数据- 优化：使用数据库聚合查询
     */
    private Map<String, Object> calculateVoucherData(Integer storeId, Date startDate, Date endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            StoreTrackEventMapper mapper = this.getBaseMapper();
            
            // 使用数据库聚合查询统计代金券事件（累计数据，截至到endDate）
            List<Map<String, Object>> voucherStats = mapper.calculateVoucherStatistics(storeId, endDate);
            
            // 将查询结果转换为Map，便于查找
            // 注意：SQL返回的字段名是下划线命名(event_type)，而非驼峰命名
            Map<String, Map<String, Object>> eventTypeMap = new HashMap<>();
            for (Map<String, Object> stat : voucherStats) {
                String eventType = (String) stat.get("event_type");
                if (eventType != null) {
                    eventTypeMap.put(eventType, stat);
                }
            }
            
            // 赠送好友数量
            Map<String, Object> giveStat = eventTypeMap.getOrDefault("VOUCHER_GIVE", new HashMap<>());
            Object giveCountObj = giveStat.get("count");
            long giveToFriendCount = giveCountObj != null ? ((Number) giveCountObj).longValue() : 0L;
            result.put("giveToFriendCount", giveToFriendCount);
            
            // 赠送好友金额合计
            Object giveAmountObj = giveStat.get("totalAmount");
            BigDecimal giveToFriendAmount = giveAmountObj != null ? 
                    new BigDecimal(giveAmountObj.toString()) : BigDecimal.ZERO;
            result.put("giveToFriendAmount", giveToFriendAmount);
            
            // 赠送好友使用数量
            Map<String, Object> useStat = eventTypeMap.getOrDefault("VOUCHER_USE", new HashMap<>());
            Object useCountObj = useStat.get("count");
            long giveToFriendUseCount = useCountObj != null ? ((Number) useCountObj).longValue() : 0L;
            result.put("giveToFriendUseCount", giveToFriendUseCount);
            
            // 赠送好友使用金额合计
            Object useAmountObj = useStat.get("totalAmount");
            BigDecimal giveToFriendUseAmount = useAmountObj != null ? 
                    new BigDecimal(useAmountObj.toString()) : BigDecimal.ZERO;
            result.put("giveToFriendUseAmount", giveToFriendUseAmount);
            
            // 赠送好友使用金额占比
            double giveToFriendUseAmountPercent = 0.0;
            if (giveToFriendAmount.compareTo(BigDecimal.ZERO) > 0) {
                giveToFriendUseAmountPercent = giveToFriendUseAmount
                        .divide(giveToFriendAmount, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100))
                        .doubleValue();
            }
            result.put("giveToFriendUseAmountPercent", giveToFriendUseAmountPercent);
            
            // 好友赠送代金券相关数据（累计数据，type=2代金券）
            List<LifeDiscountCouponStoreFriend> friendVouchers = queryFriendCouponsByStore(storeId, endDate, 2);
            
            // 好友赠送数量
            long friendGiveCount = friendVouchers.size();
            result.put("friendGiveCount", friendGiveCount);
            
            // 好友赠送金额合计（好友赠送的代金券面值总和）
            BigDecimal friendGiveAmount = friendVouchers.stream()
                    .map(fv -> {
                        LifeDiscountCoupon voucher = lifeDiscountCouponMapper.selectByIdIncludeDeleted(fv.getCouponId());
                        return voucher != null && voucher.getNominalValue() != null ? voucher.getNominalValue() : BigDecimal.ZERO;
                    })
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            result.put("friendGiveAmount", friendGiveAmount);
            
            // 好友赠送使用数量（累计数据）
            long friendGiveUseCount = calculateFriendCouponUseCount(friendVouchers, endDate);
            result.put("friendGiveUseCount", friendGiveUseCount);
            
            // 好友赠送使用金额合计（累计数据）
            BigDecimal friendGiveUseAmount = calculateFriendCouponUseAmount(friendVouchers, endDate);
            result.put("friendGiveUseAmount", friendGiveUseAmount);
            
            // 好友赠送使用金额占比
            double friendGiveUseAmountPercent = 0.0;
            if (friendGiveAmount.compareTo(BigDecimal.ZERO) > 0) {
                friendGiveUseAmountPercent = friendGiveUseAmount
                        .divide(friendGiveAmount, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100))
                        .doubleValue();
            }
            result.put("friendGiveUseAmountPercent", friendGiveUseAmountPercent);
        } catch (Exception e) {
            log.error("计算代金券数据失败: storeId={}", storeId, e);
            // 返回默认值
            result.put("giveToFriendCount", 0L);
            result.put("giveToFriendAmount", BigDecimal.ZERO);
            result.put("giveToFriendUseCount", 0L);
            result.put("giveToFriendUseAmount", BigDecimal.ZERO);
            result.put("giveToFriendUseAmountPercent", 0.0);
        result.put("friendGiveCount", 0L);
            result.put("friendGiveAmount", BigDecimal.ZERO);
        result.put("friendGiveUseCount", 0L);
            result.put("friendGiveUseAmount", BigDecimal.ZERO);
        result.put("friendGiveUseAmountPercent", 0.0);
        }
        
        return result;
    }
    
    /**
     * 计算服务质量数据- 优化：使用数据库聚合查询
     */
    private Map<String, Object> calculateServiceData(Integer storeId, Date startDate, Date endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            StoreTrackEventMapper mapper = this.getBaseMapper();
            
            // 使用数据库聚合查询统计服务事件（累计数据，截至到endDate）
            List<Map<String, Object>> serviceStats = mapper.calculateServiceStatistics(storeId, endDate);
            
            // 将查询结果转换为Map，便于查找
            Map<String, Long> eventTypeCountMap = new HashMap<>();
            for (Map<String, Object> stat : serviceStats) {
                String eventType = (String) stat.get("event_type");
                Object countObj = stat.get("count");
                long count = countObj != null ? ((Number) countObj).longValue() : 0L;
                if (eventType != null) {
                    eventTypeCountMap.put(eventType, count);
                }
            }
        
            // 差评申诉次数
            long appealCount = eventTypeCountMap.getOrDefault("APPEAL", 0L);
            result.put("appealCount", appealCount);
            
            // 从 common_rating 表查询评价数据
            List<CommonRating> ratings = queryRatings(storeId, startDate, endDate);
            
            // 店铺评分（计算平均分）
            Double storeScore = calculateStoreScore(ratings);
            result.put("storeScore", storeScore);
            
            // 评分1、评分2、评分3（直接从common_rating表的scoreOne/scoreTwo/scoreThree字段获取）
            Double scoreOne = calculateScoreAverage(ratings, CommonRating::getScoreOne);
            Double scoreTwo = calculateScoreAverage(ratings, CommonRating::getScoreTwo);
            Double scoreThree = calculateScoreAverage(ratings, CommonRating::getScoreThree);
            result.put("scoreOne", scoreOne);
            result.put("scoreTwo", scoreTwo);
            result.put("scoreThree", scoreThree);
            
            // 评价数量
            long ratingCount = ratings.size();
            result.put("ratingCount", ratingCount);
            
            // 好评数量（score >= 4.5）
            long goodRatingCount = ratings.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 4.5)
                    .count();
            result.put("goodRatingCount", goodRatingCount);
            
            // 中评数量（3.0 <= score <= 4.0）
            long midRatingCount = ratings.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 3.0 && r.getScore() <= 4.0)
                    .count();
            result.put("midRatingCount", midRatingCount);
            
            // 差评数量（0.5 <= score <= 2.5）
            long badRatingCount = ratings.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 0.5 && r.getScore() <= 2.5)
                    .count();
            result.put("badRatingCount", badRatingCount);
            
            // 差评占比
            double badRatingPercent = 0.0;
            if (ratingCount > 0) {
                badRatingPercent = (double) badRatingCount / ratingCount * 100;
                badRatingPercent = BigDecimal.valueOf(badRatingPercent)
                        .setScale(2, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            result.put("badRatingPercent", badRatingPercent);
            
            // 差评申诉成功次数（累计数据）
            long appealSuccessCount = calculateAppealSuccessCount(storeId, endDate);
            result.put("appealSuccessCount", appealSuccessCount);
            
            // 差评申诉成功占比
            double appealSuccessPercent = 0.0;
            if (appealCount > 0) {
                appealSuccessPercent = (double) appealSuccessCount / appealCount * 100;
                appealSuccessPercent = BigDecimal.valueOf(appealSuccessPercent)
                        .setScale(2, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            result.put("appealSuccessPercent", appealSuccessPercent);
        } catch (Exception e) {
            log.error("计算服务质量数据失败: storeId={}", storeId, e);
            // 返回默认值，避免统计失败
            result.put("storeScore", null);
            result.put("scoreOne", null);
            result.put("scoreTwo", null);
            result.put("scoreThree", null);
            result.put("ratingCount", 0L);
            result.put("goodRatingCount", 0L);
            result.put("midRatingCount", 0L);
            result.put("badRatingCount", 0L);
            result.put("badRatingPercent", 0.0);
            result.put("appealCount", 0L);
            result.put("appealSuccessCount", 0L);
            result.put("appealSuccessPercent", 0.0);
        }
        
        return result;
    }
    
    /**
     * 查询评价数据
     */
    private List<CommonRating> queryRatings(Integer storeId, Date startDate, Date endDate) {
        try {
            LambdaQueryWrapper<CommonRating> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CommonRating::getBusinessId, storeId)
                    .eq(CommonRating::getBusinessType, 1) // 商铺评价
                    .lt(CommonRating::getCreatedTime, endDate) // 累计数据，只限制截止日期
                    .eq(CommonRating::getDeleteFlag, 0);
            return commonRatingMapper.selectList(wrapper);
        } catch (Exception e) {
            log.error("查询评价数据失败: storeId={}", storeId, e);
            return Collections.emptyList();
        }
    }
    
    /**
     * 计算店铺评分（平均分）
     */
    private Double calculateStoreScore(List<CommonRating> ratings) {
        if (ratings == null || ratings.isEmpty()) {
            return null;
        }
        
        double sum = ratings.stream()
                .filter(r -> r.getScore() != null)
                .mapToDouble(CommonRating::getScore)
                .sum();
        long count = ratings.stream()
                .filter(r -> r.getScore() != null)
                .count();
        
        if (count == 0) {
            return null;
        }
        
        double avg = sum / count;
        return BigDecimal.valueOf(avg)
                .setScale(1, RoundingMode.HALF_UP)
                .doubleValue();
    }
    
    /**
     * 计算单个评分字段的平均分
     */
    private Double calculateScoreAverage(List<CommonRating> ratings, java.util.function.Function<CommonRating, Double> scoreExtractor) {
        if (ratings == null || ratings.isEmpty()) {
            return null;
        }
        
        double sum = ratings.stream()
                .map(scoreExtractor)
                .filter(score -> score != null)
                .mapToDouble(Double::doubleValue)
                .sum();
        long count = ratings.stream()
                .map(scoreExtractor)
                .filter(score -> score != null)
                .count();
        
        if (count == 0) {
            return null;
        }
        
        double avg = sum / count;
        return BigDecimal.valueOf(avg)
                .setScale(1, RoundingMode.HALF_UP)
                .doubleValue();
    }
    
    /**
     * 计算差评申诉成功次数（累计数据，截至到endDate）
     */
    private long calculateAppealSuccessCount(Integer storeId, Date endDate) {
        try {
            LambdaQueryWrapper<StoreCommentAppeal> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreCommentAppeal::getStoreId, storeId)
                    .eq(StoreCommentAppeal::getAppealStatus, 2) // 已同意
                    .lt(StoreCommentAppeal::getCreatedTime, endDate)
                    .eq(StoreCommentAppeal::getDeleteFlag, 0);
            return storeCommentAppealMapper.selectCount(wrapper);
        } catch (Exception e) {
            log.error("计算差评申诉成功次数失败: storeId={}", storeId, e);
            return 0L;
        }
    }
    
    /**
     * 计算价目表排名数据- 优化：使用数据库聚合查询
     */
    private List<Map<String, Object>> calculatePriceRankingData(Integer storeId, Date startDate, Date endDate) {
        try {
            StoreTrackEventMapper mapper = this.getBaseMapper();
            
            // 使用数据库聚合查询统计价目表排名数据（累计数据，截至到endDate）
            List<Map<String, Object>> result = mapper.calculatePriceRanking(storeId, endDate);
            
            // 转换数据类型，确保与文档格式一致
            for (Map<String, Object> priceData : result) {
                // priceId 保持原样
                // viewCount, visitorCount, shareCount 转换为 Integer
                Object viewCountObj = priceData.get("viewCount");
                if (viewCountObj instanceof Number) {
                    priceData.put("viewCount", ((Number) viewCountObj).intValue());
                }
                Object visitorCountObj = priceData.get("visitorCount");
                if (visitorCountObj instanceof Number) {
                    priceData.put("visitorCount", ((Number) visitorCountObj).intValue());
                }
                Object shareCountObj = priceData.get("shareCount");
                if (shareCountObj instanceof Number) {
                    priceData.put("shareCount", ((Number) shareCountObj).intValue());
                }
            }
            
            return result;
        } catch (Exception e) {
            log.error("计算价目表排名数据失败: storeId={}", storeId, e);
            return new ArrayList<>();
        }
    }

    @Override
    public Long getStoreViewCount(Integer storeId) {
        try {
            if (storeId == null || storeId <= 0) {
                log.warn("店铺ID无效: storeId={}", storeId);
                return 0L;
            }
            
            StoreTrackEventMapper mapper = this.getBaseMapper();
            Long viewCount = mapper.countStoreViewCount(storeId);
            return viewCount != null ? viewCount : 0L;
        } catch (Exception e) {
            log.error("统计店铺浏览量失败: storeId={}", storeId, e);
            return 0L;
        }
    }

    @Override
    public Long countStoreViewEventsBetweenInclusive(Integer storeId, Date startInclusive, Date endInclusive) {
        try {
            if (storeId == null || storeId <= 0 || startInclusive == null || endInclusive == null) {
                return 0L;
            }
            if (endInclusive.before(startInclusive)) {
                return 0L;
            }
            Long n = getBaseMapper().countStoreViewCountBetweenInclusive(storeId, startInclusive, endInclusive);
            return n != null ? n : 0L;
        } catch (Exception e) {
            log.error("按区间统计店铺浏览量失败: storeId={}", storeId, e);
            return 0L;
        }
    }
    
    /**
     * 根据phoneId获取StoreUser
     */
    private StoreUser getStoreUserByPhoneId(String storePhoneId) {
        try {
            if (storePhoneId == null || !storePhoneId.startsWith("store_")) {
                return null;
            }
            String phone = storePhoneId.substring(6); // 去掉 "store_" 前缀
            LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreUser::getPhone, phone)
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1");
            return storeUserMapper.selectOne(wrapper);
        } catch (Exception e) {
            log.error("获取StoreUser失败: storePhoneId={}", storePhoneId, e);
            return null;
        }
    }
    
    /**
     * 获取被拉黑的用户phoneId集合
     * @param blockerType 拉黑方类型（"1"=店铺, "2"=用户）
     * @param blockerId 拉黑方ID
     * @return 被拉黑的用户phoneId集合
     */
    private Set<String> getBlockedUserIds(String blockerType, String blockerId) {
        try {
            LambdaQueryWrapper<LifeBlacklist> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(LifeBlacklist::getBlockerType, blockerType)
                    .eq(LifeBlacklist::getBlockerId, blockerId)
                    .eq(LifeBlacklist::getDeleteFlag, 0);
            List<LifeBlacklist> blacklist = lifeBlacklistMapper.selectList(wrapper);
            
            // 将被拉黑的用户ID转换为phoneId集合
            Set<String> blockedPhoneIds = new HashSet<>();
            for (LifeBlacklist item : blacklist) {
                String blockedType = item.getBlockedType();
                String blockedId = item.getBlockedId();
                
                // 根据blockedType和blockedId查询对应的phoneId
                if ("1".equals(blockedType)) {
                    // 店铺类型
                    StoreUser storeUser = storeUserMapper.selectById(blockedId);
                    if (storeUser != null && storeUser.getPhone() != null) {
                        blockedPhoneIds.add("store_" + storeUser.getPhone());
                    }
                } else if ("2".equals(blockedType)) {
                    // 用户类型 - 直接查询LifeUser表获取phoneId
                    LifeUser lifeUser = lifeUserMapper.selectById(blockedId);
                    if (lifeUser != null && lifeUser.getUserPhone() != null) {
                        blockedPhoneIds.add("user_" + lifeUser.getUserPhone());
                    }
                }
            }
            return blockedPhoneIds;
        } catch (Exception e) {
            log.error("获取被拉黑用户列表失败: blockerType={}, blockerId={}", blockerType, blockerId, e);
            return new HashSet<>();
        }
    }
    
    /**
     * 判断phoneId是否被拉黑
     * @param phoneId 用户phoneId
     * @param blockedUserIds 被拉黑的用户phoneId集合
     * @return true表示被拉黑，false表示未被拉黑
     */
    private boolean isBlocked(String phoneId, Set<String> blockedUserIds) {
        return blockedUserIds != null && blockedUserIds.contains(phoneId);
    }
    
    /**
     * 检查用户是否存在且未被删除（与用户资料页面的SQL逻辑保持一致）
     * @param phoneId 用户phoneId（格式：store_手机号 或 user_手机号）
     * @return true表示用户存在且未被删除，false表示用户不存在或已被删除
     */
    private boolean isUserValid(String phoneId) {
        try {
            if (phoneId == null || !phoneId.contains("_")) {
                return false;
            }
            
            String[] parts = phoneId.split("_", 2);
            if (parts.length < 2) {
                return false;
            }
            
            String type = parts[0];
            String phone = parts[1];
            
            if ("store".equals(type)) {
                // 检查店铺用户是否存在且未被删除
                LambdaQueryWrapper<StoreUser> userWrapper = new LambdaQueryWrapper<>();
                userWrapper.eq(StoreUser::getPhone, phone)
                        .eq(StoreUser::getDeleteFlag, 0)
                        .last("LIMIT 1");
                StoreUser storeUser = storeUserMapper.selectOne(userWrapper);
                
                if (storeUser == null || storeUser.getStoreId() == null) {
                    return false;
                }
                
                // 检查店铺信息是否存在且未被删除
                LambdaQueryWrapper<shop.alien.entity.store.StoreInfo> infoWrapper = new LambdaQueryWrapper<>();
                infoWrapper.eq(shop.alien.entity.store.StoreInfo::getId, storeUser.getStoreId())
                        .eq(shop.alien.entity.store.StoreInfo::getDeleteFlag, 0)
                        .last("LIMIT 1");
                shop.alien.entity.store.StoreInfo storeInfo = storeInfoMapper.selectOne(infoWrapper);
                
                return storeInfo != null;
            } else if ("user".equals(type)) {
                // 检查普通用户是否存在且未被删除
                LambdaQueryWrapper<LifeUser> userWrapper = new LambdaQueryWrapper<>();
                userWrapper.eq(LifeUser::getUserPhone, phone)
                        .eq(LifeUser::getDeleteFlag, 0)
                        .last("LIMIT 1");
                LifeUser lifeUser = lifeUserMapper.selectOne(userWrapper);
                
                return lifeUser != null;
            }
            
            return false;
        } catch (Exception e) {
            log.error("检查用户有效性失败: phoneId={}", phoneId, e);
            return false;
        }
    }

}
