/**
 * Base Context Provider
 *
 * Abstract base class for context providers.
 */

import type { KuzuConnection } from '../../graph/connection.js';
import type { ContextItem, ContextProviderSpec } from '../types.js';

/**
 * Abstract base class for context providers
 *
 * Context providers extract relevant code entities from different sources:
 * - ExploredAreasProvider: Entities discovered during agent exploration
 * - TouchedAreasProvider: AST neighbors of modified files
 */
export abstract class ContextProvider {
  protected conn?: KuzuConnection;
  protected config: Record<string, unknown>;

  constructor(conn?: KuzuConnection, config?: Record<string, unknown>) {
    this.conn = conn;
    this.config = config ?? {};
  }

  /**
   * Provider metadata
   */
  abstract get spec(): ContextProviderSpec;

  /**
   * Extract context items from input data
   */
  abstract extractContext(input: unknown): Promise<ContextItem[]>;

  /**
   * Format context items as markdown for system prompt
   */
  formatForPrompt(items: ContextItem[]): string {
    if (items.length === 0) {
      return '';
    }

    const lines: string[] = [
      '## Session Context',
      '',
      'The following code entities are relevant to recent work:',
      '',
    ];

    for (const item of items) {
      // Score indicator: *** (high), ** (medium), * (low)
      const indicator = item.score > 0.8 ? '***' : item.score > 0.5 ? '**' : '*';

      lines.push(`### ${indicator}${item.entityType}: ${item.qualifiedName}${indicator}`);

      if (item.filePath) {
        lines.push(`- File: \`${item.filePath}\``);
      }

      if (item.description) {
        const desc = item.description.length > 200
          ? item.description.slice(0, 200) + '...'
          : item.description;
        lines.push(`- Description: ${desc}`);
      }

      if (item.neighbors && item.neighbors.length > 0) {
        const neighborList = item.neighbors.slice(0, 5).join(', ');
        lines.push(`- Related: ${neighborList}`);
      }

      lines.push('');
    }

    return lines.join('\n');
  }
}

/**
 * Provider constructor type
 */
export type ProviderConstructor = new (
  conn?: KuzuConnection,
  config?: Record<string, unknown>
) => ContextProvider;
