package shop.alien.store.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.LifeFansVo;
import shop.alien.entity.store.vo.LifeStoreVo;
import shop.alien.entity.store.vo.LifeUserVo;
import shop.alien.entity.store.vo.StoreInfoVo;
import shop.alien.mapper.*;
import shop.alien.store.config.BaseRedisService;
import shop.alien.util.type.LifeFansIdentityQuery;
import shop.alien.util.common.ListToPage;
import shop.alien.util.type.LifeCollectIdentityQuery;
import shop.alien.util.type.TypeUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * 门店
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LifeStoreService {

    private final LifeCollectMapper lifeCollectMapper;

    private final LifeUserMapper lifeUserMapper;

    private final LifeFansMapper lifeFansMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final StoreInfoService storeInfoService;

    private final StoreUserService storeUserService;

    private final StoreImgService storeImgService;

    private final LifeUserService lifeUserService;

    private final LifeUserDynamicsMapper lifeUserDynamicsMapper;

    private final LifeBlacklistMapper lifeBlacklistMapper;

    private final BaseRedisService baseRedisService;

    private final TypeUtil typeUtil;

    public LifeUser loginByPhone(String phone) {
        LambdaUpdateWrapper<LifeUser> wrapperFans = new LambdaUpdateWrapper<>();
        wrapperFans.eq(LifeUser::getUserPhone, phone);
        List<LifeUser> userList = lifeUserMapper.selectList(wrapperFans);
        if (!CollectionUtils.isEmpty(userList)) {
            return userList.get(0);
        }
        return null;
    }

    /**
     * 我的关注
     *
     * @param type 筛选类型：不传或 0 表示店铺+用户关注；1 且 fansId 为店铺时仅返回店铺类型关注
     * @param myFansId 可选；有值时 isFollowMe、isFollowThis、isBlocked、blackListid 相对该主体计算，列表仍按 fansId
     */
    public IPage<LifeFansVo> getMyFollowed(String fansId, String name, int page, int size, Integer type, String myFansId) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name)
                .or(StringUtils.isNotEmpty(name))
                .like(StringUtils.isNotEmpty(name), "foll.phoneId", name);
        wrapper.groupBy("foll.phoneId");
        wrapper.last(" ORDER BY MAX(foll.created_time) DESC");
        String trimmedMyFansId = StringUtils.isNotEmpty(myFansId) ? myFansId.trim() : null;
        String relationFansId = StringUtils.isNotEmpty(trimmedMyFansId) ? trimmedMyFansId : fansId;
        String blockerSourceId = StringUtils.isNotEmpty(trimmedMyFansId) ? trimmedMyFansId : fansId;
        String blockerType = "";
        String blockerId = "";
        if ("user".equals(blockerSourceId.split("_")[0])) {
            String myselfUserPhone = blockerSourceId.split("_")[1];
            blockerType = "2";
            LifeUser myLifeUser = lifeUserService.getUserByPhone(myselfUserPhone);
            blockerId = String.valueOf(myLifeUser.getId());
        } else {
            String myselfStorePhone = blockerSourceId.split("_")[1];
            blockerType = "1";
            StoreUser myStoreUser = storeUserService.getUserByPhone(myselfStorePhone);
            blockerId = String.valueOf(myStoreUser.getId());
        }
        boolean onlyStoreFollowed = (type != null && type == 1) && fansId != null && fansId.startsWith("store_");
        IPage<LifeFansVo> myFollowed = queryMyFollowed(new Page<>(page, size), fansId, relationFansId, blockerType, blockerId, onlyStoreFollowed, wrapper);
        // 过滤掉我拉黑的
        List<LifeFansVo> collect = myFollowed.getRecords().stream().filter(x -> null == x.getBlackListid()).collect(Collectors.toList());
        myFollowed.setRecords(collect);
        myFollowed.setTotal(collect.size());
        return myFollowed;
    }

    /**
     * 我的关注所有
     */
    public List<LifeFansVo> getMyFollowedAll(String fansId) {
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        return lifeFansMapper.getMyFollowedAll(fansId, scope.getUserType(), scope.getRefId());
    }

    /**
     * 我的粉丝
     *
     * @param type 筛选类型：不传或 0 表示店铺+用户粉丝；1 且 fansId 为店铺时仅返回店铺粉丝
     * @param myFansId 可选；有值时 isFollowMe、isFollowThis、isBlocked、blackListid 相对该主体计算，列表仍按 fansId
     */
    public IPage<LifeFansVo> getMyFans(String fansId, String name, int page, int size, Integer type, String myFansId) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name);
        wrapper.groupBy("foll.phoneId");
        wrapper.last(" ORDER BY MAX(foll.created_time) DESC");
        String trimmedMyFansId = StringUtils.isNotEmpty(myFansId) ? myFansId.trim() : null;
        String relationFansId = StringUtils.isNotEmpty(trimmedMyFansId) ? trimmedMyFansId : fansId;
        String blockerSourceId = StringUtils.isNotEmpty(trimmedMyFansId) ? trimmedMyFansId : fansId;
        String blockerType = "";
        String blockerId = "";
        if ("user".equals(blockerSourceId.split("_")[0])) {
            String myselfUserPhone = blockerSourceId.split("_")[1];
            blockerType = "2";
            LifeUser myLifeUser = lifeUserService.getUserByPhone(myselfUserPhone);
            blockerId = String.valueOf(myLifeUser.getId());
        } else {
            String myselfStorePhone = blockerSourceId.split("_")[1];
            blockerType = "1";
            StoreUser myStoreUser = storeUserService.getUserByPhone(myselfStorePhone);
            blockerId = String.valueOf(myStoreUser.getId());
        }
        boolean onlyStoreFans = (type != null && type == 1) && fansId != null && fansId.startsWith("store_");
        IPage<LifeFansVo> myFans = queryMyFans(new Page<>(page, size), fansId, relationFansId, blockerType, blockerId, onlyStoreFans, wrapper);
        List<LifeFansVo> collect = myFans.getRecords().stream().filter(x -> null == x.getBlackListid()).collect(Collectors.toList());
        myFans.setRecords(collect);
        myFans.setTotal(collect.size());
        return myFans;
    }

    /**
     * 我的商家粉丝
     */
    public IPage<LifeFansVo> getMyStoreFans(String fansId, String name, int page, int size) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name);
        wrapper.groupBy("foll.phoneId");
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        IPage<LifeFansVo> myStoreFans = lifeFansMapper.getMyStoreFans(new Page<>(page, size), fansId,
                scope.getUserType(), scope.getRefId(), wrapper);
        filterBlocked(fansId, myStoreFans);
        List<LifeFansVo> collect = myStoreFans.getRecords().stream().filter(x -> x.getIsBlocked().equals("0")).collect(Collectors.toList());
        myStoreFans.setRecords(collect);
        myStoreFans.setTotal(collect.size());
        return myStoreFans;
    }

    /**
     * 我的用户粉丝
     */
    public IPage<LifeFansVo> getMyUserFans(String fansId, String name, int page, int size) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name);
        wrapper.groupBy("foll.phoneId");
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        IPage<LifeFansVo> myUserFans = lifeFansMapper.getMyUserFans(new Page<>(page, size), fansId,
                scope.getUserType(), scope.getRefId(), wrapper);
        filterBlocked(fansId, myUserFans);
        List<LifeFansVo> collect = myUserFans.getRecords().stream().filter(x -> x.getIsBlocked().equals("0")).collect(Collectors.toList());
        myUserFans.setRecords(collect);
        myUserFans.setTotal(collect.size());
        return myUserFans;
    }

    /**
     * 互相关注
     */
    public IPage<LifeFansVo> getMutualAttention(String fansId, String name, int page, int size) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name);
        wrapper.groupBy("foll.phoneId");
        wrapper.last(" ORDER BY MAX(foll.created_time) DESC");
        String blockerType = "";
        String blockerId = "";
        if ("user".equals(fansId.split("_")[0])) {
            String myselfUserPhone = fansId.split("_")[1];
            blockerType = "2";
            LifeUser myLifeUser = lifeUserService.getUserByPhone(myselfUserPhone);
            blockerId = String.valueOf(myLifeUser.getId());
        } else {
            String myselfStorePhone = fansId.split("_")[1];
            blockerType = "1";
            StoreUser myStoreUser = storeUserService.getUserByPhone(myselfStorePhone);
            blockerId = String.valueOf(myStoreUser.getId());
        }
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        IPage<LifeFansVo> mutualAttention = lifeFansMapper.getMutualAttention(new Page<>(page, size), fansId,
                scope.getUserType(), scope.getRefId(), blockerType, blockerId, wrapper);
        List<LifeFansVo> collect = mutualAttention.getRecords().stream().filter(x -> null == x.getBlackListid()).collect(Collectors.toList());
        mutualAttention.setRecords(collect);
        mutualAttention.setTotal(collect.size());
        return mutualAttention;
    }

    /**
     * 互相关注（仅用户)
     */
    public IPage<LifeFansVo> getMutualAttentionUser(String fansId, String name, int page, int size) {
        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), "foll.name", name);
        wrapper.groupBy("foll.phoneId");
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        IPage<LifeFansVo> mutualAttention = lifeFansMapper.getMutualAttentionUser(new Page<>(page, size), fansId,
                scope.getUserType(), scope.getRefId(), wrapper);
        filterBlocked(fansId, mutualAttention);
        List<LifeFansVo> collect = mutualAttention.getRecords().stream().filter(x -> x.getIsBlocked().equals("0")).collect(Collectors.toList());
        mutualAttention.setRecords(collect);
        mutualAttention.setTotal(collect.size());
        return mutualAttention;
    }

    /**
     * 获取首页信息（优化版）
     * 
     * @param phoneId 用户标识（格式：user_手机号 或 store_手机号）
     * @return 首页信息
     */
    public LifeFansVo getHomePageInfo(String phoneId) {
        // 参数校验
        if (StringUtils.isEmpty(phoneId)) {
            log.warn("getHomePageInfo: phoneId为空");
            return new LifeFansVo();
        }

        // 验证 phoneId 格式
        String[] phoneIdParts = phoneId.split("_");
        if (phoneIdParts.length < 2) {
            log.warn("getHomePageInfo: phoneId格式错误，phoneId={}", phoneId);
            return new LifeFansVo();
        }

        QueryWrapper<LifeFansVo> wrapper = new QueryWrapper<>();
        wrapper.groupBy("foll.phoneId");

        // 判断自己的拉黑type
        final String blockerType;
        final String blockerId;
        try {
            if ("user".equals(phoneIdParts[0])) {
                String myselfUserPhone = phoneIdParts[1];
                blockerType = "2";
                LifeUser myLifeUser = lifeUserService.getUserByPhone(myselfUserPhone);
                if (myLifeUser == null || myLifeUser.getId() == null) {
                    log.warn("getHomePageInfo: 用户不存在，phoneId={}", phoneId);
                    return new LifeFansVo();
                }
                blockerId = String.valueOf(myLifeUser.getId());
            } else {
                String myselfStorePhone = phoneIdParts[1];
                blockerType = "1";
                StoreUser myStoreUser = storeUserService.getUserByPhone(myselfStorePhone);
                if (myStoreUser == null || myStoreUser.getId() == null) {
                    log.warn("getHomePageInfo: 商户不存在，phoneId={}", phoneId);
                    return new LifeFansVo();
                }
                blockerId = String.valueOf(myStoreUser.getId());
            }
        } catch (Exception e) {
            log.error("getHomePageInfo: 获取用户信息异常，phoneId={}", phoneId, e);
            return new LifeFansVo();
        }

        // 优化：使用分页查询统计数量，避免使用 Integer.MAX_VALUE 导致内存溢出
        // 使用合理的分页大小，如果数据量很大则循环分页统计
        int pageSize = 1000; // 设置合理的分页大小
        
        // 统计关注数量（过滤被拉黑的）
        int followedNum = countFilteredRecords(phoneId, blockerType, blockerId, wrapper, pageSize,
                (page, w) -> queryMyFollowed(page, phoneId, phoneId, blockerType, blockerId, false, w));

        // 统计粉丝数量（过滤被拉黑的）
        int fansNum = countFilteredRecords(phoneId, blockerType, blockerId, wrapper, pageSize,
                (page, w) -> queryMyFans(page, phoneId, phoneId, blockerType, blockerId, false, w));

        LifeFansIdentityQuery.Scope phoneScope = LifeFansIdentityQuery.resolve(phoneId, typeUtil);

        // 统计好友数量（过滤被拉黑的）
        int friendNum = countFilteredRecords(phoneId, blockerType, blockerId, wrapper, pageSize,
                (page, w) -> lifeFansMapper.getMutualAttention(page, phoneId,
                        phoneScope.getUserType(), phoneScope.getRefId(), blockerType, blockerId, w));

        // 获取基础信息（包含dynamicsNum）
        LifeFansVo lifeFansVo = lifeFansMapper.getHomePageInfo(phoneId, phoneScope.getUserType(), phoneScope.getRefId());
        if (lifeFansVo == null) {
            lifeFansVo = new LifeFansVo();
        }
        
        // 设置统计数量
        lifeFansVo.setFollowNum(String.valueOf(followedNum));
        lifeFansVo.setFansNum(String.valueOf(fansNum));
        lifeFansVo.setFriendNum(String.valueOf(friendNum));

        return lifeFansVo;
    }

    /**
     * 用户粉丝
     *
     * @param storeId
     * @param name
     * @param page
     * @param size
     * @return
     */
    public IPage<LifeUserVo> getUserFans(String storeId, String name, int page, int size) {
        List<LifeUser> mapList = null;
        LifeFansIdentityQuery.Scope followedScope = LifeFansIdentityQuery.resolve(storeId, typeUtil);
        LambdaQueryWrapper<LifeFans> wrapperFans = new LambdaQueryWrapper<>();
        wrapperFans.eq(LifeFans::getDeleteFlag, 0).eq(LifeFans::getFansType, "1");
        LifeFansIdentityQuery.applyFollowedSide(wrapperFans, followedScope);
        wrapperFans.eq(LifeFans::getFansUserType, 1);
        List<LifeFans> userfans = lifeFansMapper.selectList(wrapperFans);
        if (!CollectionUtils.isEmpty(userfans)) {
            List<Integer> userIds = userfans.stream().map(LifeFans::getFansRefId).filter(Objects::nonNull).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(userIds)) {
                LambdaQueryWrapper<LifeUser> wrapperUser = new LambdaQueryWrapper<>();
                wrapperUser.like(StringUtils.isNotEmpty(name), LifeUser::getUserName, name);
                wrapperUser.in(LifeUser::getId, userIds);
                mapList = lifeUserMapper.selectList(wrapperUser);
            }
        }
        List<LifeUserVo> mapListVo = new ArrayList<>();
        if (!CollectionUtils.isEmpty(mapList)) {
            for (LifeUser user : mapList) {
                LifeFansIdentityQuery.Scope fanScope = LifeFansIdentityQuery.resolve("user_" + user.getUserPhone(), typeUtil);
                LambdaQueryWrapper<LifeFans> checkWrapper = new LambdaQueryWrapper<>();
                LifeFansIdentityQuery.applyPairWithDeleteFlag(checkWrapper, fanScope, followedScope);
                LifeUserVo vo = new LifeUserVo();
                BeanUtils.copyProperties(user, vo);
                vo.setIsGuanzhu(lifeFansMapper.selectCount(checkWrapper) > 0 ? "1" : "0");
                mapListVo.add(vo);
            }
        }
        return ListToPage.setPage(mapListVo, page, size);
    }

    public List<LifeStoreVo> getStores(String storeName, String storeContact,
                                       String storePhone, String storeType, String userId) {
        checkAndUpdateExpiredRecords();
        QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!storeName.isEmpty(), "a.store_name", storeName);
        queryWrapper.like(!storeContact.isEmpty(), "a.store_contact", storeContact);
        queryWrapper.like(!storePhone.isEmpty(), "b.phone", storePhone);
        queryWrapper.like(!storeType.isEmpty(), "a.store_type", storeType).eq("a.delete_flag", 0);
        queryWrapper.orderByDesc("created_time");
        List<StoreInfoVo> result = storeInfoMapper.getStoreInfoVoList(queryWrapper);
        List<LifeStoreVo> resultVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(result)) {
            for (StoreInfoVo store : result) {
                LifeStoreVo vo = new LifeStoreVo();
                BeanUtils.copyProperties(store, vo);
                LambdaUpdateWrapper<LifeCollect> wrapper = new LambdaUpdateWrapper<>();
                wrapper.eq(LifeCollect::getStoreId, store.getId());
                LifeCollectIdentityQuery.applyUserSide(wrapper, LifeCollectIdentityQuery.resolve(userId, typeUtil));
                List<LifeCollect> storeShoucangs = lifeCollectMapper.selectList(wrapper);
                if (!CollectionUtils.isEmpty(storeShoucangs)) {
                    vo.setIsShoucang("1");
                } else {
                    vo.setIsShoucang("0");
                }
                resultVos.add(vo);
            }
        }
        return resultVos;
    }

    /**
     * 根据过期时间修改状态
     */
    public void checkAndUpdateExpiredRecords() {
        LambdaUpdateWrapper<StoreInfo> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.isNotNull(StoreInfo::getExpirationTime)
                .lt(StoreInfo::getExpirationTime, LocalDateTime.now())
                .eq(StoreInfo::getBusinessStatus, 0)
                .set(StoreInfo::getBusinessStatus, 99);
        storeInfoService.update(queryWrapper);
    }

    public boolean modifyPassword(String phone, String passWord) {
        LambdaUpdateWrapper<StoreUser> wrapperFans = new LambdaUpdateWrapper<>();
        wrapperFans.eq(StoreUser::getPhone, phone);
        wrapperFans.set(StoreUser::getPassword, passWord);
        return storeUserService.update(null, wrapperFans);
    }

    /**
     * 商户粉丝
     *
     * @param storeId
     * @param storeContact
     * @param page
     * @param size
     * @return
     */
    public IPage<LifeStoreVo> getStoreFans(String storeId, String storeContact, int page, int size) {
        LifeFansIdentityQuery.Scope followedScope = LifeFansIdentityQuery.resolve(storeId, typeUtil);
        LambdaQueryWrapper<LifeFans> wrapperFans = new LambdaQueryWrapper<>();
        wrapperFans.eq(LifeFans::getDeleteFlag, 0).eq(LifeFans::getFansType, "2");
        LifeFansIdentityQuery.applyFollowedSide(wrapperFans, followedScope);
        wrapperFans.eq(LifeFans::getFansUserType, 2);
        List<LifeFans> userFans = lifeFansMapper.selectList(wrapperFans);
        if (!CollectionUtils.isEmpty(userFans)) {
            List<Integer> storeUserIds = userFans.stream().map(LifeFans::getFansRefId).filter(Objects::nonNull).collect(Collectors.toList());
            List<StoreUser> fanStoreUsers = new ArrayList<>(storeUserService.listByIds(storeUserIds));
            List<Integer> storeInfoIds = fanStoreUsers.stream().map(StoreUser::getStoreId).filter(Objects::nonNull).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(storeInfoIds)) {
                return null;
            }
            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("a.id", storeInfoIds).eq("a.delete_flag", 0).eq("b.name", storeContact);
            List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getStoreInfoVoList(queryWrapper);
            List<LifeStoreVo> mapListVo = new ArrayList<>();
            if (!CollectionUtils.isEmpty(storeInfoVoList)) {
                for (StoreInfoVo store : storeInfoVoList) {
                    LifeFansIdentityQuery.Scope fanScope = LifeFansIdentityQuery.resolve(storeId, typeUtil);
                    LifeFansIdentityQuery.Scope backScope = LifeFansIdentityQuery.resolve("store_" + store.getStoreTel(), typeUtil);
                    LambdaQueryWrapper<LifeFans> checkWrapper = new LambdaQueryWrapper<>();
                    LifeFansIdentityQuery.applyPairWithDeleteFlag(checkWrapper, fanScope, backScope);
                    LifeStoreVo vo = new LifeStoreVo();
                    BeanUtils.copyProperties(store, vo);
                    vo.setIsGuanzhu(lifeFansMapper.selectCount(checkWrapper) > 0 ? "1" : "0");
                    mapListVo.add(vo);
                }
            }
            return ListToPage.setPage(mapListVo, page, size);
        }
        return null;
    }

    public boolean deleteLunbotu(String id) {
        LambdaQueryWrapper<StoreImg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(StoreImg::getStoreId, id);
        return storeImgService.remove(lambdaQueryWrapper);
    }

    public List<String> getLunbotu() {
        LambdaQueryWrapper<StoreImg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreImg::getDeleteFlag, 0);
        List<StoreImg> list = storeImgService.list(lambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            return list.stream().map(StoreImg::getImgUrl).collect(Collectors.toList());
        }
        return null;
    }

    public boolean uploadLunbotu(String storeId, String lunbotu) {
        LambdaUpdateWrapper<StoreImg> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(StoreImg::getStoreId, storeId)
                .set(StoreImg::getImgUrl, lunbotu);
        return storeImgService.update(null, updateWrapper);
    }


    /**
     * 统计过滤后的记录数量（分页查询，避免内存溢出）
     * 
     * @param phoneId 用户标识
     * @param blockerType 拉黑类型
     * @param blockerId 拉黑者ID
     * @param wrapper 查询条件
     * @param pageSize 分页大小
     * @param queryFunction 查询函数
     * @return 过滤后的记录数量
     */
    private int countFilteredRecords(String phoneId, String blockerType, String blockerId, 
                                     QueryWrapper<LifeFansVo> wrapper, int pageSize,
                                     java.util.function.BiFunction<Page<LifeFansVo>, QueryWrapper<LifeFansVo>, IPage<LifeFansVo>> queryFunction) {
        int totalCount = 0;
        int currentPage = 1;
        int maxPages = 100; // 限制最大页数，防止无限循环
        
        while (currentPage <= maxPages) {
            IPage<LifeFansVo> pageResult = queryFunction.apply(new Page<>(currentPage, pageSize), wrapper);
            
            if (pageResult == null || CollectionUtils.isEmpty(pageResult.getRecords())) {
                break;
            }
            
            // 统计当前页过滤后的数量
            long currentPageCount = pageResult.getRecords().stream()
                    .filter(x -> null == x.getBlackListid())
                    .count();
            totalCount += (int) currentPageCount;
            
            // 如果当前页数据少于分页大小，说明已经是最后一页
            if (pageResult.getRecords().size() < pageSize) {
                break;
            }
            
            currentPage++;
        }
        
        return totalCount;
    }

    private IPage<LifeFansVo> queryMyFollowed(Page<LifeFansVo> page, String fansId, String relationFansId,
                                              String blockerType, String blockerId, boolean onlyStoreFollowed,
                                              QueryWrapper<LifeFansVo> wrapper) {
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        LifeFansIdentityQuery.Scope relationScope = LifeFansIdentityQuery.resolve(relationFansId, typeUtil);
        return lifeFansMapper.getMyFollowed(page, fansId, scope.getUserType(), scope.getRefId(),
                relationFansId, relationScope.getUserType(), relationScope.getRefId(),
                blockerType, blockerId, onlyStoreFollowed, wrapper);
    }

    private IPage<LifeFansVo> queryMyFans(Page<LifeFansVo> page, String fansId, String relationFansId,
                                          String blockerType, String blockerId, boolean onlyStoreFans,
                                          QueryWrapper<LifeFansVo> wrapper) {
        LifeFansIdentityQuery.Scope scope = LifeFansIdentityQuery.resolve(fansId, typeUtil);
        LifeFansIdentityQuery.Scope relationScope = LifeFansIdentityQuery.resolve(relationFansId, typeUtil);
        return lifeFansMapper.getMyFans(page, fansId, scope.getUserType(), scope.getRefId(),
                relationFansId, relationScope.getUserType(), relationScope.getRefId(),
                blockerType, blockerId, onlyStoreFans, wrapper);
    }

    private void filterBlocked(String fansId, IPage<LifeFansVo> myFollowed) {

        // 判断自己的拉黑type
        LifeUser myLifeUser = null;
        StoreUser myStoreUser = null;
        if ("user".equals(fansId.split("_")[0])) {
            String myselfUserPhone = fansId.split("_")[1];
            myLifeUser = lifeUserService.getUserByPhone(myselfUserPhone);
        } else {
            String myselfStorePhone = fansId.split("_")[1];
            myStoreUser = storeUserService.getUserByPhone(myselfStorePhone);
        }

        LambdaQueryWrapper<LifeBlacklist> lifeBlacklistWrapper = new LambdaQueryWrapper<>();
        if (null != myLifeUser) {
            lifeBlacklistWrapper.eq(LifeBlacklist::getBlockerType, "2");
            lifeBlacklistWrapper.eq(LifeBlacklist::getBlockerId, myLifeUser.getId());
        } else {
            lifeBlacklistWrapper.eq(LifeBlacklist::getBlockerType, "1");
            lifeBlacklistWrapper.eq(LifeBlacklist::getBlockerId, myStoreUser.getId());
        }
        List<LifeBlacklist> lifeBlacklist = lifeBlacklistMapper.selectList(lifeBlacklistWrapper);
        Map<String, List<LifeBlacklist>> collect = lifeBlacklist.stream().collect(Collectors.groupingBy(x -> x.getBlockedId()));
        for (LifeFansVo lifeFansVo : myFollowed.getRecords()) {
            // 判断被拉黑的type
            LifeUser lifeUser = null;
            StoreUser storeUser = null;
            if ("user".equals(lifeFansVo.getPhoneId().split("_")[0])) {
                String userPhone = lifeFansVo.getPhoneId().split("_")[1];
                lifeUser = lifeUserService.getUserByPhone(userPhone);
            } else {
                String storePhone = lifeFansVo.getPhoneId().split("_")[1];
                storeUser = storeUserService.getUserByPhone(storePhone);
            }
            //查询是否已拉黑
            String blockedId = "";
            String blockedType = "";
            if (null != lifeUser) {
                blockedId = String.valueOf(lifeUser.getId());
                blockedType = "2";
            } else {
                blockedId = String.valueOf(storeUser.getId());
                blockedType = "1";
            }
            lifeFansVo.setIsBlocked("0");
            if (collect.containsKey(blockedId)) {
                String finalBlockedType = blockedType;
                Optional<LifeBlacklist> first = collect.get(blockedId).stream().filter(x -> x.getBlockedType().equals(finalBlockedType)).findFirst();
                if (first.isPresent()) {
                    lifeFansVo.setIsBlocked("1");
                }
            }
        }
    }
}
