package tech.easyflow.chatlog.service.impl;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tech.easyflow.chatlog.domain.dto.ChatHistoryPage;
import tech.easyflow.chatlog.domain.dto.ChatMessageRecord;
import tech.easyflow.chatlog.domain.dto.ChatSessionPage;
import tech.easyflow.chatlog.domain.dto.ChatSessionSummary;
import tech.easyflow.chatlog.domain.query.ChatPageQuery;
import tech.easyflow.chatlog.domain.query.ChatSessionFilterQuery;
import tech.easyflow.chatlog.repository.analyticaldb.ChatAnalyticalDBRepository;
import tech.easyflow.chatlog.service.ChatHistoryManageService;
import tech.easyflow.chatlog.service.ChatHistoryQueryService;
import tech.easyflow.chatlog.service.ChatRoundOperateService;
import tech.easyflow.chatlog.service.ChatSessionCommandService;
import tech.easyflow.chatlog.service.ChatSessionQueryService;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.math.BigInteger;

@Service
public class ChatHistoryManageServiceImpl implements ChatHistoryManageService {

    private static final String ADMIN_ASSISTANT_CODE = "AGENT";

    private final ChatSessionQueryService chatSessionQueryService;
    private final ChatSessionCommandService chatSessionCommandService;
    private final ChatHistoryQueryService chatHistoryQueryService;
    private final ChatRoundOperateService chatRoundOperateService;
    private final ChatAnalyticalDBRepository chatAnalyticalDBRepository;

    public ChatHistoryManageServiceImpl(ChatSessionQueryService chatSessionQueryService,
                                        ChatSessionCommandService chatSessionCommandService,
                                        ChatHistoryQueryService chatHistoryQueryService,
                                        ChatRoundOperateService chatRoundOperateService,
                                        ChatAnalyticalDBRepository chatAnalyticalDBRepository) {
        this.chatSessionQueryService = chatSessionQueryService;
        this.chatSessionCommandService = chatSessionCommandService;
        this.chatHistoryQueryService = chatHistoryQueryService;
        this.chatRoundOperateService = chatRoundOperateService;
        this.chatAnalyticalDBRepository = chatAnalyticalDBRepository;
    }

    @Override
    public ChatSessionPage queryUserSessions(BigInteger userId, BigInteger assistantId, ChatPageQuery query) {
        return chatSessionQueryService.pageSessions(userId, assistantId, query);
    }

    @Override
    public ChatSessionPage queryAdminSessions(ChatSessionFilterQuery query) {
        ChatSessionFilterQuery effectiveQuery = query == null ? new ChatSessionFilterQuery() : query;
        // 管理端聊天历史已经切换为 Agent 专属入口，类型由服务端固定，避免客户端绕过。
        effectiveQuery.setAssistantCode(ADMIN_ASSISTANT_CODE);
        return chatAnalyticalDBRepository.pageSessions(effectiveQuery);
    }

    @Override
    public ChatSessionSummary getUserSession(BigInteger userId, BigInteger sessionId) {
        ChatSessionSummary summary = chatSessionQueryService.getSessionSummary(sessionId);
        if (summary == null || summary.getIsDeleted() != null && summary.getIsDeleted() == 1) {
            throw new BusinessException("会话不存在");
        }
        if (!summary.getUserId().equals(userId)) {
            throw new BusinessException("无权访问该会话");
        }
        return summary;
    }

    @Override
    public ChatSessionSummary getAdminSession(BigInteger sessionId) {
        ChatSessionSummary summary = chatAnalyticalDBRepository.getSession(sessionId);
        if (summary == null
                || Integer.valueOf(1).equals(summary.getIsDeleted())
                || !ADMIN_ASSISTANT_CODE.equals(summary.getAssistantCode())) {
            throw new BusinessException("Agent 会话不存在");
        }
        return summary;
    }

    @Override
    public ChatHistoryPage queryUserMessages(BigInteger userId, BigInteger sessionId, ChatPageQuery query) {
        ChatSessionSummary summary = getUserSession(userId, sessionId);
        ChatHistoryPage firstPage = restoreRecentMessages(summary, query);
        if (firstPage != null) {
            return firstPage;
        }
        return chatHistoryQueryService.queryHistoryMessages(sessionId, query);
    }

    @Override
    public ChatHistoryPage queryAdminMessages(BigInteger sessionId, ChatPageQuery query) {
        ChatSessionSummary summary = getAdminSession(sessionId);
        ChatHistoryPage firstPage = restoreRecentMessages(summary, query);
        if (firstPage != null) {
            return firstPage;
        }
        return chatHistoryQueryService.queryHistoryMessages(sessionId, query);
    }

    @Override
    public void renameUserSession(BigInteger userId, BigInteger sessionId, String title, BigInteger operatorId) {
        if (!StringUtils.hasText(title)) {
            throw new BusinessException("标题不能为空");
        }
        getUserSession(userId, sessionId);
        chatSessionCommandService.renameSession(sessionId, userId, title.trim(), operatorId);
    }

    @Override
    public void deleteUserSession(BigInteger userId, BigInteger sessionId, BigInteger operatorId) {
        getUserSession(userId, sessionId);
        chatSessionCommandService.deleteSession(sessionId, userId, operatorId);
    }

    @Override
    public java.util.List<ChatMessageRecord> listUserRoundVariants(BigInteger userId, BigInteger sessionId, BigInteger roundId) {
        getUserSession(userId, sessionId);
        return chatRoundOperateService.listVariants(sessionId, roundId);
    }

    @Override
    public ChatMessageRecord selectUserRoundVariant(BigInteger userId, BigInteger sessionId, BigInteger roundId, Integer variantIndex, BigInteger operatorId) {
        getUserSession(userId, sessionId);
        return chatRoundOperateService.selectVariant(sessionId, roundId, variantIndex, operatorId);
    }

    @Override
    public java.util.List<ChatMessageRecord> listAdminRoundVariants(BigInteger sessionId, BigInteger roundId) {
        getAdminSession(sessionId);
        return chatRoundOperateService.listVariants(sessionId, roundId);
    }

    @Override
    public ChatMessageRecord selectAdminRoundVariant(BigInteger sessionId, BigInteger roundId, Integer variantIndex, BigInteger operatorId) {
        getAdminSession(sessionId);
        return chatRoundOperateService.selectVariant(sessionId, roundId, variantIndex, operatorId);
    }

    private ChatHistoryPage restoreRecentMessages(ChatSessionSummary summary, ChatPageQuery query) {
        if (summary == null || query == null || query.getPageNumber() != 1) {
            return null;
        }
        java.util.List<ChatMessageRecord> records = chatSessionQueryService.getRecentTail(
                summary.getId(),
                Math.toIntExact(query.getPageSize())
        );
        if (records == null || records.isEmpty()) {
            return null;
        }
        ChatHistoryPage page = new ChatHistoryPage();
        page.setPageNumber(query.getPageNumber());
        page.setPageSize(query.getPageSize());
        page.setRecords(records);
        long total = summary.getMessageCount() == null ? 0L : summary.getMessageCount();
        page.setTotal(Math.max(total, records.size()));
        return page;
    }
}
