/**
 * Local 검색 서비스 구현
 * Phase 3.6: searchLocal 메서드 분리 - 파이프라인 단계별 메서드 분리
 */
import { logger } from '../../../../shared/utils/logger.js';
/**
 * Local 검색 서비스
 * searchLocal 메서드의 각 단계를 메서드로 분리
 */
export class LocalSearchService {
    db = null;
    cacheService;
    nHopSearchStrategy;
    queryFilterStrategy;
    fallbackStrategy;
    constructor(cacheService, nHopSearchStrategy, queryFilterStrategy, fallbackStrategy) {
        this.cacheService = cacheService;
        this.nHopSearchStrategy = nHopSearchStrategy;
        this.queryFilterStrategy = queryFilterStrategy;
        this.fallbackStrategy = fallbackStrategy;
    }
    /**
     * 데이터베이스 설정
     */
    setDatabase(db) {
        if (!db) {
            throw new Error('Database instance is required');
        }
        this.db = db;
    }
    /**
     * 앵커 정보 및 임베딩 조회
     */
    async getAnchorWithEmbedding(agentId, slot) {
        if (!this.db) {
            throw new Error('Database is not set. Call setDatabase() first.');
        }
        // 앵커 정보 조회
        const anchorInfo = this.db.prepare(`
      SELECT memory_id
      FROM anchor
      WHERE agent_id = ? AND slot = ?
    `).get(agentId, slot);
        if (!anchorInfo || !anchorInfo.memory_id) {
            return null;
        }
        // 앵커 임베딩 조회
        const anchorEmbedding = await this.cacheService.getAnchorEmbedding(anchorInfo.memory_id);
        if (!anchorEmbedding) {
            throw new Error(`Embedding not found for anchor memory_id: ${anchorInfo.memory_id}`);
        }
        return {
            memory_id: anchorInfo.memory_id,
            embedding: anchorEmbedding
        };
    }
    /**
     * N-hop 검색 수행
     */
    async performNHopSearch(anchorEmbedding, provider, anchorMemoryId, threshold, maxHops, limit, useRelations = true) {
        return this.nHopSearchStrategy.search(anchorEmbedding, provider, anchorMemoryId, threshold, maxHops, limit, useRelations);
    }
    /**
     * 쿼리 필터링 적용
     */
    async applyQueryFilter(query, results, provider) {
        if (!query || query.trim().length === 0) {
            return results;
        }
        return this.queryFilterStrategy.filter(query, results, provider);
    }
    /**
     * Fallback 처리
     */
    async handleFallback(query, localResults, minResults, options, startTime) {
        // Fallback 조건: query가 있고 localCount < minResults
        if (!query || query.trim().length === 0 || localResults.length >= minResults) {
            return {
                items: localResults,
                totalCount: localResults.length,
                fallbackUsed: false
            };
        }
        try {
            logger.info('Fallback to global search', {
                localCount: localResults.length,
                minResults
            });
            const limit = options?.limit ?? 10;
            const fallbackResult = await this.fallbackStrategy.fallback(query, { ...options, limit: limit - localResults.length }, startTime);
            // Local 결과와 Fallback 결과 병합 (중복 제거)
            const localMemoryIds = new Set(localResults.map(r => r.id));
            const fallbackItems = fallbackResult.items
                .filter((item) => !localMemoryIds.has(item.id))
                .map((item) => ({
                id: item.id,
                content: item.content,
                type: item.type,
                similarity: item.similarity ?? 0,
                hop_distance: item.hop_distance ?? 999,
                importance: item.importance ?? 0.5,
                created_at: item.created_at ?? new Date().toISOString(),
                tags: item.tags ?? undefined
            }));
            const finalResults = [...localResults, ...fallbackItems].slice(0, limit);
            logger.info('Fallback completed', {
                localCount: localResults.length,
                fallbackCount: fallbackItems.length,
                totalCount: finalResults.length
            });
            return {
                items: finalResults,
                totalCount: finalResults.length,
                fallbackUsed: true
            };
        }
        catch (error) {
            logger.error('Fallback failed', {
                error: error instanceof Error ? error.message : String(error)
            });
            return {
                items: localResults,
                totalCount: localResults.length,
                fallbackUsed: false
            };
        }
    }
}
//# sourceMappingURL=local-search-service.js.map