import { effectiveOffset, MCP_DEFAULTS } from '../middleware.js';
import type { McpToolContext } from '../server.js';

export const name = 'semantic_search';

interface SemanticSearchArgs {
  query: string;
  mode?: string;
  limit?: number;
  offset?: number;
  min_score?: number;
  file_pattern?: string | string[];
}

export async function handler(args: SemanticSearchArgs, ctx: McpToolContext): Promise<unknown> {
  const mode = args.mode || 'hybrid';
  const searchOpts = {
    limit: Math.min(args.limit ?? MCP_DEFAULTS.semantic_search ?? 100, ctx.MCP_MAX_LIMIT),
    offset: effectiveOffset(args),
    minScore: args.min_score,
    filePattern: args.file_pattern,
  };

  if (mode === 'keyword') {
    const { ftsSearchData } = await import('../../domain/search/index.js');
    const result = ftsSearchData(args.query, ctx.dbPath, searchOpts);
    if (result === null) {
      return {
        content: [
          {
            type: 'text',
            text: 'No FTS5 index found. Run `codegraph embed` to build the keyword index.',
          },
        ],
        isError: true,
      };
    }
    return result;
  }

  if (mode === 'semantic') {
    const { searchData } = await import('../../domain/search/index.js');
    const result = await searchData(args.query, ctx.dbPath, searchOpts);
    if (result === null) {
      return {
        content: [
          {
            type: 'text',
            text: 'Semantic search unavailable. Run `codegraph embed` first.',
          },
        ],
        isError: true,
      };
    }
    return result;
  }

  // hybrid (default) — falls back to semantic if no FTS5
  const { hybridSearchData, searchData } = await import('../../domain/search/index.js');
  let result: unknown = await hybridSearchData(args.query, ctx.dbPath, searchOpts);
  if (result === null) {
    result = await searchData(args.query, ctx.dbPath, searchOpts);
    if (result === null) {
      return {
        content: [
          {
            type: 'text',
            text: 'Semantic search unavailable. Run `codegraph embed` first.',
          },
        ],
        isError: true,
      };
    }
  }
  return result;
}
