package com.kexue.skills.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.kexue.skills.common.Assert;
import com.kexue.skills.common.LoginUserCacheUtil;
import com.kexue.skills.entity.CmsContent;
import com.kexue.skills.entity.CmsContentView;
import com.kexue.skills.entity.CmsContentLike;
import com.kexue.skills.entity.base.BaseQueryDto;
import com.kexue.skills.entity.dto.CmsContentDto;
import com.kexue.skills.entity.request.ImportPathDto;
import com.kexue.skills.mapper.CmsContentMapper;
import com.kexue.skills.mapper.CmsContentViewMapper;
import com.kexue.skills.mapper.CmsContentLikeMapper;
import com.kexue.skills.service.CmsContentService;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.dev33.satoken.stp.StpUtil;

/**
 * (CmsContent)表服务实现类
 *
 * @author 王志维
 * @since 2025-02-21 23:01:48
 */
@Service("cmsContentService")
@Transactional(rollbackFor = Exception.class)
public class CmsContentServiceImpl implements CmsContentService {
    @Resource
    private CmsContentMapper cmsContentMapper;
    
    @Resource
    private CmsContentViewMapper cmsContentViewMapper;
    
    @Resource
    private CmsContentLikeMapper cmsContentLikeMapper;
    
    @Resource
    private LoginUserCacheUtil loginUserCacheUtil;

    /**
     * 分页查询
     *
     * @param queryDto 筛选条件
     * @return 查询结果
     */
    @Override
    public PageInfo<CmsContent> getPageList(CmsContentDto queryDto) {
        // 添加参数校验，确保分页参数有效
        if (queryDto.getPageNum() == null || queryDto.getPageNum() < 1) {
            queryDto.setPageNum(BaseQueryDto.DEFAULT_CURRENT_PAGE);
        }
        if (queryDto.getPageSize() == null || queryDto.getPageSize() < 1) {
            queryDto.setPageSize(BaseQueryDto.DEFAULT_PAGE_SIZE);
        }

        // 使用 PageHelper 进行分页
        PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        // 设置默认语言类型为中文
        if (queryDto.getLanguageType() == null) {
            queryDto.setLanguageType(0);
        }
        List<CmsContent> list = this.cmsContentMapper.getPageList(queryDto);
        PageInfo<CmsContent> pageInfo = new PageInfo<>(list);


        if (queryDto.getTitle() != null && !queryDto.getTitle().trim().isEmpty() && list.size() <= 3 && !list.isEmpty()) {
            // 获取第一个 skill 的标签
            CmsContent firstSkill = list.get(0);
            String tagsStr = firstSkill.getTags();
            if (tagsStr != null && !tagsStr.trim().isEmpty()) {
                // 解析标签（逗号分隔）
                String[] tags = tagsStr.split(",");
                if (tags.length > 0) {
                    // 构建标签 ID 列表
                    Set<Long> tagIdSet = new HashSet<>();
                    for (String tag : tags) {
                        if (tag != null && !tag.trim().isEmpty()) {
                            try {
                                Long tagId = Long.parseLong(tag.trim());
                                tagIdSet.add(tagId);
                            } catch (NumberFormatException e) {
                                // 忽略格式不正确的标签
                            }
                        }
                    }

                    //如果传入的tagId不为空，则添加到tagIdSet中
                    if (queryDto.getTagId() != null) {
                        tagIdSet.add(queryDto.getTagId());
                    }

                    // 如果有有效的标签 ID，查询相关内容
                    if (!tagIdSet.isEmpty()) {
                        // 排除已返回的 contentId
                        Set<Long> existingIds = list.stream()
                                .map(CmsContent::getContentId)
                                .collect(Collectors.toSet());

                        // 构建查询条件，使用 tagIdList 一次性查询
                        CmsContentDto tagQueryDto = new CmsContentDto();
                        tagQueryDto.setDeleteFlag(0);
                        tagQueryDto.setPublishStatus(2); // 已发布
                        tagQueryDto.setTagIdList(new ArrayList<>(tagIdSet));
                        tagQueryDto.setPageNum(1);
                        tagQueryDto.setPageSize(1000);

                        // 查询包含这些标签的所有 skill
                        List<CmsContent> taggedContents = this.cmsContentMapper.getPageList(tagQueryDto);
                        
                        //如果 tag 传参，则根据 tag 再次过滤
                        if (queryDto.getTagId() != null) {
                            taggedContents = taggedContents.stream().filter(content -> content.getTags().contains(queryDto.getTagId().toString())).toList() ;
                        }

                        // 过滤掉已返回的内容，避免重复
                        List<CmsContent> finalList = taggedContents.stream()
                                .filter(content -> !existingIds.contains(content.getContentId()))
                                .collect(Collectors.toList());

                        // 如果有相关 skill，添加到结果中
                        if (!finalList.isEmpty()) {
                            // 将外层查询结果和内层查询结果合并
                            List<CmsContent> allContents = new ArrayList<>(list);
                            allContents.addAll(finalList);
                            
                            // 按 view_count 和 create_time 排序
                            allContents.sort((a, b) -> {
                                int sortCompare = Integer.compare(
                                        a.getViewCount() != null ? a.getViewCount() : 0,
                                        b.getViewCount() != null ? b.getViewCount() : 0);
                                if (sortCompare != 0) {
                                    return sortCompare;
                                }
                                if (a.getCreateTime() == null || b.getCreateTime() == null) {
                                    return 0;
                                }
                                return b.getCreateTime().compareTo(a.getCreateTime());
                            });

                            // 计算需要添加的数量，确保总数量不超过 pageSize
                            PageInfo<CmsContent> newPageInfo = new PageInfo<>(memoryPagination(allContents, queryDto.getPageNum(), queryDto.getPageSize()));
                            newPageInfo.setTotal(allContents.size());
                            pageInfo = newPageInfo;
                        }
                    }
                }
            }
        }

        return pageInfo;
    }

    /**
     * 内存分页方法
     *
     * @param list 原始数据列表
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 当前页的 list，对应的页码没有数据则返回空 list
     */
    private List<CmsContent> memoryPagination(List<CmsContent> list, int pageNum, int pageSize) {
        // 参数校验
        if (list == null) {
            return new ArrayList<>();
        }
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1) {
            pageSize = 10;
        }

        // 计算总记录数
        int total = list.size();

        // 计算分页参数
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        // 截取分页数据
        List<CmsContent> pageList = new ArrayList<>();
        if (startIndex < total) {
            pageList = list.subList(startIndex, endIndex);
        }

        return pageList;
    }

    /**
     * 查询列表
     *
     * @param queryDto 筛选条件
     * @return 查询结果
     */
    @Override
    public List<CmsContent> getList(CmsContentDto queryDto) {
        // 设置默认语言类型为中文
        if (queryDto.getLanguageType() == null) {
            queryDto.setLanguageType(0);
        }
        return this.cmsContentMapper.getList(queryDto);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param contentId 主键
     * @return 实例对象
     */
    @Override
    public CmsContent queryById(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        CmsContent content = this.cmsContentMapper.queryById(contentId);
        if (content == null) {
            return null;
        }
        
        try {
            // 尝试获取当前登录用户ID
            Long userId = Long.parseLong(StpUtil.getLoginId().toString());
            // 检查用户是否已经查看过该内容（5分钟内）
            CmsContentView existingView = cmsContentViewMapper.queryByUserIdAndContentId(userId, contentId);
            if (existingView == null) {
                // 新增查看记录
                CmsContentView viewRecord = new CmsContentView();
                viewRecord.setUserId(userId);
                viewRecord.setUserName(StpUtil.getLoginIdAsString());
                viewRecord.setContentId(contentId);
                viewRecord.setContentTitle(content.getTitle());
                viewRecord.setViewTime(new Date());
                viewRecord.setDeleteFlag(0);
                viewRecord.setCreateBy(StpUtil.getLoginIdAsString());
                viewRecord.setUpdateBy(StpUtil.getLoginIdAsString());
                cmsContentViewMapper.insert(viewRecord);
            } else {
                // 检查是否超过5分钟
                Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
                if (existingView.getViewTime().before(fiveMinutesAgo)) {
                    // 更新查看时间
                    existingView.setViewTime(new Date());
                    existingView.setUpdateBy(StpUtil.getLoginIdAsString());
                    cmsContentViewMapper.update(existingView);
                }
            }
        } catch (Exception e) {
            // 未登录用户，不记录查看历史
        }
        
        return content;
    }

    /**
     * 通过主键查询单条数据，带权限检查
     *
     * @param contentId 主键
     * @param userId 用户ID
     * @return 实例对象
     */
    public CmsContent queryByIdWithPermission(Long contentId, Long userId) {
        Assert.notNull(contentId, "内容ID不能为空");
        CmsContent content = this.cmsContentMapper.queryById(contentId);
        if (content == null) {
            return null;
        }
        
        // 如果是付费内容，检查用户是否购买过
        if (content.getIsPaid() == 1) {
            // 这里需要调用ContentPurchaseService检查权限，但为了避免循环依赖，我们返回完整内容
            // 权限检查将在Controller层进行
        }
        
        return content;
    }

    /**
     * 新增数据
     *
     * @param cmsContent 实例对象
     * @return 实例对象
     */
    @Override
    public CmsContent insert(CmsContent cmsContent) {
        // 设置创建时间和更新时间
        Date now = new Date();
        cmsContent.setCreateTime(now);
        cmsContent.setUpdateTime(now);
        // 设置默认值
        cmsContent.setDeleteFlag(0);
        if (cmsContent.getAuditStatus() == null) {
            cmsContent.setAuditStatus(1); // 默认草稿状态
        }
        if (cmsContent.getPublishStatus() == null) {
            cmsContent.setPublishStatus(1); // 默认未发布状态
        }
        if (cmsContent.getViewCount() == null) {
            cmsContent.setViewCount(0);
        }
        if (cmsContent.getLikeCount() == null) {
            cmsContent.setLikeCount(0);
        }
        if (cmsContent.getCommentCount() == null) {
            cmsContent.setCommentCount(0);
        }
        if (cmsContent.getShareCount() == null) {
            cmsContent.setShareCount(0);
        }
        if (cmsContent.getSort() == null) {
            cmsContent.setSort(0);
        }
        if (cmsContent.getIsOfficial() == null) {
            cmsContent.setIsOfficial(false);
        }
        cmsContent.setAuthorId(StpUtil.getLoginIdAsLong());
        // 保存数据
        this.cmsContentMapper.insert(cmsContent);
        return cmsContent;
    }

    /**
     * 更新数据
     *
     * @param cmsContent 实例对象
     * @return 实例对象
     */
    @Override
    public CmsContent update(CmsContent cmsContent) {
        Assert.notNull(cmsContent.getContentId(), "内容ID不能为空");
        // 设置更新时间
        cmsContent.setUpdateTime(new Date());
        // 更新数据
        this.cmsContentMapper.update(cmsContent);
        return this.queryById(cmsContent.getContentId());
    }

    /**
     * 更新审核状态
     *
     * @param contentId 内容ID
     * @param auditStatus 审核状态
     * @param reviewerId 审核人ID
     * @param reviewerName 审核人名称
     * @param auditComment 审核意见
     * @param updateBy 更新人
     * @return 影响行数
     */
    @Override
    public int updateAuditStatus(Long contentId, Integer auditStatus, Long reviewerId, String reviewerName, String auditComment, String updateBy) {
        Assert.notNull(contentId, "内容ID不能为空");
        return this.cmsContentMapper.updateAuditStatus(contentId, auditStatus, reviewerId, reviewerName, auditComment, updateBy);
    }

    /**
     * 更新发布状态
     *
     * @param contentId 内容ID
     * @param publishStatus 发布状态
     * @param publishTime 发布时间
     * @param updateBy 更新人
     * @return 影响行数
     */
    @Override
    public int updatePublishStatus(Long contentId, Integer publishStatus, String publishTime, String updateBy) {
        Assert.notNull(contentId, "内容ID不能为空");
        return this.cmsContentMapper.updatePublishStatus(contentId, publishStatus, publishTime, updateBy);
    }

    /**
     * 增加阅读量
     *
     * @param contentId 内容ID
     * @return 影响行数
     */
    @Override
    public int increaseViewCount(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        // 增加阅读量
        int result = this.cmsContentMapper.increaseViewCount(contentId);
        
        try {
            // 尝试获取当前登录用户ID
            Long userId = Long.parseLong(StpUtil.getLoginId().toString());
            // 调用addView方法添加查看记录
            this.addView(contentId);
        } catch (Exception e) {
            // 未登录用户，不记录查看历史
        }
        
        return result;
    }

    /**
     * 通过主键逻辑删除
     *
     * @param contentId 主键
     * @param updateBy 更新人
     * @return 影响行数
     */
    @Override
    public int logicDeleteById(Long contentId, String updateBy) {
        Assert.notNull(contentId, "内容ID不能为空");
        return this.cmsContentMapper.logicDeleteById(contentId, updateBy);
    }

    /**
     * 通过主键物理删除
     *
     * @param contentId 主键
     * @return 影响行数
     */
    @Override
    public int deleteById(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        return this.cmsContentMapper.deleteById(contentId);
    }

    /**
     * 添加/取消收藏
     *
     * @param contentId 内容ID
     * @return 影响行数
     */
    @Override
    public int addFavorite(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        // 获取当前登录用户名
        String userName = StpUtil.getLoginIdAsString();
        
        // 检查内容是否存在
        CmsContent content = this.cmsContentMapper.queryById(contentId);
        if (content == null) {
            return 0;
        }
        if(Objects.isNull(content.getLikeCount())){
            content.setLikeCount(0);
        }
        
        // 检查用户是否已经收藏过该内容
        CmsContentLike existingLike = cmsContentLikeMapper.queryByUserIdAndContentId(userId, contentId);
        int result = 0;
        
        if (existingLike != null) {
            // 已经收藏过，执行取消收藏操作
            result = cmsContentLikeMapper.deleteById(existingLike.getLikeId());
            
            // 减少内容的点赞数
            if (content != null && content.getLikeCount() > 0) {
                content.setLikeCount(content.getLikeCount() - 1);
                this.cmsContentMapper.update(content);
            }
        } else {
            // 未收藏过，执行添加收藏操作
            CmsContentLike likeRecord = new CmsContentLike();
            likeRecord.setUserId(userId);
            likeRecord.setUserName(userName);
            likeRecord.setContentId(contentId);
            likeRecord.setContentTitle(content.getTitle());
            likeRecord.setLikeTime(new Date());
            likeRecord.setDeleteFlag(0);
            
            // 增加内容的点赞数
            content.setLikeCount(content.getLikeCount() + 1);
            this.cmsContentMapper.update(content);
            
            result = cmsContentLikeMapper.insert(likeRecord);
        }
        
        // 更新Redis中的LoginUser对象
        if (result > 0) {
            String token = loginUserCacheUtil.getTokenFromRequest();
            if (token != null) {
                loginUserCacheUtil.updateFavorites(token, userId);
            }
        }
        
        return result;
    }

    /**
     * 取消收藏
     *
     * @param contentId 内容ID
     * @return 影响行数
     */
    @Override
    public int removeFavorite(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        
        // 检查用户是否已经收藏过该内容
        CmsContentLike existingLike = cmsContentLikeMapper.queryByUserIdAndContentId(userId, contentId);
        if (existingLike == null) {
            return 0; // 没有收藏过，无需取消
        }
        
        // 删除收藏记录
        int result = cmsContentLikeMapper.deleteById(existingLike.getLikeId());
        
        // 减少内容的点赞数
        CmsContent content = this.cmsContentMapper.queryById(contentId);
        if (content != null && content.getLikeCount() > 0) {
            content.setLikeCount(content.getLikeCount() - 1);
            this.cmsContentMapper.update(content);
        }
        
        // 更新Redis中的LoginUser对象
        if (result > 0) {
            String token = loginUserCacheUtil.getTokenFromRequest();
            if (token != null) {
                loginUserCacheUtil.updateFavorites(token, userId);
            }
        }
        
        return result;
    }

    /**
     * 检查用户是否已收藏该内容
     *
     * @param contentId 内容ID
     * @return 是否已收藏
     */
    @Override
    public boolean isFavorited(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        try {
            // 获取当前登录用户ID
            Long userId = Long.parseLong(StpUtil.getLoginId().toString());
            CmsContentLike existingLike = cmsContentLikeMapper.queryByUserIdAndContentId(userId, contentId);
            return existingLike != null;
        } catch (Exception e) {
            // 未登录用户，返回false
            return false;
        }
    }

    /**
     * 添加查看记录
     *
     * @param contentId 内容ID
     * @return 影响行数
     */
    @Override
    public int addView(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        try {
            // 获取当前登录用户ID
            Long userId = Long.parseLong(StpUtil.getLoginId().toString());
            // 获取当前登录用户名
            String userName = StpUtil.getLoginIdAsString();
            
            // 检查内容是否存在
            CmsContent content = this.cmsContentMapper.queryById(contentId);
            if (content == null) {
                return 0;
            }
            
            // 检查用户是否已经查看过该内容（5分钟内）
            CmsContentView existingView = cmsContentViewMapper.queryByUserIdAndContentId(userId, contentId);
            int result = 0;
            if (existingView == null) {
                // 新增查看记录
                CmsContentView viewRecord = new CmsContentView();
                viewRecord.setUserId(userId);
                viewRecord.setUserName(userName);
                viewRecord.setContentId(contentId);
                viewRecord.setContentTitle(content.getTitle());
                viewRecord.setViewTime(new Date());
                viewRecord.setDeleteFlag(0);
                viewRecord.setCreateBy(userName);
                viewRecord.setUpdateBy(userName);
                result = cmsContentViewMapper.insert(viewRecord);
            } else {
                // 检查是否超过5分钟
                Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
                if (existingView.getViewTime().before(fiveMinutesAgo)) {
                    // 更新查看时间
                    existingView.setViewTime(new Date());
                    existingView.setUpdateBy(userName);
                    result = cmsContentViewMapper.update(existingView);
                }
                // 5分钟内已查看过，不重复记录
            }
            
            // 更新Redis中的LoginUser对象
            if (result > 0) {
                String token = loginUserCacheUtil.getTokenFromRequest();
                if (token != null) {
                    loginUserCacheUtil.updateHistory(token, userId);
                }
            }
            
            return result;
        } catch (Exception e) {
            // 未登录用户，不记录查看历史
            return 0;
        }
    }

    @Override
    public PageInfo<CmsContent> getPageListByUserHistory(CmsContentDto queryDto) {
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        
        // 添加参数校验，确保分页参数有效
        if (queryDto.getPageNum() == null || queryDto.getPageNum() < 1) {
            queryDto.setPageNum(BaseQueryDto.DEFAULT_CURRENT_PAGE);
        }
        if (queryDto.getPageSize() == null || queryDto.getPageSize() < 1) {
            queryDto.setPageSize(BaseQueryDto.DEFAULT_PAGE_SIZE);
        }
        
        // 计算偏移量
        int offset = (queryDto.getPageNum() - 1) * queryDto.getPageSize();
        int limit = queryDto.getPageSize();
        
        // 查询数据
        List<CmsContent> list = this.cmsContentMapper.getPageListByUserHistory(userId, offset, limit);
        int total = this.cmsContentMapper.getPageListByUserHistoryCount(userId);
        
        // 构建分页结果
        PageInfo<CmsContent> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(queryDto.getPageNum());
        pageInfo.setPageSize(queryDto.getPageSize());
        pageInfo.setPages((total + limit - 1) / limit);
        
        return pageInfo;
    }

    @Override
    public PageInfo<CmsContent> getPageListByUserFavorites(CmsContentDto queryDto) {
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        
        // 添加参数校验，确保分页参数有效
        if (queryDto.getPageNum() == null || queryDto.getPageNum() < 1) {
            queryDto.setPageNum(BaseQueryDto.DEFAULT_CURRENT_PAGE);
        }
        if (queryDto.getPageSize() == null || queryDto.getPageSize() < 1) {
            queryDto.setPageSize(BaseQueryDto.DEFAULT_PAGE_SIZE);
        }
        
        // 计算偏移量
        int offset = (queryDto.getPageNum() - 1) * queryDto.getPageSize();
        int limit = queryDto.getPageSize();
        
        // 查询数据
        List<CmsContent> list = this.cmsContentMapper.getPageListByUserFavorites(userId, offset, limit);
        int total = this.cmsContentMapper.getPageListByUserFavoritesCount(userId);
        
        // 构建分页结果
        PageInfo<CmsContent> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(queryDto.getPageNum());
        pageInfo.setPageSize(queryDto.getPageSize());
        pageInfo.setPages((total + limit - 1) / limit);
        
        return pageInfo;
    }

    @Override
    public PageInfo<CmsContent> getPageListByUserPurchases(CmsContentDto queryDto) {
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        
        // 添加参数校验，确保分页参数有效
        if (queryDto.getPageNum() == null || queryDto.getPageNum() < 1) {
            queryDto.setPageNum(BaseQueryDto.DEFAULT_CURRENT_PAGE);
        }
        if (queryDto.getPageSize() == null || queryDto.getPageSize() < 1) {
            queryDto.setPageSize(BaseQueryDto.DEFAULT_PAGE_SIZE);
        }
        
        // 计算偏移量
        int offset = (queryDto.getPageNum() - 1) * queryDto.getPageSize();
        int limit = queryDto.getPageSize();
        
        // 查询数据
        List<CmsContent> list = this.cmsContentMapper.getPageListByUserPurchases(userId, offset, limit);
        int total = this.cmsContentMapper.getPageListByUserPurchasesCount(userId);
        
        // 构建分页结果
        PageInfo<CmsContent> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(queryDto.getPageNum());
        pageInfo.setPageSize(queryDto.getPageSize());
        pageInfo.setPages((total + limit - 1) / limit);
        
        return pageInfo;
    }

    @Override
    public PageInfo<CmsContent> getPageListByUserCreated(CmsContentDto queryDto) {
        // 获取当前登录用户ID
        Long userId = Long.parseLong(StpUtil.getLoginId().toString());
        
        // 添加参数校验，确保分页参数有效
        if (queryDto.getPageNum() == null || queryDto.getPageNum() < 1) {
            queryDto.setPageNum(BaseQueryDto.DEFAULT_CURRENT_PAGE);
        }
        if (queryDto.getPageSize() == null || queryDto.getPageSize() < 1) {
            queryDto.setPageSize(BaseQueryDto.DEFAULT_PAGE_SIZE);
        }
        
        // 计算偏移量
        int offset = (queryDto.getPageNum() - 1) * queryDto.getPageSize();
        int limit = queryDto.getPageSize();
        
        // 查询数据
        List<CmsContent> list = this.cmsContentMapper.getPageListByUserCreated(userId, queryDto.getPublishStatus(), offset, limit);
        int total = this.cmsContentMapper.getPageListByUserCreatedCount(userId, queryDto.getPublishStatus());
        
        // 构建分页结果
        PageInfo<CmsContent> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(queryDto.getPageNum());
        pageInfo.setPageSize(queryDto.getPageSize());
        pageInfo.setPages((total + limit - 1) / limit);
        
        return pageInfo;
    }

    @Override
    public int importFromExcel(byte[] fileBytes, String createBy) {
        int successCount = 0;
        final int BATCH_SIZE = 10; // 批量处理大小
        
        try (InputStream inputStream = new ByteArrayInputStream(fileBytes);
             ExcelReader reader = ExcelUtil.getReader(inputStream)) {
            
            // 获取总行数（包括标题行）
            int totalRows = reader.getRowCount();
            if (totalRows <= 1) {
                // 只有标题行或空文件
                return 0;
            }
            
            Date now = new Date();
            List<CmsContent> batchList = new ArrayList<>(BATCH_SIZE);
            
            // 读取标题行
            List<Object> headerObjList = reader.readRow(0);
            if (headerObjList == null || headerObjList.isEmpty()) {
                return 0;
            }
            // 转换为List<String>
            List<String> headerList = new ArrayList<>();
            for (Object obj : headerObjList) {
                headerList.add(obj != null ? obj.toString() : "");
            }
            
            // 从第二行开始读取数据（第一行为标题行）
            for (int rowIndex = 1; rowIndex < totalRows; rowIndex++) {
                try {
                    List<Object> rowList = reader.readRow(rowIndex);
                    if (rowList == null || rowList.isEmpty()) {
                        continue;
                    }
                    
                    // 转换为Map<String, Object>
                    Map<String, Object> row = new HashMap<>();



                    for (int i = 0; i < headerList.size() && i < rowList.size(); i++) {
                        row.put(headerList.get(i), rowList.get(i));
                    }
                    if (row.isEmpty()) {
                        continue;
                    }

                    // 打印映射后的数据
                    System.out.println("映射后的数据：" + row);

                    CmsContent cmsContent = new CmsContent();
                    
                    // 设置创建时间和更新时间
                    cmsContent.setCreateTime(now);
                    cmsContent.setUpdateTime(now);
                    cmsContent.setCreateBy(createBy);
                    cmsContent.setUpdateBy(createBy);
                    
                    // 设置默认值
                    cmsContent.setDeleteFlag(0);
                    cmsContent.setAuditStatus(1); // 默认草稿状态
                    cmsContent.setPublishStatus(1); // 默认未发布状态
                    cmsContent.setViewCount(0);
                    cmsContent.setLikeCount(0);
                    cmsContent.setCommentCount(0);
                    cmsContent.setSort(0);
                    cmsContent.setIsOfficial(true); // 固定设置为1
                    
                    // 读取Excel中的字段
                    // content_id - 数据库自动生成，不需要读取
                    cmsContent.setTitle(getStringValue(row, "title"));
                    cmsContent.setTitleEn(getStringValue(row, "title_en"));
                    cmsContent.setOrigin(getStringValue(row, "origin"));
                    
                    // 处理tags字段，避免NullPointerException
                    String tags = getStringValue(row, "tags");
                    if (tags == null) {
                        System.err.println("第 " + rowIndex + " 行数据的tags字段为null，跳过该条记录");
                        continue;
                    }
                    cmsContent.setTags(tags.replaceAll(" ",""));
                    
                    cmsContent.setIcon(getStringValue(row, "icon"));
                    cmsContent.setIsOfficial(true); // 固定设置为1
                    cmsContent.setPrice(getBigDecimalValue(row, "price"));
                    cmsContent.setLikeCount(100 + new Random().nextInt(3000));
                    cmsContent.setShareCount(100 + new Random().nextInt(1000));
                    cmsContent.setContentType(getIntegerValue(row, "content_type"));
                    cmsContent.setContent(getStringValue(row, "content"));
                    cmsContent.setContentEn(getStringValue(row, "content_en"));
                    cmsContent.setAuditStatus(getIntegerValue(row, "audit_status"));
                    cmsContent.setPublishStatus(getIntegerValue(row, "publish_status"));
                    cmsContent.setPublishTime(now); // 设置为与update_time一致
                    cmsContent.setViewCount(getIntegerValue(row, "view_count"));
                    cmsContent.setCommentCount(getIntegerValue(row, "comment_count"));
                    cmsContent.setIsPaid(getIntegerValue(row, "is_paid"));
                    cmsContent.setSupportPointsPay(getIntegerValue(row, "support_points_pay"));
                    cmsContent.setDescription(getStringValue(row, "description"));
                    cmsContent.setDescriptionEn(getStringValue(row, "description_en"));
                    cmsContent.setIntroduce(getStringValue(row, "introduce"));
                    cmsContent.setIntroduceEn(getStringValue(row, "introduce_en"));
                    // create_time - 由系统生成，不需要读取
                    // update_time - 由系统生成，不需要读取
                    cmsContent.setDeleteFlag(getIntegerValue(row, "delete_flag"));
                    
                    batchList.add(cmsContent);
                    
                    // 达到批量大小或最后一行时，执行批量插入
                    if (batchList.size() >= BATCH_SIZE) {
                        if (!batchList.isEmpty()) {
                            // 执行批量插入
                            this.cmsContentMapper.batchInsert(batchList);
                            successCount += batchList.size();
                            batchList.clear(); // 清空批次
                        }
                    }
                } catch (Exception e) {
                    System.err.println("处理第 " + rowIndex + " 行数据时出错: " + e.getMessage());
                    e.printStackTrace();
                    // 跳过当前行，继续处理下一行
                    continue;
                }
            }
            
            // 处理最后一批不足BATCH_SIZE的数据
            if (!batchList.isEmpty()) {
                this.cmsContentMapper.batchInsert(batchList);
                successCount += batchList.size();
                batchList.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return successCount;
    }
    
    /**
     * 从Map中获取字符串值
     */
    private String getStringValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        return value != null ? value.toString() : null;
    }
    
    /**
     * 从Map中获取布尔值
     */
    private Boolean getBooleanValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        if (value instanceof String) {
            return Boolean.parseBoolean((String) value);
        }
        return null;
    }
    
    /**
     * 从Map中获取整数值
     */
    private Integer getIntegerValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 从Map中获取BigDecimal值
     */
    private BigDecimal getBigDecimalValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return BigDecimal.valueOf(((Number) value).doubleValue());
        }
        if (value instanceof String) {
            try {
                return new BigDecimal((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 从Map中获取日期值
     */
    private Date getDateValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Date) {
            return (Date) value;
        }
        return null;
    }
    
    @Override
    public String getContent(Long contentId, Integer languageType) {
        Assert.notNull(contentId, "内容ID不能为空");
        CmsContent cmsContent = this.cmsContentMapper.queryById(contentId);
        if (cmsContent == null) {
            return null;
        }
        
        // 当languageType为1时返回contentEn，否则返回content
        if (languageType != null && languageType == 1) {
            return cmsContent.getContentEn();
        } else {
            return cmsContent.getContent();
        }
    }
    
    @Override
    public String getTitle(Long contentId) {
        Assert.notNull(contentId, "内容ID不能为空");
        CmsContent cmsContent = this.cmsContentMapper.queryById(contentId);
        if (cmsContent == null) {
            return null;
        }
        return cmsContent.getTitle();
    }
    
    @Override
    public int importFromPath(ImportPathDto importPathDto, String createBy) {
        int totalSuccessCount = 0;
        
        try {
            // 检查目录是否存在
            File directory = new File(importPathDto.getFilePath());
            if (!directory.exists() || !directory.isDirectory()) {
                System.err.println("目录不存在或不是有效目录: " + importPathDto.getFilePath());
                return 0;
            }
            
            // 如果不是追加模式，清空表
            if (!importPathDto.isAppend()) {
                cmsContentMapper.truncateTable();
            }
            
            // 读取目录下所有 Excel 文件（排除 Office 临时锁定文件）
            File[] files = directory.listFiles((dir, name) -> {
                // 跳过以 ~$ 开头的临时锁定文件
                if (name.startsWith("~$")) {
                    return false;
                }
                return name.endsWith(".xls") || name.endsWith(".xlsx");
            });
            if (files == null || files.length == 0) {
                return 0;
            }
            
            // 记录文件总数
            int totalFiles = files.length;
            System.out.println("总共发现 " + totalFiles + " 个 Excel 文件需要导入");
            
            // 遍历所有 Excel 文件并导入
            for (int i = 0; i < files.length; i++) {
                File file = files[i];
                System.out.println("当前处理第 " + (i + 1) + " 个文件，文件名称是：" + file.getName());
                try (FileInputStream fis = new FileInputStream(file)) {
                    // 读取文件内容到字节数组
                    byte[] fileBytes = new byte[(int) file.length()];
                    fis.read(fileBytes);
                    
                    // 调用现有的 importFromExcel 方法进行导入
                    int successCount = importFromExcel(fileBytes, createBy);
                    totalSuccessCount += successCount;
                    System.out.println("第 " + (i + 1) + " 个文件导入成功，导入了 " + successCount + " 条记录");
                } catch (Exception e) {
                    System.err.println("导入文件失败: " + file.getAbsolutePath());
                    e.printStackTrace();
                    // 单个文件导入失败不影响其他文件
                    continue;
                }
            }
            System.out.println("导入完成，共处理 " + totalFiles + " 个文件，成功导入 " + totalSuccessCount + " 条记录");
        } catch (Exception e) {
            System.err.println("导入操作失败: " + importPathDto.getFilePath());
            e.printStackTrace();
        }
        
        return totalSuccessCount;
    }

    
}