package cn.nianxx.thhotel.platform.message.service.impl;

import cn.nianxx.thhotel.platform.common.time.UtcTimeFormatter;
import cn.nianxx.thhotel.platform.hotel.service.HotelContextService;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageInboxSnapshot;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageSummaryResponse;
import cn.nianxx.thhotel.platform.message.common.request.SourceMessageQueryRequest;
import cn.nianxx.thhotel.platform.message.common.result.SourceMessagePageResult;
import cn.nianxx.thhotel.platform.message.repository.SourceMessageInboxRepository;
import cn.nianxx.thhotel.platform.message.service.SourceMessageQueryService;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Service;

/**
 * 来源消息安全查询服务。该服务只返回摘要字段，原文读取必须走独立权限接口。
 */
@Service
public class SourceMessageQueryServiceImpl implements SourceMessageQueryService {

    private static final int DEFAULT_PAGE_NUM = 1;
    private static final int DEFAULT_PAGE_SIZE = 20;
    private static final int MAX_PAGE_SIZE = 100;
    private static final int MAX_SAFE_KEYWORD_MATCHES = 500;

    private final SourceMessageInboxRepository inboxRepository;
    private final HotelContextService hotelContextService;

    /**
     * 注入 SourceMessage 持久化边界和酒店上下文服务，查询服务不直接依赖 Mapper。
     */
    public SourceMessageQueryServiceImpl(
            SourceMessageInboxRepository inboxRepository,
            HotelContextService hotelContextService) {
        this.inboxRepository = inboxRepository;
        this.hotelContextService = hotelContextService;
    }

    /**
     * 分页查询 SourceMessage Inbox 安全摘要，最大页大小由服务端控制。
     */
    @Override
    public SourceMessagePageResult<SourceMessageSummaryResponse> query(SourceMessageQueryRequest request) {
        SourceMessageQueryRequest normalizedRequest = normalizeRequest(request);
        int pageNum = normalizePageNum(normalizedRequest.pageNum());
        int pageSize = normalizePageSize(normalizedRequest.pageSize());
        SourceMessagePageResult<SourceMessageInboxSnapshot> page = inboxRepository.query(normalizedRequest, pageNum, pageSize);
        List<SourceMessageSummaryResponse> items = page.items().stream().map(this::toSummary).toList();
        return new SourceMessagePageResult<>(items, page.total(), pageNum, pageSize);
    }

    /**
     * 查询匹配来源消息安全摘要关键词的内部 SourceMessage ID，供业务查询做关联过滤。
     */
    @Override
    public List<Long> findIdsBySafeKeyword(String hotelId, String keyword) {
        return inboxRepository.findIdsBySafeKeyword(
                hotelContextService.resolveCurrentHotelId(hotelId),
                keyword,
                MAX_SAFE_KEYWORD_MATCHES);
    }

    /**
     * 读取单条 SourceMessage 安全摘要，不返回正文、HTML、媒体 URL 或原始 payload。
     */
    @Override
    public Optional<SourceMessageSummaryResponse> getSummary(Long inboxId) {
        return inboxRepository.findById(inboxId).map(this::toSummary);
    }

    /**
     * 批量读取 SourceMessage 安全摘要，用于业务列表预取主题等摘要字段，避免逐条查询。
     */
    @Override
    public List<SourceMessageSummaryResponse> getSummariesByIds(List<Long> inboxIds) {
        if (inboxIds == null || inboxIds.isEmpty()) {
            return List.of();
        }
        return inboxRepository.findByIds(inboxIds).stream()
                .map(this::toSummary)
                .toList();
    }

    /**
     * 批量统计邮件会话消息数，只访问 SourceMessage Inbox 索引表。
     */
    @Override
    public Map<String, Long> countByExternalConversationIds(String hotelId, List<String> externalConversationIds) {
        return inboxRepository.countByExternalConversationIds(
                hotelContextService.resolveCurrentHotelId(hotelId),
                externalConversationIds);
    }

    /**
     * 标准化查询条件。hotel_id 可选，缺省时由当前用户或单酒店系统上下文解析。
     */
    private SourceMessageQueryRequest normalizeRequest(SourceMessageQueryRequest request) {
        if (request == null) {
            return new SourceMessageQueryRequest(
                    hotelContextService.resolveCurrentHotelId(null),
                    null,
                    null,
                    null,
                    null,
                    null);
        }
        return new SourceMessageQueryRequest(
                hotelContextService.resolveCurrentHotelId(request.hotelId()),
                request.externalMessageId(),
                request.externalConversationId(),
                request.captureStatus(),
                request.pageNum(),
                request.pageSize());
    }

    /**
     * 规范化页码，缺失或非法页码统一回到第一页。
     */
    private int normalizePageNum(Integer pageNum) {
        if (pageNum == null || pageNum < 1) {
            return DEFAULT_PAGE_NUM;
        }
        return pageNum;
    }

    /**
     * 规范化页大小，防止调用方一次拉取过多 SourceMessage 摘要。
     */
    private int normalizePageSize(Integer pageSize) {
        if (pageSize == null || pageSize < 1) {
            return DEFAULT_PAGE_SIZE;
        }
        return Math.min(pageSize, MAX_PAGE_SIZE);
    }

    /**
     * 将持久化快照转换为 Controller 可返回的安全响应对象。
     */
    private SourceMessageSummaryResponse toSummary(SourceMessageInboxSnapshot snapshot) {
        return new SourceMessageSummaryResponse(
                snapshot.id().toString(),
                snapshot.hotelId(),
                snapshot.provider(),
                snapshot.channel(),
                snapshot.externalMessageId(),
                snapshot.externalConversationId(),
                snapshot.captureStatus(),
                snapshot.duplicatePayloadChanged(),
                UtcTimeFormatter.toUtcOffsetDateTime(snapshot.receivedAt()),
                UtcTimeFormatter.toUtcOffsetDateTime(snapshot.sourceSentAt()),
                snapshot.senderSummary(),
                snapshot.subject(),
                snapshot.safeSnippet()
        );
    }
}
