package com.dora.service.impl;

import com.dora.dto.SearchDto;
import com.dora.entity.Course;
import com.dora.entity.User;
import com.dora.entity.Workflow;
import com.dora.mapper.CourseMapper;
import com.dora.mapper.UserMapper;
import com.dora.mapper.WorkflowMapper;
import com.dora.service.SearchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 搜索服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SearchServiceImpl implements SearchService {

    private static final String TYPE_COURSE = "course";
    private static final String TYPE_WORKFLOW = "workflow";
    private static final String TYPE_ALL = "all";
    private static final String PARAM_KEYWORD = "keyword";

    private final CourseMapper courseMapper;
    private final WorkflowMapper workflowMapper;
    private final UserMapper userMapper;

    @Override
    public SearchDto.SearchResponse search(SearchDto.SearchRequest request) {
        try {
            log.info("搜索内容 - keyword: {}, type: {}, category: {}", 
                    request.getKeyword(), request.getType(), request.getCategory());

            List<SearchDto.SearchResultItem> allResults = new ArrayList<>();
            long totalCount = 0;

            // 根据类型搜索
            boolean shouldSearchCourses = TYPE_ALL.equals(request.getType()) || TYPE_COURSE.equals(request.getType());
            boolean shouldSearchWorkflows = TYPE_ALL.equals(request.getType()) || TYPE_WORKFLOW.equals(request.getType());
            
            log.info("搜索决策 - shouldSearchCourses: {}, shouldSearchWorkflows: {}, requestType: '{}'", 
                    shouldSearchCourses, shouldSearchWorkflows, request.getType());

            if (shouldSearchCourses) {
                List<SearchDto.SearchResultItem> courseResults = searchCourses(request);
                log.info("课程搜索结果数量: {}", courseResults.size());
                allResults.addAll(courseResults);
            }

            if (shouldSearchWorkflows) {
                List<SearchDto.SearchResultItem> workflowResults = searchWorkflows(request);
                log.info("工作流搜索结果数量: {}", workflowResults.size());
                allResults.addAll(workflowResults);
            }

            // 排序
            allResults = sortResults(allResults, request.getSortBy(), request.getSortOrder(), request.getKeyword());

            // 分页
            int offset = (request.getPage() - 1) * request.getSize();
            int endIndex = Math.min(offset + request.getSize(), allResults.size());
            List<SearchDto.SearchResultItem> pagedResults = offset < allResults.size() ? 
                    allResults.subList(offset, endIndex) : new ArrayList<>();

            totalCount = allResults.size();

            // 最终结果调试日志
            long finalCourseCount = allResults.stream().filter(item -> TYPE_COURSE.equals(item.getType())).count();
            long finalWorkflowCount = allResults.stream().filter(item -> TYPE_WORKFLOW.equals(item.getType())).count();
            log.info("最终搜索结果 - course类型: {}, workflow类型: {}, 总数: {}, 请求类型: '{}'", 
                    finalCourseCount, finalWorkflowCount, totalCount, request.getType());

            // 构建响应
            SearchDto.SearchResponse response = new SearchDto.SearchResponse();
            response.setTotal(totalCount);
            response.setPage(request.getPage());
            response.setSize(request.getSize());
            response.setTotalPages((int) Math.ceil((double) totalCount / request.getSize()));
            response.setKeyword(request.getKeyword());
            response.setItems(pagedResults);

            return response;

        } catch (Exception e) {
            log.error("搜索内容失败", e);
            throw new RuntimeException("搜索失败", e);
        }
    }

    @Override
    public SearchDto.SearchStats getSearchStats(SearchDto.SearchRequest request) {
        try {
            SearchDto.SearchStats stats = new SearchDto.SearchStats();
            
            // 搜索课程和工作流，获取统计信息
            List<SearchDto.SearchResultItem> allResults = new ArrayList<>();
            
            if (TYPE_ALL.equals(request.getType()) || TYPE_COURSE.equals(request.getType())) {
                allResults.addAll(searchCourses(request));
            }
            
            if (TYPE_ALL.equals(request.getType()) || TYPE_WORKFLOW.equals(request.getType())) {
                allResults.addAll(searchWorkflows(request));
            }

            // 统计各类型数量
            long courseCount = allResults.stream().filter(item -> TYPE_COURSE.equals(item.getType())).count();
            long workflowCount = allResults.stream().filter(item -> TYPE_WORKFLOW.equals(item.getType())).count();

            stats.setCourseCount(courseCount);
            stats.setWorkflowCount(workflowCount);
            stats.setTotalCount(courseCount + workflowCount);

            // 统计分类信息
            Map<String, Long> categoryMap = allResults.stream()
                    .filter(item -> StringUtils.hasText(item.getCategory()))
                    .collect(Collectors.groupingBy(
                            SearchDto.SearchResultItem::getCategory,
                            Collectors.counting()
                    ));

            List<SearchDto.CategoryStats> categoryStats = categoryMap.entrySet().stream()
                    .map(entry -> {
                        SearchDto.CategoryStats categoryStatsItem = new SearchDto.CategoryStats();
                        categoryStatsItem.setCategoryName(entry.getKey());
                        categoryStatsItem.setCount(entry.getValue());
                        return categoryStatsItem;
                    })
                    .sorted(Comparator.comparing(SearchDto.CategoryStats::getCount).reversed())
                    .toList();

            stats.setCategoryStats(categoryStats);

            return stats;

        } catch (Exception e) {
            log.error("获取搜索统计失败", e);
            throw new RuntimeException("获取搜索统计失败", e);
        }
    }

    /**
     * 搜索课程
     */
    private List<SearchDto.SearchResultItem> searchCourses(SearchDto.SearchRequest request) {
        try {
            // 构建搜索条件
            Map<String, Object> params = new HashMap<>();
            params.put(PARAM_KEYWORD, request.getKeyword());
            params.put("category", request.getCategory());
            params.put("freeOnly", request.getFreeOnly());
            params.put("offset", 0);
            params.put("limit", 10000); // 先获取所有结果，后面再分页

            // 调用自定义的搜索方法（需要在Mapper中添加）
            List<Course> courses = courseMapper.searchCourses(params);
            
            // 获取创建者信息
            Set<Long> userIds = courses.stream()
                    .map(Course::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            final Map<Long, User> userMap;
            if (!userIds.isEmpty()) {
                List<User> users = userMapper.selectByIds(new ArrayList<>(userIds));
                userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));
            } else {
                userMap = new HashMap<>();
            }

            // 转换为SearchResultItem
            List<SearchDto.SearchResultItem> resultItems = courses.stream()
                    .map(course -> convertCourseToSearchItem(course, userMap.get(course.getUserId())))
                    .toList();
            
            // 调试日志：验证类型设置
            long courseTypeCount = resultItems.stream().filter(item -> TYPE_COURSE.equals(item.getType())).count();
            long workflowTypeCount = resultItems.stream().filter(item -> TYPE_WORKFLOW.equals(item.getType())).count();
            log.info("课程搜索转换结果 - course类型: {}, workflow类型: {}, 总数: {}", 
                    courseTypeCount, workflowTypeCount, resultItems.size());
            
            return resultItems;

        } catch (Exception e) {
            log.error("搜索课程失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 搜索工作流
     */
    private List<SearchDto.SearchResultItem> searchWorkflows(SearchDto.SearchRequest request) {
        try {
            // 构建搜索条件
            Map<String, Object> params = new HashMap<>();
            params.put(PARAM_KEYWORD, request.getKeyword());
            params.put("category", request.getCategory());
            params.put("freeOnly", request.getFreeOnly());
            params.put("offset", 0);
            params.put("limit", 10000); // 先获取所有结果，后面再分页

            // 调用自定义的搜索方法（需要在Mapper中添加）
            List<Workflow> workflows = workflowMapper.searchWorkflows(params);
            
            // 获取创建者信息
            Set<Long> userIds = workflows.stream()
                    .map(Workflow::getOwnerId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            final Map<Long, User> userMap;
            if (!userIds.isEmpty()) {
                List<User> users = userMapper.selectByIds(new ArrayList<>(userIds));
                userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));
            } else {
                userMap = new HashMap<>();
            }

            // 转换为SearchResultItem
            List<SearchDto.SearchResultItem> resultItems = workflows.stream()
                    .map(workflow -> convertWorkflowToSearchItem(workflow, userMap.get(workflow.getOwnerId())))
                    .toList();
            
            // 调试日志：验证类型设置
            long courseTypeCount = resultItems.stream().filter(item -> TYPE_COURSE.equals(item.getType())).count();
            long workflowTypeCount = resultItems.stream().filter(item -> TYPE_WORKFLOW.equals(item.getType())).count();
            log.info("工作流搜索转换结果 - course类型: {}, workflow类型: {}, 总数: {}", 
                    courseTypeCount, workflowTypeCount, resultItems.size());
            
            return resultItems;

        } catch (Exception e) {
            log.error("搜索工作流失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 对搜索结果排序
     */
    private List<SearchDto.SearchResultItem> sortResults(List<SearchDto.SearchResultItem> results, 
                                                         String sortBy, String sortOrder, String keyword) {
        if (results.isEmpty()) {
            return results;
        }

        Comparator<SearchDto.SearchResultItem> comparator;

        switch (sortBy) {
            case "createTime":
                comparator = Comparator.comparing(SearchDto.SearchResultItem::getCreateTime, 
                        Comparator.nullsLast(String::compareTo));
                break;
            case "updateTime":
                comparator = Comparator.comparing(SearchDto.SearchResultItem::getUpdateTime,
                        Comparator.nullsLast(String::compareTo));
                break;
            case "viewCount":
                comparator = Comparator.comparing(item -> 
                        item.getViewCount() != null ? item.getViewCount() : 0);
                break;
            case "likeCount":
                comparator = Comparator.comparing(item -> 
                        item.getLikeCount() != null ? item.getLikeCount() : 0);
                break;
            case "relevance":
            default:
                // 相关度排序：按标题匹配度、点赞数、创建时间综合排序
                comparator = Comparator.comparing((SearchDto.SearchResultItem item) -> {
                    int relevanceScore = 0;
                    // 修复：使用实际搜索关键词而非固定字符串
                    if (keyword != null && item.getTitle() != null && 
                        item.getTitle().toLowerCase().contains(keyword.toLowerCase())) {
                        relevanceScore += 100;
                    }
                    if (keyword != null && item.getDescription() != null && 
                        item.getDescription().toLowerCase().contains(keyword.toLowerCase())) {
                        relevanceScore += 50;
                    }
                    if (item.getLikeCount() != null) {
                        relevanceScore += Math.min(item.getLikeCount() / 100, 50); // 限制最大加分
                    }
                    return relevanceScore;
                }).reversed().thenComparing(SearchDto.SearchResultItem::getCreateTime,
                        Comparator.nullsLast(String::compareTo));
                break;
        }

        if ("asc".equals(sortOrder)) {
            results.sort(comparator);
        } else {
            results.sort(comparator.reversed());
        }

        return results;
    }

    /**
     * 将Course转换为SearchResultItem
     */
    private SearchDto.SearchResultItem convertCourseToSearchItem(Course course, User creator) {
        SearchDto.SearchResultItem item = new SearchDto.SearchResultItem();
        
        // 基本信息
        item.setId(course.getId());
        item.setType(TYPE_COURSE);
        item.setTitle(course.getTitle() != null ? course.getTitle() : "");
        item.setDescription(course.getDescription() != null ? course.getDescription() : "");
        item.setCoverUrl(course.getCoverUrl());
        item.setPrice(course.getPrice() != null ? course.getPrice().toString() : "0");
        item.setCategory(course.getCategory());
        item.setIsFree(course.getIsFree() != null && course.getIsFree() == 1);
        
        // 课程特有字段 - 使用真实数据
        item.setLevel(course.getLevel() != null ? course.getLevel() : 0);
        
        try {
            // 获取真实的课程时长
            Integer durationSec = courseMapper.getCourseDuration(course.getId());
            if (durationSec != null && durationSec > 0) {
                int hours = durationSec / 3600;
                int minutes = (durationSec % 3600) / 60;
                item.setDuration(String.format("%d:%02d", hours, minutes));
            } else {
                item.setDuration("0:00");
            }
            
            // 获取真实的观看数
            Integer viewCount = courseMapper.getCourseViewCount(course.getId());
            item.setViewCount(viewCount != null ? viewCount : 0);
            
            // 获取真实的点赞数
            Integer likeCount = courseMapper.getCourseLikeCount(course.getId());
            item.setLikeCount(likeCount != null ? likeCount : 0);
            
        } catch (Exception e) {
            log.warn("获取课程统计数据失败 - courseId: {}", course.getId(), e);
            // 如果查询失败，使用默认值
            item.setDuration("0:00");
            item.setViewCount(0);
            item.setLikeCount(0);
        }
        
        // 评论数暂时设为0（数据库中暂无评论表）
        item.setCommentCount(0);
        item.setVipType(getVipType(course.getLevel()));
        
        // 设置创建者信息
        if (creator != null) {
            SearchDto.CreatorInfo creatorInfo = new SearchDto.CreatorInfo();
            creatorInfo.setId(creator.getId().toString());
            creatorInfo.setUsername(creator.getUsername() != null ? creator.getUsername() : "");
            creatorInfo.setAvatarUrl(creator.getAvatarUrl());
            item.setCreator(creatorInfo);
        }
        
        // 时间字段
        item.setCreateTime(course.getCreateTime() != null ? 
                course.getCreateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null);
        item.setUpdateTime(course.getUpdateTime() != null ? 
                course.getUpdateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null);
        
        return item;
    }

    /**
     * 将Workflow转换为SearchResultItem
     */
    private SearchDto.SearchResultItem convertWorkflowToSearchItem(Workflow workflow, User creator) {
        SearchDto.SearchResultItem item = new SearchDto.SearchResultItem();
        
        // 基本信息
        item.setId(workflow.getId());
        item.setType(TYPE_WORKFLOW);
        item.setTitle(workflow.getName() != null ? workflow.getName() : "");
        item.setDescription(workflow.getDescription() != null ? workflow.getDescription() : "");
        item.setCoverUrl(workflow.getCoverUrl());
        item.setPrice(workflow.getPrice() != null ? workflow.getPrice().toString() : "0");
        item.setCategory(workflow.getCategory());
        item.setIsFree(workflow.getIsFree() != null && workflow.getIsFree() == 1);
        
        // 工作流特有字段 - 使用数据库中的真实数据
        item.setLikeCount(workflow.getLikeCount() != null ? workflow.getLikeCount() : 0);
        item.setRating(workflow.getRating() != null ? workflow.getRating() : 0);
        
        // 设置访问等级信息
        item.setFullAccessRole(workflow.getFullAccessRole());
        item.setFullAccessRoleName(getRoleNameByLevel(workflow.getFullAccessRole()));
        item.setCopyAccessRole(workflow.getCopyAccessRole());
        item.setCopyAccessRoleName(getRoleNameByLevel(workflow.getCopyAccessRole()));
        
        // 工作流没有观看数和评论数的概念，设为0或null
        item.setViewCount(0);
        item.setCommentCount(0);
        item.setDuration(null); // 工作流没有时长概念
        
        // 设置创建者信息
        if (creator != null) {
            SearchDto.CreatorInfo creatorInfo = new SearchDto.CreatorInfo();
            creatorInfo.setId(creator.getId().toString());
            creatorInfo.setUsername(creator.getUsername() != null ? creator.getUsername() : "");
            creatorInfo.setAvatarUrl(creator.getAvatarUrl());
            item.setCreator(creatorInfo);
        }
        
        // 时间字段
        item.setCreateTime(workflow.getCreateTime() != null ? 
                workflow.getCreateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null);
        item.setUpdateTime(workflow.getUpdateTime() != null ? 
                workflow.getUpdateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null);
        
        return item;
    }

    /**
     * 根据课程级别获取VIP类型
     * @deprecated 使用 CoursePermissionUtil.getVipType() 替代，确保全局一致性
     */
    @Deprecated
    private String getVipType(Integer level) {
        return com.dora.util.CoursePermissionUtil.getVipType(level);
    }
    
    /**
     * 根据级别获取角色名称
     */
    private String getRoleNameByLevel(Integer level) {
        if (level == null || level <= 0) {
            return "游客";
        } else if (level == 1) {
            return "普通用户";
        } else if (level == 2) {
            return "VIP用户";
        } else {
            return "SVIP用户";
        }
    }
}
