"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssistantSessionLogger = void 0;
const path_1 = __importDefault(require("path"));
const config_1 = require("../config");
const files_1 = require("../utils/files");
function unique(values) {
    return Array.from(new Set(values.filter((item) => typeof item === "string" && item.length > 0)));
}
function toObject(value) {
    if (!value || typeof value !== "object" || Array.isArray(value)) {
        return null;
    }
    return value;
}
function toStringOrNull(value) {
    if (typeof value !== "string") {
        return null;
    }
    const trimmed = value.trim();
    return trimmed ? trimmed : null;
}
function extractFragments(assistantItem) {
    if (!assistantItem.debug || !Array.isArray(assistantItem.debug.fragments)) {
        return [];
    }
    return assistantItem.debug.fragments
        .map((item) => toObject(item))
        .filter((item) => item !== null);
}
function extractNormalizedQuestion(userText, assistantItem) {
    const normalized = toObject(assistantItem.debug?.normalized);
    if (normalized) {
        const fromUserMessageRaw = toStringOrNull(normalized.user_message_raw);
        if (fromUserMessageRaw)
            return fromUserMessageRaw;
        const fromUserQuestionRaw = toStringOrNull(normalized.user_question_raw);
        if (fromUserQuestionRaw)
            return fromUserQuestionRaw;
        const fromNormalizedQuestion = toStringOrNull(normalized.normalized_question);
        if (fromNormalizedQuestion)
            return fromNormalizedQuestion;
    }
    const fragments = extractFragments(assistantItem);
    if (fragments.length > 0) {
        const joined = fragments
            .map((fragment) => toStringOrNull(fragment.normalized_fragment_text) ?? toStringOrNull(fragment.raw_fragment_text))
            .filter((item) => Boolean(item))
            .join(" | ");
        if (joined) {
            return joined;
        }
    }
    return userText;
}
function buildRouteLookup(assistantItem) {
    const output = new Map();
    if (!assistantItem.debug || !Array.isArray(assistantItem.debug.routes)) {
        return output;
    }
    for (const route of assistantItem.debug.routes) {
        const routeObject = toObject(route);
        if (!routeObject)
            continue;
        const fragmentId = toStringOrNull(routeObject.fragment_id);
        if (!fragmentId)
            continue;
        output.set(fragmentId, routeObject);
    }
    return output;
}
function buildDecompositionLines(assistantItem) {
    const fragments = extractFragments(assistantItem);
    if (fragments.length === 0) {
        return ["Фрагменты декомпозиции не выделены."];
    }
    const routeLookup = buildRouteLookup(assistantItem);
    return fragments.map((fragment, index) => {
        const fragmentId = toStringOrNull(fragment.fragment_id) ?? `F${index + 1}`;
        const fragmentText = toStringOrNull(fragment.normalized_fragment_text) ??
            toStringOrNull(fragment.raw_fragment_text) ??
            "текст фрагмента отсутствует";
        const executionReadiness = toStringOrNull(fragment.execution_readiness);
        const routeStatus = toStringOrNull(fragment.route_status);
        const routeObject = routeLookup.get(fragmentId);
        const route = toStringOrNull(routeObject?.route);
        const noRouteReason = toStringOrNull(fragment.no_route_reason) ?? toStringOrNull(routeObject?.no_route_reason);
        const parts = [`${fragmentId}: ${fragmentText}`];
        if (executionReadiness)
            parts.push(`execution_readiness=${executionReadiness}`);
        if (routeStatus)
            parts.push(`route_status=${routeStatus}`);
        if (route)
            parts.push(`route=${route}`);
        if (noRouteReason)
            parts.push(`no_route_reason=${noRouteReason}`);
        return parts.join("; ");
    });
}
function toHumanBlock(input) {
    const lines = [];
    lines.push(`Вопрос: ${input.questionRaw}`);
    lines.push(`Понято как: ${input.questionUnderstood}`);
    lines.push("Декомпозиция:");
    lines.push(...input.decomposition.map((item) => `- ${item}`));
    lines.push(`Ответ: ${input.answer}`);
    return lines.join("\n");
}
function buildTurns(items) {
    const turns = [];
    const pendingUsers = [];
    for (const item of items) {
        if (item.role === "user") {
            pendingUsers.push(item);
            continue;
        }
        const pairedUser = pendingUsers.shift();
        if (!pairedUser) {
            continue;
        }
        const questionRaw = pairedUser.text;
        const questionUnderstood = extractNormalizedQuestion(questionRaw, item);
        const decomposition = buildDecompositionLines(item);
        const answer = item.text;
        turns.push({
            turn_id: `turn-${turns.length + 1}`,
            started_at: pairedUser.created_at ?? null,
            completed_at: item.created_at ?? null,
            human_block: toHumanBlock({
                questionRaw,
                questionUnderstood,
                decomposition,
                answer
            }),
            human_readable: {
                question_raw: questionRaw,
                question_understood: questionUnderstood,
                decomposition,
                answer,
                reply_type: item.reply_type
            },
            technical_json: {
                trace_id: item.trace_id,
                user_message: pairedUser,
                assistant_message: item,
                debug: item.debug
            }
        });
    }
    return turns;
}
class AssistantSessionLogger {
    rootDir;
    constructor(rootDir = config_1.ASSISTANT_SESSIONS_DIR) {
        this.rootDir = rootDir;
    }
    persistSession(session) {
        (0, files_1.ensureDir)(this.rootDir);
        const filePath = path_1.default.resolve(this.rootDir, `${session.session_id}.json`);
        const startedAt = session.items[0]?.created_at ?? session.updated_at;
        const userMessages = session.items.filter((item) => item.role === "user").length;
        const assistantMessages = session.items.filter((item) => item.role === "assistant").length;
        const assistantItems = session.items.filter((item) => item.role === "assistant");
        const lastAssistant = assistantItems.length > 0 ? assistantItems[assistantItems.length - 1] : null;
        const traceIds = unique(session.items.map((item) => item.trace_id));
        const replyTypes = Array.from(new Set(session.items
            .map((item) => item.reply_type)
            .filter((item) => typeof item === "string" && item.length > 0)));
        const turns = buildTurns(session.items);
        const record = {
            schema_version: "assistant_session_log_v1",
            session_id: session.session_id,
            started_at: startedAt,
            updated_at: session.updated_at,
            counters: {
                total_messages: session.items.length,
                user_messages: userMessages,
                assistant_messages: assistantMessages
            },
            trace_ids: traceIds,
            reply_types: replyTypes,
            investigation_state: session.investigation_state,
            turns,
            conversation: session.items,
            last_assistant: {
                message_id: lastAssistant?.message_id ?? null,
                reply_type: lastAssistant?.reply_type ?? null,
                trace_id: lastAssistant?.trace_id ?? null,
                created_at: lastAssistant?.created_at ?? null
            }
        };
        (0, files_1.writeJsonFile)(filePath, record);
    }
}
exports.AssistantSessionLogger = AssistantSessionLogger;
