package com.seer.teach.mp.app.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.mp.app.controller.req.AppMpSignUpActivityReq;
import com.seer.teach.mp.app.controller.req.TestChildCharacterReq;
import com.seer.teach.mp.app.controller.resp.AppMpSignUpActivityResp;
import com.seer.teach.mp.app.controller.resp.TestChildCharacterResp;
import com.seer.teach.mp.app.convert.AppMpActivityInfoCollectionConvert;
import com.seer.teach.mp.entity.MpActivityEntity;
import com.seer.teach.mp.entity.MpActivityInfoCollectionEntity;
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
import com.seer.teach.mp.entity.MpAgentEntity;
import com.seer.teach.mp.entity.MpParentAgentActivityRelationEntity;
import com.seer.teach.mp.service.IMpActivityInfoCollectionService;
import com.seer.teach.mp.service.IMpActivityService;
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
import com.seer.teach.mp.service.IMpAgentService;
import com.seer.teach.mp.service.IMpParentAgentActivityRelationService;
import com.seer.teach.teacher.service.AiModelCallService;
import com.seer.teach.teacher.service.platform.LlmResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Objects;

@RequiredArgsConstructor
@Slf4j
@Service
public class AppParentAgentActivityService implements IAppParentAgentActivityService {

    private final IMpParentAgentActivityRelationService parentAgentActivityRelationService;
    private final IMpActivityInfoCollectionService activityInfoCollectionService;
    private final IMpActivityService activityService;
    private final IMpAgentService agentService;
    private final IMpAgentActivityParticipantService mpAgentActivityParticipantService;
    private final AiModelCallService aiModelCallService;

    /**
     * 报名活动
     *
     * @param request 报名信息
     * @param parentId 家长ID
     * @return true表示成功，false表示失败
     */
    @Transactional(rollbackFor = Exception.class,timeout = 120)
    public boolean signUpForActivityWithInfo(AppMpSignUpActivityReq request, Integer parentId) {
        Integer agentId = request.getAgentId();
        Integer activityId = request.getActivityId();
        MpActivityEntity activity = activityService.getById(activityId);
        AssertUtils.notNull(activity, ResultCodeEnum.INVALID_ACTIVITY);

        MpAgentEntity agent = agentService.getById(agentId);
        AssertUtils.notNull(agent, ResultCodeEnum.INVALID_AGENT);

        MpAgentActivityParticipantEntity participants = mpAgentActivityParticipantService.getParticipantsByActivityAndAgent(request.getActivityId(), request.getAgentId());
        AssertUtils.notNull(participants, ResultCodeEnum.AGENT_NON_PARTICIPANT_ACTIVE);

        MpParentAgentActivityRelationEntity relation = parentAgentActivityRelationService.getByAgentIdAndActivityIdAndParentId(agentId, activityId, parentId);
        AssertUtils.isNull(relation, ResultCodeEnum.PARENT_ALREADY_SIGN_UP);

        relation = new MpParentAgentActivityRelationEntity();
        relation.setActivityId(activityId);
        relation.setAgentId(agentId);
        relation.setParentId(parentId);
        relation.setActivityName(activity.getActivityName());
        relation.setAgentName(agent.getAgentName());
        relation.setStatus(1);
        relation.setSignUpTime(LocalDateTime.now());
        boolean saved = parentAgentActivityRelationService.save(relation);
        log.info("报名结果：{}，关系ID：{}", saved, relation.getId());

        if(saved){
            MpActivityInfoCollectionEntity mpActivityInfoCollectionEntity = AppMpActivityInfoCollectionConvert.INSTANCE.convertOne2Entity(request);
            mpActivityInfoCollectionEntity.setRelationId(relation.getId());
            boolean activityInfoCollectionResult = activityInfoCollectionService.save(mpActivityInfoCollectionEntity);
            log.info("活动信息收集结果：{}", activityInfoCollectionResult);
            return activityInfoCollectionResult;
        }
        return false;
    }

    /**
     * 更新活动信息
     *
     * @param request 活动信息
     * @param parentId 家长ID
     * @return true表示成功，false表示失败
     */
    public boolean updateActivityInfo(AppMpSignUpActivityReq request, Integer parentId) {
        Integer agentId = request.getAgentId();
        Integer activityId = request.getActivityId();
        MpParentAgentActivityRelationEntity relation = parentAgentActivityRelationService.getByAgentIdAndActivityIdAndParentId(agentId, activityId, parentId);
        AssertUtils.notNull(relation, ResultCodeEnum.PARENT_NOT_SIGNED_UP);
        MpActivityInfoCollectionEntity mpActivityInfoCollectionEntity = AppMpActivityInfoCollectionConvert.INSTANCE.convertOne2Entity(request);
        mpActivityInfoCollectionEntity.setRelationId(relation.getId());
        return activityInfoCollectionService.updateById(mpActivityInfoCollectionEntity);
    }

    /**
     * 取消报名
     *
     * @param relationId 关系ID
     * @param parentId   家长ID
     * @return true表示成功，false表示失败
     */
    public boolean cancelSignUp(Integer relationId, Integer parentId) {
        MpParentAgentActivityRelationEntity relation = parentAgentActivityRelationService.getById(relationId);
        if (Objects.nonNull(relation) && relation.getParentId().equals(parentId)) {
            relation.setStatus(0);
            boolean result = parentAgentActivityRelationService.updateById(relation);
            log.info("取消报名结果：{}", result);
            return result;
        }
        return false;
    }


    /**
     * 获取报名信息
     *
     * @param agentId    代理商ID
     * @param activityId 活动ID
     * @param parentId   家长ID
     * @return 报名信息
     */
    public AppMpSignUpActivityResp getByActivityIdAndParentId(Integer agentId, Integer activityId, Integer parentId) {
        LambdaQueryWrapper<MpParentAgentActivityRelationEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MpParentAgentActivityRelationEntity::getActivityId, activityId)
                .eq(MpParentAgentActivityRelationEntity::getParentId, parentId)
                .eq(MpParentAgentActivityRelationEntity::getAgentId, agentId);
        MpParentAgentActivityRelationEntity one = parentAgentActivityRelationService.getOne(wrapper);
        AssertUtils.notNull(one, ResultCodeEnum.INVALID_ACTIVITY);
        MpActivityInfoCollectionEntity activityInfoCollection = activityInfoCollectionService.getByActivityIdAndParentId(agentId, activityId, parentId);
        return AppMpActivityInfoCollectionConvert.INSTANCE.convert2Resp(activityInfoCollection);
    }

    /**
     * 测试孩子性格
     *
     * @param request 测试请求对象
     * @param parentId 家长ID
     * @return 性格测试结果
     */
    public TestChildCharacterResp testChildCharacter(TestChildCharacterReq request, Integer parentId) {
        log.info("开始测试孩子性格，家长ID: {}，请求参数: {}", parentId, request);

        // 构建AI模型的提示词
        String prompt = buildCharacterTestPrompt(request);

        // 调用AI模型获取性格分析
        LlmResponse response = aiModelCallService.callModel("child_character_analysis", prompt, new HashMap<>(), parentId);

        TestChildCharacterResp result = new TestChildCharacterResp();

        if (response != null && response.getChoices() != null && !response.getChoices().isEmpty()) {
            // 获取AI返回的内容
            String content = response.getChoices().get(0).getMessage().getContent();
            result = parseAiResponse(content);
        } else {
            // 如果AI调用失败，返回默认响应
            result.setCharacterAnalysis("暂时无法分析孩子的性格，请稍后重试。");
            result.setCharacterTraits("未知");
            result.setSuggestions("请尝试重新分析或咨询专业教育专家。");
            result.setCharacterType("待定");
        }

        log.info("性格测试完成，返回结果: {}", result);
        return result;
    }

    /**
     * 构建性格测试的提示词
     *
     * @param request 请求参数
     * @return 提示词内容
     */
    private String buildCharacterTestPrompt(TestChildCharacterReq request) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("请根据以下孩子信息分析其性格特点，并给出教育建议：\n");
        prompt.append("- 性别: ").append(request.getChildGender()).append("\n");
        prompt.append("- 出生日期: ").append(request.getChildBirthDate()).append("\n");
        prompt.append("- 星座: ").append(request.getConstellation() != null ? request.getConstellation() : "未知").append("\n");
        prompt.append("- 年级: ").append(request.getGrade()).append("\n");
        prompt.append("- 学习情况: ").append(request.getLearningSituation()).append("\n");
        prompt.append("- 偏科情况: ").append(request.getWeakSubject()).append("\n");
        prompt.append("\n请按照以下格式返回分析结果：\n");
        prompt.append("1. 性格分析：[具体分析内容]\n");
        prompt.append("2. 性格特征：[关键特征]\n");
        prompt.append("3. 教育建议：[针对性建议]\n");
        prompt.append("4. 性格类型：[简要分类]");
        
        return prompt.toString();
    }

    /**
     * 解析AI返回的结果
     *
     * @param aiResponse AI返回的原始内容
     * @return 解析后的响应对象
     */
    private TestChildCharacterResp parseAiResponse(String aiResponse) {
        TestChildCharacterResp resp = new TestChildCharacterResp();
        
        // 简单解析AI返回的内容
        String[] parts = aiResponse.split("\n");
        for (String part : parts) {
            if (part.startsWith("1. 性格分析：") || part.contains("性格分析")) {
                resp.setCharacterAnalysis(part.replaceFirst("^[0-9]+\\.\\s*", "").replace("性格分析：", "").trim());
            } else if (part.startsWith("2. 性格特征：") || part.contains("性格特征")) {
                resp.setCharacterTraits(part.replaceFirst("^[0-9]+\\.\\s*", "").replace("性格特征：", "").trim());
            } else if (part.startsWith("3. 教育建议：") || part.contains("教育建议")) {
                resp.setSuggestions(part.replaceFirst("^[0-9]+\\.\\s*", "").replace("教育建议：", "").trim());
            } else if (part.startsWith("4. 性格类型：") || part.contains("性格类型")) {
                resp.setCharacterType(part.replaceFirst("^[0-9]+\\.\\s*", "").replace("性格类型：", "").trim());
            }
        }
        
        // 如果解析失败，将整个内容作为性格分析
        if (resp.getCharacterAnalysis() == null || resp.getCharacterAnalysis().isEmpty()) {
            resp.setCharacterAnalysis(aiResponse);
        }
        
        return resp;
    }
}