package com.emotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.PageResult;
import com.emotion.dto.request.EpicScriptCreateRequest;
import com.emotion.dto.request.EpicScriptPageRequest;
import com.emotion.dto.request.EpicScriptUpdateRequest;
import com.emotion.dto.response.EpicScriptResponse;
import com.emotion.entity.EpicScript;
import com.emotion.mapper.EpicScriptMapper;
import com.emotion.service.AiChatService;
import com.emotion.service.EpicScriptService;
import com.emotion.service.LifePathService;
import com.emotion.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 爽文剧本服务实现类
 *
 * @author huazhongmin
 * @date 2025-12-22
 */
@Slf4j
@Service
public class EpicScriptServiceImpl extends ServiceImpl<EpicScriptMapper, EpicScript>
        implements EpicScriptService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * Coze工作流配置键 - 爽文剧本生成
     */
    private static final String COZE_EPIC_SCRIPT_CONFIG_KEY = "coze.course.life.generate";

    @Autowired
    @Lazy
    private LifePathService lifePathService;

    @Autowired
    private AiChatService aiChatService;

    @Override
    public PageResult<EpicScriptResponse> getPageByCurrentUser(EpicScriptPageRequest request) {
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (currentUserId == null) {
            return new PageResult<>();
        }

        Page<EpicScript> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<EpicScript> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EpicScript::getUserId, currentUserId)
                .eq(EpicScript::getIsDeleted, 0);

        // 风格筛选
        if (StringUtils.hasText(request.getStyle())) {
            wrapper.eq(EpicScript::getStyle, request.getStyle());
        }

        // 篇幅筛选
        if (StringUtils.hasText(request.getLength())) {
            wrapper.eq(EpicScript::getLength, request.getLength());
        }

        // 关键词搜索
        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w.like(EpicScript::getTitle, request.getKeyword())
                    .or().like(EpicScript::getTheme, request.getKeyword()));
        }

        // 按创建时间倒序排列
        wrapper.orderByDesc(EpicScript::getCreateTime);

        Page<EpicScript> resultPage = this.page(page, wrapper);
        List<EpicScriptResponse> responses = resultPage.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());

        PageResult<EpicScriptResponse> pageResult = new PageResult<>();
        pageResult.setCurrent(resultPage.getCurrent());
        pageResult.setSize(resultPage.getSize());
        pageResult.setTotal(resultPage.getTotal());
        pageResult.setPages(resultPage.getPages());
        pageResult.setRecords(responses);

        return pageResult;
    }

    @Override
    public List<EpicScriptResponse> getListByCurrentUser() {
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (currentUserId == null) {
            return List.of();
        }

        LambdaQueryWrapper<EpicScript> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EpicScript::getUserId, currentUserId)
                .eq(EpicScript::getIsDeleted, 0)
                .orderByDesc(EpicScript::getCreateTime);

        return this.list(wrapper).stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    @Override
    public EpicScriptResponse getScriptById(String id) {
        EpicScript script = this.getById(id);
        if (script == null || script.getIsDeleted() == 1) {
            return null;
        }

        // 验证权限
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (!script.getUserId().equals(currentUserId)) {
            return null;
        }

        return convertToResponse(script);
    }

    @Override
    public EpicScriptResponse createScript(EpicScriptCreateRequest request) {
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (currentUserId == null) {
            return null;
        }

        EpicScript script = new EpicScript();
        script.setUserId(currentUserId);
        script.setTitle(request.getTitle());
        script.setTheme(request.getTheme());
        script.setStyle(StringUtils.hasText(request.getStyle()) ? request.getStyle() : "career");
        script.setLength(StringUtils.hasText(request.getLength()) ? request.getLength() : "medium");
        script.setPlotIntro(request.getPlotIntro());
        script.setPlotTurning(request.getPlotTurning());
        script.setPlotClimax(request.getPlotClimax());
        script.setPlotEnding(request.getPlotEnding());
        script.setPlotJson(request.getPlotJson());
        script.setIsSelected(request.getIsSelected() != null && request.getIsSelected() ? 1 : 0);

        // 调用Coze AI生成剧本内容
        String aiGeneratedContent = generateScriptByAi(request, currentUserId);
        if (aiGeneratedContent != null) {
            // 将AI生成的内容存储到plotJson中
            Map<String, Object> plotJson = script.getPlotJson();
            if (plotJson == null) {
                plotJson = new java.util.HashMap<>();
            }
            plotJson.put("fullContent", aiGeneratedContent);
            script.setPlotJson(plotJson);
            log.info("AI生成剧本内容成功，用户ID: {}, 内容长度: {}", currentUserId, aiGeneratedContent.length());
        }

        this.save(script);
        return convertToResponse(script);
    }

    /**
     * 调用Coze AI生成爽文剧本内容
     *
     * @param request 剧本创建请求
     * @param userId 用户ID
     * @return AI生成的剧本内容，失败时返回null
     */
    private String generateScriptByAi(EpicScriptCreateRequest request, String userId) {
        try {
            // 组装AI输入
            String input = assembleScriptInput(request);
            log.info("开始调用AI生成剧本，用户ID: {}, 输入长度: {}", userId, input.length());

            // 调用Coze工作流
            String result = aiChatService.callWorkflowByConfigKey(COZE_EPIC_SCRIPT_CONFIG_KEY, input, userId);

            log.info("AI生成剧本完成，用户ID: {}, 结果长度: {}", userId, result != null ? result.length() : 0);
            return result;

        } catch (Exception e) {
            log.error("AI生成剧本失败，用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            // AI调用失败不影响剧本创建，返回null
            return null;
        }
    }

    /**
     * 组装AI输入内容
     * 将EpicScriptCreateRequest的字段组装为格式化字符串
     *
     * @param request 剧本创建请求
     * @return 格式化的输入字符串
     */
    private String assembleScriptInput(EpicScriptCreateRequest request) {
        StringBuilder sb = new StringBuilder();

        // 角色信息
        if (StringUtils.hasText(request.getCharacterInfo())) {
            sb.append("【角色信息】").append(request.getCharacterInfo()).append("\n");
        }

        // 过往经历
        if (StringUtils.hasText(request.getLifeEventsSummary())) {
            sb.append("【过往经历】").append(request.getLifeEventsSummary()).append("\n");
        }

        // 标题
        if (StringUtils.hasText(request.getTitle())) {
            sb.append("【剧本标题】").append(request.getTitle()).append("\n");
        }

        // 主题/渴望
        if (StringUtils.hasText(request.getTheme())) {
            sb.append("【主题渴望】").append(request.getTheme()).append("\n");
        }

        // 风格
        if (StringUtils.hasText(request.getStyle())) {
            String styleDesc = getStyleDescription(request.getStyle());
            sb.append("【剧本风格】").append(styleDesc).append("\n");
        }

        // 篇幅
        if (StringUtils.hasText(request.getLength())) {
            String lengthDesc = getLengthDescription(request.getLength());
            sb.append("【篇幅长度】").append(lengthDesc).append("\n");
        }

        // 序幕：低谷回响
        if (StringUtils.hasText(request.getPlotIntro())) {
            sb.append("【序幕-低谷回响】").append(request.getPlotIntro()).append("\n");
        }

        // 转折：契机出现
        if (StringUtils.hasText(request.getPlotTurning())) {
            sb.append("【转折-契机出现】").append(request.getPlotTurning()).append("\n");
        }

        // 高潮：命运抉择
        if (StringUtils.hasText(request.getPlotClimax())) {
            sb.append("【高潮-命运抉择】").append(request.getPlotClimax()).append("\n");
        }

        // 结局：新的开始
        if (StringUtils.hasText(request.getPlotEnding())) {
            sb.append("【结局-新的开始】").append(request.getPlotEnding()).append("\n");
        }

        return sb.toString().trim();
    }

    /**
     * 获取风格描述
     *
     * @param style 风格代码
     * @return 风格描述
     */
    private String getStyleDescription(String style) {
        switch (style) {
            case "career":
                return "职场逆袭";
            case "love":
                return "情感圆满";
            case "fantasy":
                return "玄幻觉醒";
            default:
                return style;
        }
    }

    /**
     * 获取篇幅描述
     *
     * @param length 篇幅代码
     * @return 篇幅描述
     */
    private String getLengthDescription(String length) {
        switch (length) {
            case "medium":
                return "标准篇";
            case "long":
                return "长篇";
            default:
                return length;
        }
    }

    @Override
    public EpicScriptResponse updateScript(EpicScriptUpdateRequest request) {
        EpicScript script = this.getById(request.getId());
        if (script == null || script.getIsDeleted() == 1) {
            return null;
        }

        // 验证权限
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (!script.getUserId().equals(currentUserId)) {
            return null;
        }

        // 更新字段
        if (StringUtils.hasText(request.getTitle())) {
            script.setTitle(request.getTitle());
        }
        if (request.getTheme() != null) {
            script.setTheme(request.getTheme());
        }
        if (StringUtils.hasText(request.getStyle())) {
            script.setStyle(request.getStyle());
        }
        if (StringUtils.hasText(request.getLength())) {
            script.setLength(request.getLength());
        }
        if (request.getPlotIntro() != null) {
            script.setPlotIntro(request.getPlotIntro());
        }
        if (request.getPlotTurning() != null) {
            script.setPlotTurning(request.getPlotTurning());
        }
        if (request.getPlotClimax() != null) {
            script.setPlotClimax(request.getPlotClimax());
        }
        if (request.getPlotEnding() != null) {
            script.setPlotEnding(request.getPlotEnding());
        }
        if (request.getPlotJson() != null) {
            script.setPlotJson(request.getPlotJson());
        }
        if (request.getIsSelected() != null) {
            script.setIsSelected(request.getIsSelected() ? 1 : 0);
        }

        // 如果需要重新生成AI内容
        if (Boolean.TRUE.equals(request.getRegenerateContent())) {
            String aiGeneratedContent = regenerateScriptByAi(request, script, currentUserId);
            if (aiGeneratedContent != null) {
                Map<String, Object> plotJson = script.getPlotJson();
                if (plotJson == null) {
                    plotJson = new java.util.HashMap<>();
                }
                plotJson.put("fullContent", aiGeneratedContent);
                script.setPlotJson(plotJson);
                log.info("AI重新生成剧本内容成功，用户ID: {}, 剧本ID: {}", currentUserId, script.getId());
            }
        }

        this.updateById(script);
        return convertToResponse(script);
    }

    /**
     * 调用Coze AI重新生成爽文剧本内容
     *
     * @param request 剧本更新请求
     * @param script 原剧本实体
     * @param userId 用户ID
     * @return AI生成的剧本内容，失败时返回null
     */
    private String regenerateScriptByAi(EpicScriptUpdateRequest request, EpicScript script, String userId) {
        try {
            // 组装AI输入
            String input = assembleUpdateScriptInput(request, script);
            log.info("开始调用AI重新生成剧本，用户ID: {}, 剧本ID: {}", userId, script.getId());

            // 调用Coze工作流
            String result = aiChatService.callWorkflowByConfigKey(COZE_EPIC_SCRIPT_CONFIG_KEY, input, userId);

            log.info("AI重新生成剧本完成，用户ID: {}, 结果长度: {}", userId, result != null ? result.length() : 0);
            return result;

        } catch (Exception e) {
            log.error("AI重新生成剧本失败，用户ID: {}, 剧本ID: {}, 错误: {}", userId, script.getId(), e.getMessage(), e);
            return null;
        }
    }

    /**
     * 组装更新时的AI输入内容
     *
     * @param request 更新请求
     * @param script 原剧本实体
     * @return 格式化的输入字符串
     */
    private String assembleUpdateScriptInput(EpicScriptUpdateRequest request, EpicScript script) {
        StringBuilder sb = new StringBuilder();

        // 角色信息（优先使用请求中的，否则使用原有的）
        String characterInfo = StringUtils.hasText(request.getCharacterInfo())
            ? request.getCharacterInfo() : null;
        if (characterInfo != null) {
            sb.append("【角色信息】").append(characterInfo).append("\n");
        }

        // 过往经历
        String lifeEventsSummary = StringUtils.hasText(request.getLifeEventsSummary())
            ? request.getLifeEventsSummary() : null;
        if (lifeEventsSummary != null) {
            sb.append("【过往经历】").append(lifeEventsSummary).append("\n");
        }

        // 标题
        String title = StringUtils.hasText(request.getTitle()) ? request.getTitle() : script.getTitle();
        if (StringUtils.hasText(title)) {
            sb.append("【剧本标题】").append(title).append("\n");
        }

        // 主题/渴望
        String theme = request.getTheme() != null ? request.getTheme() : script.getTheme();
        if (StringUtils.hasText(theme)) {
            sb.append("【主题渴望】").append(theme).append("\n");
        }

        // 风格
        String style = StringUtils.hasText(request.getStyle()) ? request.getStyle() : script.getStyle();
        if (StringUtils.hasText(style)) {
            String styleDesc = getStyleDescription(style);
            sb.append("【剧本风格】").append(styleDesc).append("\n");
        }

        // 篇幅
        String length = StringUtils.hasText(request.getLength()) ? request.getLength() : script.getLength();
        if (StringUtils.hasText(length)) {
            String lengthDesc = getLengthDescription(length);
            sb.append("【篇幅长度】").append(lengthDesc).append("\n");
        }

        // 序幕
        String plotIntro = request.getPlotIntro() != null ? request.getPlotIntro() : script.getPlotIntro();
        if (StringUtils.hasText(plotIntro)) {
            sb.append("【序幕-低谷回响】").append(plotIntro).append("\n");
        }

        // 转折
        String plotTurning = request.getPlotTurning() != null ? request.getPlotTurning() : script.getPlotTurning();
        if (StringUtils.hasText(plotTurning)) {
            sb.append("【转折-契机出现】").append(plotTurning).append("\n");
        }

        // 高潮
        String plotClimax = request.getPlotClimax() != null ? request.getPlotClimax() : script.getPlotClimax();
        if (StringUtils.hasText(plotClimax)) {
            sb.append("【高潮-命运抉择】").append(plotClimax).append("\n");
        }

        // 结局
        String plotEnding = request.getPlotEnding() != null ? request.getPlotEnding() : script.getPlotEnding();
        if (StringUtils.hasText(plotEnding)) {
            sb.append("【结局-新的开始】").append(plotEnding).append("\n");
        }

        return sb.toString().trim();
    }

    @Override
    public EpicScriptResponse selectScript(String id) {
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (currentUserId == null) {
            return null;
        }

        // 先取消所有选中
        LambdaQueryWrapper<EpicScript> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EpicScript::getUserId, currentUserId)
                .eq(EpicScript::getIsSelected, 1)
                .eq(EpicScript::getIsDeleted, 0);
        List<EpicScript> selectedScripts = this.list(wrapper);
        for (EpicScript s : selectedScripts) {
            s.setIsSelected(0);
            this.updateById(s);
        }

        // 选中指定剧本
        EpicScript script = this.getById(id);
        if (script == null || script.getIsDeleted() == 1) {
            return null;
        }
        if (!script.getUserId().equals(currentUserId)) {
            return null;
        }

        script.setIsSelected(1);
        this.updateById(script);
        return convertToResponse(script);
    }

    @Override
    public boolean deleteScript(String id) {
        EpicScript script = this.getById(id);
        if (script == null) {
            return false;
        }

        // 验证权限
        String currentUserId = UserContextHolder.getCurrentUserId();
        if (!script.getUserId().equals(currentUserId)) {
            return false;
        }

        // 删除关联的路径
        lifePathService.deleteByScriptId(id);

        // 使用 MyBatis-Plus 的 removeById 方法，自动处理逻辑删除
        return this.removeById(id);
    }

    /**
     * 转换为响应对象
     */
    private EpicScriptResponse convertToResponse(EpicScript script) {
        EpicScriptResponse response = new EpicScriptResponse();
        BeanUtils.copyProperties(script, response);
        response.setId(script.getId());
        response.setIsSelected(script.getIsSelected() != null && script.getIsSelected() == 1);
        if (script.getCreateTime() != null) {
            response.setCreateTime(script.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (script.getUpdateTime() != null) {
            response.setUpdateTime(script.getUpdateTime().format(DATE_TIME_FORMATTER));
        }
        return response;
    }
}
