package top.tqx.demo_1.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tqx.demo_1.dto.*;
import top.tqx.demo_1.entity.*;
import top.tqx.demo_1.mapper.*;
import top.tqx.demo_1.service.ExamPaperService;
import top.tqx.demo_1.service.ExamService;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ExamPaperServiceImpl implements ExamPaperService {

    @Autowired
    private ExamPaperMapper examPaperMapper;

    @Autowired
    private ExamAssignmentMapper examAssignmentMapper;

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private ExamService examService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public ExamPaperGenerateResponse previewPaper(ExamPaperGenerateRequest request, Long userId, Long deptId, Integer userType) {
        return examService.generatePaper(request, userId, deptId, userType);
    }

    @Override
    public ExamPaperPreviewResponse previewPaperWithDetails(ExamPaperGenerateRequest request, Long userId, Long deptId, Integer userType) {
        log.info("生成试卷预览详情: userId={}, deptId={}, userType={}", userId, deptId, userType);
        
        ExamPaperGenerateResponse generateResponse = examService.generatePaper(request, userId, deptId, userType);
        
        ExamPaperPreviewResponse previewResponse = new ExamPaperPreviewResponse();
        previewResponse.setPaperId(generateResponse.getPaperId());
        previewResponse.setPaperTitle(generateResponse.getPaperTitle());
        previewResponse.setTotalScore(generateResponse.getTotalScore());
        previewResponse.setQuestionCount(generateResponse.getQuestionCount());
        previewResponse.setGeneratedAt(generateResponse.getGeneratedAt());
        previewResponse.setPermissionScope(generateResponse.getPermissionScope());
        previewResponse.setWarnings(generateResponse.getWarnings());
        
        List<ExamPaperPreviewResponse.ExamPaperQuestionDetail> detailedQuestions = new ArrayList<>();
        
        if (generateResponse.getQuestions() != null) {
            for (ExamPaperGenerateResponse.ExamPaperQuestion q : generateResponse.getQuestions()) {
                ExamPaperPreviewResponse.ExamPaperQuestionDetail detail = convertToDetailedQuestion(q);
                detailedQuestions.add(detail);
            }
        }
        
        previewResponse.setQuestions(detailedQuestions);
        
        log.info("试卷预览详情生成成功: paperId={}, questionCount={}", 
                previewResponse.getPaperId(), previewResponse.getQuestionCount());
        
        return previewResponse;
    }
    
    private ExamPaperPreviewResponse.ExamPaperQuestionDetail convertToDetailedQuestion(ExamPaperGenerateResponse.ExamPaperQuestion q) {
        ExamPaperPreviewResponse.ExamPaperQuestionDetail detail = new ExamPaperPreviewResponse.ExamPaperQuestionDetail();
        detail.setQuestionId(q.getQuestionId());
        detail.setQuestionType(q.getQuestionType());
        detail.setQuestionTypeName(q.getQuestionTypeName());
        detail.setDifficulty(q.getDifficulty());
        detail.setDifficultyName(getDifficultyName(q.getDifficulty()));
        detail.setScore(q.getScore());
        detail.setDocumentName(q.getDocumentName());
        detail.setKnowledgeBasePath(q.getKnowledgeBasePath());
        
        if (q.getContent() != null) {
            try {
                String contentJson = objectMapper.writeValueAsString(q.getContent());
                JSONObject contentObj = JSONObject.parseObject(contentJson);
                
                ExamPaperPreviewResponse.QuestionContent questionContent = new ExamPaperPreviewResponse.QuestionContent();
                
                if (contentObj.containsKey("stem")) {
                    questionContent.setStem(contentObj.getString("stem"));
                }
                if (contentObj.containsKey("options")) {
                    questionContent.setOptions(contentObj.get("options"));
                }
                if (contentObj.containsKey("answer")) {
                    questionContent.setAnswer(contentObj.get("answer"));
                }
                if (contentObj.containsKey("explanation")) {
                    questionContent.setExplanation(contentObj.getString("explanation"));
                }
                if (contentObj.containsKey("data")) {
                    questionContent.setData(contentObj.get("data"));
                }
                
                detail.setContent(questionContent);
            } catch (Exception e) {
                log.warn("解析题目内容失败: {}", e.getMessage());
            }
        }
        
        return detail;
    }
    
    private String getDifficultyName(Integer difficulty) {
        if (difficulty == null) {
            return "中等";
        }
        switch (difficulty) {
            case 1:
                return "简单";
            case 2:
                return "较易";
            case 3:
                return "中等";
            case 4:
                return "较难";
            case 5:
                return "困难";
            default:
                return "中等";
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ExamPaperResponse savePaper(ExamPaperSaveRequest request, Long userId) {
        User user = userMapper.selectById(userId);
        
        ExamPaper paper = new ExamPaper();
        paper.setPaperId(UUID.randomUUID().toString());
        paper.setTitle(request.getTitle());
        paper.setDescription(request.getDescription());
        
        // 设置时长，默认120分钟
        paper.setDuration(request.getDuration() != null ? request.getDuration() : 120);
        
        paper.setStatus("draft");
        paper.setPermissionScope(request.getPermissionScope());
        paper.setDeptId(user.getDeptId());
        
        try {
            String jsonStr = JSONArray.toJSONString(request.getQuestionIds());
            paper.setQuestionIds(objectMapper.readTree(jsonStr));
        } catch (Exception e) {
            throw new RuntimeException("解析题目ID列表失败", e);
        }
        
        // 自动计算总分和题数
        if (request.getQuestionIds() != null && !request.getQuestionIds().isEmpty()) {
            List<Question> questions = questionMapper.selectList(
                new LambdaQueryWrapper<Question>()
                    .in(Question::getQuestionId, request.getQuestionIds())
            );
            
            // 计算总分
            BigDecimal totalScore = BigDecimal.ZERO;
            for (Question q : questions) {
                if (q.getScore() != null) {
                    totalScore = totalScore.add(q.getScore());
                }
            }
            paper.setTotalScore(totalScore);
            
            // 计算题数
            paper.setQuestionCount(request.getQuestionIds().size());
        } else {
            paper.setQuestionCount(0);
            paper.setTotalScore(BigDecimal.ZERO);
        }
        
        paper.setCreatedBy(userId);
        paper.setCreatedAt(LocalDateTime.now());
        paper.setUpdatedAt(LocalDateTime.now());
        
        examPaperMapper.insert(paper);
        
        return convertToResponse(paper, false);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishPaper(String paperId, ExamPublishRequest request, Long userId) {
        ExamPaper paper = examPaperMapper.selectOne(
            new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));
        
        if (paper == null) {
            throw new RuntimeException("试卷不存在");
        }
        
        paper.setStatus("published");
        paper.setPublishTime(request.getPublishTime() != null ? request.getPublishTime() : LocalDateTime.now());
        paper.setDeadline(request.getDeadline());
        paper.setUpdatedAt(LocalDateTime.now());
        examPaperMapper.updateById(paper);
        
        ExamAssignment assignment = new ExamAssignment();
        assignment.setPaperId(paperId);
        
        // 兼容旧版：如果传了deptId，优先使用deptId
        if (request.getDeptId() != null) {
            assignment.setDeptId(request.getDeptId());
        }
        
        // 支持新版多部门：如果传了deptIds列表，使用deptIds
        if (request.getDeptIds() != null && !request.getDeptIds().isEmpty()) {
            try {
                assignment.setDeptIds(objectMapper.readTree(JSONArray.toJSONString(request.getDeptIds())));
            } catch (Exception e) {
                throw new RuntimeException("解析部门ID列表失败", e);
            }
        }
        
        try {
            if (request.getUserIds() != null) {
                assignment.setUserIds(objectMapper.readTree(JSONArray.toJSONString(request.getUserIds())));
            }
            if (request.getExcludeUserIds() != null) {
                assignment.setExcludeUserIds(objectMapper.readTree(JSONArray.toJSONString(request.getExcludeUserIds())));
            }
        } catch (Exception e) {
            throw new RuntimeException("解析用户ID列表失败", e);
        }
        
        assignment.setStatus("active");
        assignment.setPublishTime(paper.getPublishTime());
        assignment.setDeadline(paper.getDeadline());
        assignment.setCreatedAt(LocalDateTime.now());
        assignment.setUpdatedAt(LocalDateTime.now());
        examAssignmentMapper.insert(assignment);
        
        List<Long> targetUserIds = getTargetUserIds(request);
        
        for (Long uid : targetUserIds) {
            ExamRecord record = new ExamRecord();
            record.setRecordId(UUID.randomUUID().toString());
            record.setPaperId(paperId);
            record.setAnswerType("formal_exam");
            record.setUserId(uid);
            record.setStatus("not_started");
            record.setCreatedAt(LocalDateTime.now());
            record.setUpdatedAt(LocalDateTime.now());
            examRecordMapper.insert(record);
        }
    }

    private List<Long> getTargetUserIds(ExamPublishRequest request) {
        Set<Long> userIds = new HashSet<>();
        
        // 兼容旧版：单个部门
        if (request.getDeptId() != null) {
            List<User> deptUsers = userMapper.selectList(
                new LambdaQueryWrapper<User>()
                    .eq(User::getDeptId, request.getDeptId())
                    .eq(User::getStatus, 1));
            userIds.addAll(deptUsers.stream().map(User::getId).collect(Collectors.toList()));
        }
        
        // 支持新版：多个部门
        if (request.getDeptIds() != null && !request.getDeptIds().isEmpty()) {
            List<User> multiDeptUsers = userMapper.selectList(
                new LambdaQueryWrapper<User>()
                    .in(User::getDeptId, request.getDeptIds())
                    .eq(User::getStatus, 1));
            userIds.addAll(multiDeptUsers.stream().map(User::getId).collect(Collectors.toList()));
        }
        
        // 指定用户
        if (request.getUserIds() != null) {
            userIds.addAll(request.getUserIds());
        }
        
        // 排除用户
        if (request.getExcludeUserIds() != null) {
            userIds.removeAll(request.getExcludeUserIds());
        }
        
        return new ArrayList<>(userIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokePaper(String paperId) {
        ExamPaper paper = examPaperMapper.selectOne(
            new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));
        
        if (paper != null) {
            paper.setStatus("draft");
            paper.setPublishTime(null);
            paper.setDeadline(null);
            paper.setUpdatedAt(LocalDateTime.now());
            examPaperMapper.updateById(paper);
        }
        
        ExamAssignment updateAssignment = new ExamAssignment();
        updateAssignment.setStatus("revoked");
        LambdaQueryWrapper<ExamAssignment> assignmentWrapper = 
            new LambdaQueryWrapper<ExamAssignment>().eq(ExamAssignment::getPaperId, paperId);
        examAssignmentMapper.update(updateAssignment, assignmentWrapper);
        
        examRecordMapper.delete(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getPaperId, paperId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePaper(String paperId) {
        examRecordMapper.delete(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getPaperId, paperId));
        examAssignmentMapper.delete(new LambdaQueryWrapper<ExamAssignment>().eq(ExamAssignment::getPaperId, paperId));
        examPaperMapper.delete(new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));
    }

    @Override
    public ExamPaperResponse getPaperById(String paperId) {
        ExamPaper paper = examPaperMapper.selectOne(
            new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));
        
        if (paper == null) {
            return null;
        }
        
        return convertToResponse(paper, true);
    }

    @Override
    public PageResponse<ExamPaperResponse> listPapers(String status, Integer page, Integer pageSize) {
        Page<ExamPaper> pageQuery = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<ExamPaper> wrapper = new LambdaQueryWrapper<>();
        if (status != null && !status.isEmpty()) {
            wrapper.eq(ExamPaper::getStatus, status);
        }
        wrapper.orderByDesc(ExamPaper::getCreatedAt);
        
        Page<ExamPaper> resultPage = examPaperMapper.selectPage(pageQuery, wrapper);
        
        List<ExamPaperResponse> responses = resultPage.getRecords().stream()
            .map(p -> convertToResponse(p, false))
            .collect(Collectors.toList());
        
        return new PageResponse<>(responses, resultPage.getTotal(), page, pageSize);
    }

    @Override
    public List<ExamPaperResponse> listPapersByDept(Long deptId) {
        List<ExamPaper> papers = examPaperMapper.selectList(
            new LambdaQueryWrapper<ExamPaper>()
                .eq(ExamPaper::getDeptId, deptId)
                .eq(ExamPaper::getStatus, "published"));
        
        return papers.stream()
            .map(p -> convertToResponse(p, false))
            .collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> getPaperAssignment(String paperId) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取分配记录
        List<ExamAssignment> assignments = examAssignmentMapper.selectList(
            new LambdaQueryWrapper<ExamAssignment>()
                .eq(ExamAssignment::getPaperId, paperId)
        );
        
        if (assignments == null || assignments.isEmpty()) {
            result.put("deptIds", new ArrayList<>());
            result.put("deptNames", new ArrayList<>());
            result.put("userIds", new ArrayList<>());
            result.put("excludeUserIds", new ArrayList<>());
            result.put("targetUserCount", 0);
            return result;
        }
        
        ExamAssignment assignment = assignments.get(0);
        
        // 获取部门ID列表
        List<Long> deptIdList = new ArrayList<>();
        if (assignment.getDeptIds() != null && !assignment.getDeptIds().isNull()) {
            if (assignment.getDeptIds().isArray()) {
                for (JsonNode node : assignment.getDeptIds()) {
                    deptIdList.add(node.asLong());
                }
            }
        } else if (assignment.getDeptId() != null) {
            // 兼容旧数据：单个部门
            deptIdList.add(assignment.getDeptId());
        }
        result.put("deptIds", deptIdList);
        
        // 获取部门名称
        List<Map<String, Object>> deptInfoList = new ArrayList<>();
        if (!deptIdList.isEmpty()) {
            List<Department> departments = departmentMapper.selectBatchIds(deptIdList);
            for (Department dept : departments) {
                Map<String, Object> deptInfo = new HashMap<>();
                deptInfo.put("id", dept.getId());
                deptInfo.put("name", dept.getDeptName());
                deptInfo.put("code", dept.getDeptCode());
                deptInfoList.add(deptInfo);
            }
        }
        result.put("depts", deptInfoList);
        
        // 获取用户ID列表
        List<Long> userIdList = new ArrayList<>();
        if (assignment.getUserIds() != null && !assignment.getUserIds().isNull()) {
            if (assignment.getUserIds().isArray()) {
                for (JsonNode node : assignment.getUserIds()) {
                    userIdList.add(node.asLong());
                }
            }
        }
        result.put("userIds", userIdList);
        
        // 获取排除用户ID列表
        List<Long> excludeUserIdList = new ArrayList<>();
        if (assignment.getExcludeUserIds() != null && !assignment.getExcludeUserIds().isNull()) {
            if (assignment.getExcludeUserIds().isArray()) {
                for (JsonNode node : assignment.getExcludeUserIds()) {
                    excludeUserIdList.add(node.asLong());
                }
            }
        }
        result.put("excludeUserIds", excludeUserIdList);
        
        // 计算目标用户数量
        Set<Long> targetUserIds = new HashSet<>();
        if (!deptIdList.isEmpty()) {
            List<User> deptUsers = userMapper.selectList(
                new LambdaQueryWrapper<User>()
                    .in(User::getDeptId, deptIdList)
                    .eq(User::getStatus, 1));
            targetUserIds.addAll(deptUsers.stream().map(User::getId).collect(Collectors.toList()));
        }
        if (!userIdList.isEmpty()) {
            targetUserIds.addAll(userIdList);
        }
        targetUserIds.removeAll(excludeUserIdList);
        result.put("targetUserCount", targetUserIds.size());
        
        return result;
    }

    private ExamPaperResponse convertToResponse(ExamPaper paper, boolean includeQuestions) {
        ExamPaperResponse response = new ExamPaperResponse();
        response.setPaperId(paper.getPaperId());
        response.setTitle(paper.getTitle());
        response.setDescription(paper.getDescription());
        response.setTotalScore(paper.getTotalScore());
        response.setDuration(paper.getDuration());
        response.setQuestionCount(paper.getQuestionCount());
        response.setStatus(paper.getStatus());
        response.setPermissionScope(paper.getPermissionScope());
        response.setDeptId(paper.getDeptId());
        response.setCreatedBy(paper.getCreatedBy());
        response.setCreatedAt(paper.getCreatedAt());
        response.setUpdatedAt(paper.getUpdatedAt());
        response.setPublishTime(paper.getPublishTime());
        response.setDeadline(paper.getDeadline());
        
        // 添加分配信息
        if (paper.getPaperId() != null) {
            ExamAssignment assignment = examAssignmentMapper.selectOne(
                new LambdaQueryWrapper<ExamAssignment>()
                    .eq(ExamAssignment::getPaperId, paper.getPaperId())
                    .eq(ExamAssignment::getStatus, "active")
            );
            
            if (assignment != null) {
                // 设置部门ID列表（多部门）
                if (assignment.getDeptIds() != null && !assignment.getDeptIds().isNull()) {
                    try {
                        List<Long> deptIdList = new ArrayList<>();
                        if (assignment.getDeptIds().isArray()) {
                            for (JsonNode node : assignment.getDeptIds()) {
                                deptIdList.add(node.asLong());
                            }
                        }
                        response.setDeptIds(deptIdList);
                    } catch (Exception e) {
                        log.warn("解析deptIds失败: {}", e.getMessage());
                    }
                }
                
                // 设置用户ID列表
                if (assignment.getUserIds() != null && !assignment.getUserIds().isNull()) {
                    try {
                        List<Long> userIdList = new ArrayList<>();
                        if (assignment.getUserIds().isArray()) {
                            for (JsonNode node : assignment.getUserIds()) {
                                userIdList.add(node.asLong());
                            }
                        }
                        response.setUserIds(userIdList);
                    } catch (Exception e) {
                        log.warn("解析userIds失败: {}", e.getMessage());
                    }
                }
                
                // 设置排除用户ID列表
                if (assignment.getExcludeUserIds() != null && !assignment.getExcludeUserIds().isNull()) {
                    try {
                        List<Long> excludeUserIdList = new ArrayList<>();
                        if (assignment.getExcludeUserIds().isArray()) {
                            for (JsonNode node : assignment.getExcludeUserIds()) {
                                excludeUserIdList.add(node.asLong());
                            }
                        }
                        response.setExcludeUserIds(excludeUserIdList);
                    } catch (Exception e) {
                        log.warn("解析excludeUserIds失败: {}", e.getMessage());
                    }
                }
            }
        }
        
        if (includeQuestions && paper.getQuestionIds() != null) {
            List<String> questionIdList = new ArrayList<>();
            if (paper.getQuestionIds().isArray()) {
                for (JsonNode node : paper.getQuestionIds()) {
                    questionIdList.add(node.asText());
                }
            }
            
            List<ExamPaperResponse.ExamPaperQuestion> questions = new ArrayList<>();
            for (String qId : questionIdList) {
                Question question = questionMapper.selectOne(
                    new LambdaQueryWrapper<Question>().eq(Question::getQuestionId, qId));
                
                if (question != null) {
                    ExamPaperResponse.ExamPaperQuestion q = new ExamPaperResponse.ExamPaperQuestion();
                    q.setQuestionId(question.getQuestionId());
                    q.setQuestionType(question.getQuestionType());
                    q.setDifficulty(question.getDifficulty());
                    q.setScore(question.getScore());
                    q.setContent(question.getContent() != null ? question.getContent().toString() : "");
                    
                    if (question.getContent() != null) {
                        try {
                            JSONObject contentObj = JSONObject.parseObject(q.getContent());
                            if (contentObj != null) {
                                q.setAnswer(contentObj.getString("answer"));
                                q.setAnalysis(contentObj.getString("analysis"));
                            }
                        } catch (Exception e) {
                            log.warn("解析题目内容失败: {}", e.getMessage());
                        }
                    }
                    
                    questions.add(q);
                }
            }
            
            response.setQuestions(questions);
        }
        
        return response;
    }
}