package com.jeesharp.business.modules.ai.application;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.jeesharp.business.modules.ai.dto.AiChatFeedbackDTO;
import com.jeesharp.business.modules.ai.dto.AiChatMessageDTO;
import com.jeesharp.business.modules.ai.dto.AiChatSessionCreateDTO;
import com.jeesharp.business.modules.ai.entity.AiChatFeedback;
import com.jeesharp.business.modules.ai.entity.AiChatMessage;
import com.jeesharp.business.modules.ai.entity.AiChatSession;
import com.jeesharp.business.modules.ai.entity.AiFaq;
import com.jeesharp.business.modules.ai.service.AiChatFeedbackService;
import com.jeesharp.business.modules.ai.service.AiChatMessageService;
import com.jeesharp.business.modules.ai.service.AiChatSessionService;
import com.jeesharp.business.modules.ai.service.AiFaqService;
import com.jeesharp.business.modules.common.constants.PlatformTenantConstants;
import com.jeesharp.business.modules.ai.vo.AiChatAnswerVO;
import com.jeesharp.business.modules.ai.vo.AiChatHistoryVO;
import com.jeesharp.business.modules.ai.vo.AiChatMessageListVO;
import com.jeesharp.business.modules.ai.vo.AiChatMessageQueryVO;
import com.jeesharp.business.modules.ai.vo.AiChatSessionCreateVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
@Transactional(readOnly = true)
public class AiChatMobileApplicationService {

    private static final String DEFAULT_MEMBER_ID = "-";
    private static final String DEFAULT_SESSION_STATUS = "active";
    private static final String ROLE_USER = "user";
    private static final String ROLE_ASSISTANT = "assistant";
    private static final String MESSAGE_TYPE_TEXT = "text";
    private static final String MESSAGE_TYPE_FAQ = "faq";
    private static final String MESSAGE_STATUS_SUCCESS = "success";
    private static final String DEFAULT_WELCOME = "你好，我是牧童小悠，24小时在线陪你游杏花村。你可以直接问我门票、路线、停车、文创特产等问题。";
    private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final AiChatSessionService aiChatSessionService;
    private final AiChatMessageService aiChatMessageService;
    private final AiChatFeedbackService aiChatFeedbackService;
    private final AiFaqService aiFaqService;

    public AiChatMobileApplicationService(AiChatSessionService aiChatSessionService,
                                          AiChatMessageService aiChatMessageService,
                                          AiChatFeedbackService aiChatFeedbackService,
                                          AiFaqService aiFaqService) {
        this.aiChatSessionService = aiChatSessionService;
        this.aiChatMessageService = aiChatMessageService;
        this.aiChatFeedbackService = aiChatFeedbackService;
        this.aiFaqService = aiFaqService;
    }

    @Transactional(readOnly = false)
    public AiChatSessionCreateVO createSession(AiChatSessionCreateDTO dto) {
        LocalDateTime now = LocalDateTime.now();
        AiChatSession session = new AiChatSession();
        session.setId(IdUtil.getSnowflakeNextIdStr());
        session.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
        session.setSessionCode("AI" + session.getId());
        session.setSessionTitle(StrUtil.blankToDefault(dto.getFirstQuestion(), "新会话"));
        session.setSessionStatus(DEFAULT_SESSION_STATUS);
        session.setLastMessageTime(now);
        session.setLastMessagePreview(StrUtil.blankToDefault(dto.getFirstQuestion(), "欢迎使用 AI 客服"));
        session.setExtJson(buildSessionExt(dto));
        session.setTenantCode(PlatformTenantConstants.PLATFORM_TENANT_CODE);
        session.setTenantId(PlatformTenantConstants.PLATFORM_TENANT_ID);
        aiChatSessionService.createSession(session);

        AiChatMessage welcome = new AiChatMessage();
        welcome.setId(IdUtil.getSnowflakeNextIdStr());
        welcome.setSessionId(session.getId());
        welcome.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
        welcome.setMessageRole(ROLE_ASSISTANT);
        welcome.setMessageType(MESSAGE_TYPE_TEXT);
        welcome.setMessageContent(DEFAULT_WELCOME);
        welcome.setMessageStatus(MESSAGE_STATUS_SUCCESS);
        welcome.setTenantCode(PlatformTenantConstants.PLATFORM_TENANT_CODE);
        welcome.setTenantId(PlatformTenantConstants.PLATFORM_TENANT_ID);
        aiChatMessageService.createMessage(welcome);

        if (StrUtil.isNotBlank(dto.getFirstQuestion())) {
            AiChatMessage first = new AiChatMessage();
            first.setId(IdUtil.getSnowflakeNextIdStr());
            first.setSessionId(session.getId());
            first.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
            first.setMessageRole(ROLE_USER);
            first.setMessageType(MESSAGE_TYPE_TEXT);
            first.setMessageContent(dto.getFirstQuestion());
            first.setMessageStatus(MESSAGE_STATUS_SUCCESS);
            aiChatMessageService.createMessage(first);
        }

        AiChatSessionCreateVO vo = new AiChatSessionCreateVO();
        vo.setSessionId(session.getId());
        vo.setWelcomeMessage(DEFAULT_WELCOME);
        vo.setCreatedAt(now.format(DT_FMT));
        return vo;
    }

    @Transactional(readOnly = false)
    public AiChatAnswerVO sendMessage(AiChatMessageDTO dto) {
        LocalDateTime now = LocalDateTime.now();

        AiChatMessage userMsg = new AiChatMessage();
        userMsg.setId(IdUtil.getSnowflakeNextIdStr());
        userMsg.setSessionId(dto.getSessionId());
        userMsg.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
        userMsg.setMessageRole(ROLE_USER);
        userMsg.setMessageType(MESSAGE_TYPE_TEXT);
        userMsg.setMessageContent(dto.getMessage());
        userMsg.setMessageStatus(MESSAGE_STATUS_SUCCESS);
        userMsg.setExtJson(buildMessageExt(dto));
        userMsg.closeTenantCodeAutoSet();
        userMsg.setTenantCode(PlatformTenantConstants.PLATFORM_TENANT_CODE);
        userMsg.setTenantId(PlatformTenantConstants.PLATFORM_TENANT_ID);
        aiChatMessageService.createMessage(userMsg);

        AiFaq matchedFaq = aiFaqService.matchFaq(dto.getMessage());
        String answer = matchedFaq == null
                ? "已收到您的问题，我们会根据 FAQ 与当前场景给出建议。"
                : matchedFaq.getAnswer();

        AiChatMessage assistantMsg = new AiChatMessage();
        assistantMsg.setId(IdUtil.getSnowflakeNextIdStr());
        assistantMsg.setSessionId(dto.getSessionId());
        assistantMsg.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
        assistantMsg.setMessageRole(ROLE_ASSISTANT);
        assistantMsg.setMessageType(MESSAGE_TYPE_TEXT);
        assistantMsg.setMessageContent(answer);
        assistantMsg.setMessageStatus(MESSAGE_STATUS_SUCCESS);
        assistantMsg.setExtJson(buildAnswerExt(dto, matchedFaq));
        aiChatMessageService.createMessage(assistantMsg);

        AiChatSession session = aiChatSessionService.get(dto.getSessionId());
        if (session != null) {
            session.setLastMessageTime(now);
            session.setLastMessagePreview(dto.getMessage());
            if (StrUtil.isBlank(session.getSessionTitle())) {
                session.setSessionTitle(StrUtil.sub(dto.getMessage(), 0, 20));
            }
            aiChatSessionService.updateSession(session);
        }

        AiChatAnswerVO vo = new AiChatAnswerVO();
        vo.setMessageId(assistantMsg.getId());
        vo.setAnswer(answer);
        vo.setAnswerType(matchedFaq == null ? MESSAGE_TYPE_TEXT : MESSAGE_TYPE_FAQ);
        if (matchedFaq != null) {
            vo.getReferences().add("faq:" + matchedFaq.getId());
            vo.getReferences().add("faq_category:" + StrUtil.nullToEmpty(matchedFaq.getCategoryId()));
        }
        return vo;
    }

    public AiChatHistoryVO getHistory(String sessionId) {
        AiChatSession session = aiChatSessionService.get(sessionId);
        AiChatMessageQueryVO query = new AiChatMessageQueryVO();
        query.setSessionId(sessionId);
        List<AiChatMessageListVO> messages = com.jeesharp.business.modules.ai.convert.AiChatMessageConvert.INSTANCE
                .toListVO(aiChatMessageService.findList(query));

        AiChatHistoryVO vo = new AiChatHistoryVO();
        vo.setSessionId(sessionId);
        if (session != null) {
            vo.setSessionTitle(session.getSessionTitle());
            vo.setSessionStatus(session.getSessionStatus());
            vo.setUpdatedAt(session.getUpdateDate() == null ? null : session.getUpdateDate().format(DT_FMT));
        }
        messages.sort((a, b) -> {
            if (a.getCreateDate() == null || b.getCreateDate() == null) {
                return 0;
            }
            return a.getCreateDate().compareTo(b.getCreateDate());
        });
        vo.setMessages(messages);
        return vo;
    }

    @Transactional(readOnly = false)
    public void feedback(AiChatFeedbackDTO dto) {
        AiChatFeedback feedback = new AiChatFeedback();
        feedback.setId(IdUtil.getSnowflakeNextIdStr());
        feedback.setSessionId(dto.getSessionId());
        feedback.setMessageId(dto.getMessageId());
        feedback.setMemberId(StrUtil.blankToDefault(dto.getMemberId(), DEFAULT_MEMBER_ID));
        feedback.setFeedbackType(Boolean.TRUE.equals(dto.getHelpful()) ? "helpful" : "unhelpful");
        feedback.setFeedbackNote(StrUtil.trimToNull(dto.getRemark()));
        aiChatFeedbackService.createFeedback(feedback);
    }

    private String buildSessionExt(AiChatSessionCreateDTO dto) {
        JSONObject ext = new JSONObject();
        ext.set("scene", dto.getScene());
        ext.set("bizId", dto.getBizId());
        return ext.toString();
    }

    private String buildMessageExt(AiChatMessageDTO dto) {
        JSONObject ext = new JSONObject();
        ext.set("contextBizType", dto.getContextBizType());
        ext.set("contextBizId", dto.getContextBizId());
        return ext.toString();
    }

    private String buildAnswerExt(AiChatMessageDTO dto, AiFaq matchedFaq) {
        JSONObject ext = new JSONObject();
        ext.set("contextBizType", dto.getContextBizType());
        ext.set("contextBizId", dto.getContextBizId());
        if (matchedFaq != null) {
            ext.set("faqId", matchedFaq.getId());
            ext.set("faqCategoryId", matchedFaq.getCategoryId());
        }
        return ext.toString();
    }
}
