import type { SessionStore } from './store.js';
import { tokenize } from './indexer.js';

export interface HistorySearchResult {
  sessionId: string;
  messageId: number;
  role: 'user' | 'assistant';
  content: string;
  score: number;
  createdAt: number;
}

export interface HistorySearchConfig {
  limit: number;
  minScore: number;
}

export class SessionSearch {
  private readonly store: SessionStore;
  private readonly config: HistorySearchConfig;

  constructor(store: SessionStore, config: HistorySearchConfig) {
    this.store = store;
    this.config = config;
  }

  search(query: string, opts?: { limit?: number; sessionId?: string }): HistorySearchResult[] {
    const queryTokens = new Set(tokenize(query));
    if (queryTokens.size === 0) {
      return [];
    }

    const rows = opts?.sessionId
      ? this.store.getMessagesWithMetadata(opts.sessionId)
      : this.store.getAllMessagesWithMetadata();

    const now = Math.floor(Date.now() / 1000);
    const results: HistorySearchResult[] = [];

    for (const row of rows) {
      const keywords = row.metadata?.keywords ?? [];
      if (keywords.length === 0) {
        continue;
      }

      const overlapCount = keywords.filter(keyword => queryTokens.has(keyword)).length;
      if (overlapCount === 0) {
        continue;
      }

      const overlapScore = overlapCount / queryTokens.size;
      const ageSeconds = Math.max(0, now - row.createdAt);
      const recencyScore = Math.max(0, 1 - ageSeconds / (30 * 24 * 3600)) * 0.2;
      const totalScore = overlapScore + recencyScore;

      if (totalScore < this.config.minScore) {
        continue;
      }

      results.push({
        sessionId: row.sessionId,
        messageId: row.id,
        role: row.role,
        content: row.content,
        score: totalScore,
        createdAt: row.createdAt,
      });
    }

    results.sort((a, b) => b.score - a.score || b.createdAt - a.createdAt);
    return results.slice(0, opts?.limit ?? this.config.limit);
  }
}
