/**
 * Structured Extraction MCP Tools
 *
 * Tools for listing and retrieving structured extractions.
 *
 * CRITICAL: NEVER use console.log() - stdout is reserved for JSON-RPC protocol.
 * Use console.error() for all logging.
 *
 * @module tools/extraction-structured
 */
import { z } from 'zod';
import { formatResponse, handleError, fetchProvenanceChain, } from './shared.js';
import { successResult } from '../server/types.js';
import { MCPError } from '../server/errors.js';
import { validateInput } from '../utils/validation.js';
import { requireDatabase } from '../server/state.js';
const ExtractionListInput = z.object({
    document_id: z.string().optional().describe('Document ID to list extractions for'),
    label: z.string().optional().describe('Filter by extraction label'),
    // Search params (when query is provided, search mode is used)
    query: z.string().optional().describe('Search query to match within extraction JSON content'),
    document_filter: z.array(z.string()).optional().describe('Filter by document IDs (search mode)'),
    limit: z.number().min(1).max(100).default(50).describe('Maximum results'),
    include_provenance: z.boolean().default(false).describe('Include provenance chain'),
});
const ExtractionGetInput = z.object({
    extraction_id: z.string().min(1).describe('Extraction ID to retrieve'),
    include_provenance: z.boolean().default(false).describe('Include provenance chain'),
});
async function handleExtractionList(params) {
    try {
        const input = validateInput(ExtractionListInput, params);
        const { db } = requireDatabase();
        if (input.query) {
            // ── Search mode: query extraction JSON content ──
            const results = db.searchExtractions(input.query, {
                document_filter: input.document_filter,
                limit: input.limit,
            });
            const enrichedResults = results.map((ext) => {
                const doc = db.getDocument(ext.document_id);
                let parsedExtractionJson;
                try {
                    parsedExtractionJson = JSON.parse(ext.extraction_json);
                }
                catch (error) {
                    console.error(`[extraction-structured] Failed to parse extraction_json for extraction ${ext.id}: ${error instanceof Error ? error.message : String(error)}`);
                    parsedExtractionJson = ext.extraction_json;
                }
                let parsedSchemaJson;
                try {
                    parsedSchemaJson = JSON.parse(ext.schema_json);
                }
                catch (error) {
                    console.error(`[extraction-structured] Failed to parse schema_json for extraction ${ext.id}: ${error instanceof Error ? error.message : String(error)}`);
                    parsedSchemaJson = ext.schema_json;
                }
                const provenanceChain = input.include_provenance
                    ? fetchProvenanceChain(db, ext.provenance_id, '[extraction-search]')
                    : undefined;
                return {
                    id: ext.id,
                    document_id: ext.document_id,
                    document_file_path: doc?.file_path ?? null,
                    document_file_name: doc?.file_name ?? null,
                    schema_json: parsedSchemaJson,
                    extraction_json: parsedExtractionJson,
                    content_hash: ext.content_hash,
                    provenance_id: ext.provenance_id,
                    created_at: ext.created_at,
                    provenance_chain: provenanceChain,
                };
            });
            return formatResponse(successResult({
                mode: 'search',
                query: input.query,
                total: enrichedResults.length,
                results: enrichedResults,
                next_steps: [
                    { tool: 'ocr_extraction_get', description: 'View a specific matched extraction' },
                ],
            }));
        }
        else {
            // ── List mode: list extractions for a document ──
            if (!input.document_id) {
                throw new MCPError('VALIDATION_ERROR', 'Provide document_id for listing or query for searching', {});
            }
            const extractions = db.getExtractionsByDocument(input.document_id);
            return formatResponse(successResult({
                mode: 'list',
                document_id: input.document_id,
                total: extractions.length,
                extractions: extractions.map((ext) => {
                    const provenanceChain = input.include_provenance
                        ? fetchProvenanceChain(db, ext.provenance_id, '[extraction-list]')
                        : undefined;
                    let parsedExtractionJson;
                    try {
                        parsedExtractionJson = JSON.parse(ext.extraction_json);
                    }
                    catch (error) {
                        console.error(`[extraction-structured] Failed to parse extraction_json for extraction ${ext.id}: ${error instanceof Error ? error.message : String(error)}`);
                        parsedExtractionJson = ext.extraction_json;
                    }
                    let parsedSchemaJson;
                    try {
                        parsedSchemaJson = JSON.parse(ext.schema_json);
                    }
                    catch (error) {
                        console.error(`[extraction-structured] Failed to parse schema_json for extraction ${ext.id}: ${error instanceof Error ? error.message : String(error)}`);
                        parsedSchemaJson = ext.schema_json;
                    }
                    return {
                        id: ext.id,
                        schema_json: parsedSchemaJson,
                        extraction_json: parsedExtractionJson,
                        content_hash: ext.content_hash,
                        provenance_id: ext.provenance_id,
                        created_at: ext.created_at,
                        provenance_chain: provenanceChain,
                    };
                }),
                next_steps: [
                    { tool: 'ocr_extraction_get', description: 'View a specific extraction in detail' },
                ],
            }));
        }
    }
    catch (error) {
        return handleError(error);
    }
}
async function handleExtractionGet(params) {
    try {
        const input = validateInput(ExtractionGetInput, params);
        const { db } = requireDatabase();
        const extraction = db.getExtraction(input.extraction_id);
        if (!extraction) {
            throw new Error(`Extraction not found: ${input.extraction_id}`);
        }
        // Get document for context
        const doc = db.getDocument(extraction.document_id);
        // Check if an embedding exists for this extraction
        const embedding = db.getEmbeddingByExtractionId(extraction.id);
        const hasEmbedding = embedding !== null;
        // Parse the stored JSON string back to object
        let parsedExtractionJson;
        try {
            parsedExtractionJson = JSON.parse(extraction.extraction_json);
        }
        catch (error) {
            console.error(`[extraction-structured] Failed to parse extraction_json for extraction ${extraction.id}: ${error instanceof Error ? error.message : String(error)}`);
            parsedExtractionJson = extraction.extraction_json;
        }
        // Parse schema_json
        let parsedSchemaJson;
        try {
            parsedSchemaJson = JSON.parse(extraction.schema_json);
        }
        catch (error) {
            console.error(`[extraction-structured] Failed to parse schema_json for extraction ${extraction.id}: ${error instanceof Error ? error.message : String(error)}`);
            parsedSchemaJson = extraction.schema_json;
        }
        // Optionally fetch provenance chain
        const provenanceChain = input.include_provenance
            ? fetchProvenanceChain(db, extraction.provenance_id, '[extraction-get]')
            : undefined;
        return formatResponse(successResult({
            id: extraction.id,
            document_id: extraction.document_id,
            document_file_path: doc?.file_path ?? null,
            document_file_name: doc?.file_name ?? null,
            ocr_result_id: extraction.ocr_result_id,
            schema_json: parsedSchemaJson,
            extraction_json: parsedExtractionJson,
            content_hash: extraction.content_hash,
            provenance_id: extraction.provenance_id,
            created_at: extraction.created_at,
            has_embedding: hasEmbedding,
            embedding_id: embedding?.id ?? null,
            provenance_chain: provenanceChain,
            next_steps: [
                {
                    tool: 'ocr_extraction_list',
                    description: 'Search across all extractions (pass query param)',
                },
                { tool: 'ocr_document_get', description: 'View the source document' },
            ],
        }));
    }
    catch (error) {
        return handleError(error);
    }
}
export const structuredExtractionTools = {
    ocr_extraction_list: {
        description: '[STATUS] Use to list or search structured extractions. Filter by document_id, or search by query across all extractions.',
        inputSchema: ExtractionListInput.shape,
        handler: handleExtractionList,
    },
    ocr_extraction_get: {
        description: '[STATUS] Use to retrieve full results of a specific structured extraction by ID. Returns parsed extraction JSON, schema, embedding status, and optional provenance chain.',
        inputSchema: ExtractionGetInput.shape,
        handler: handleExtractionGet,
    },
};
//# sourceMappingURL=extraction-structured.js.map