"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.QuestionGraphEngine = void 0;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const core_1 = require("@myycontext/core");
class QuestionGraphEngine {
    constructor(config) {
        this.graph = null;
        this.brainPath =
            config?.brainPath ||
                path.join(process.cwd(), ".mycontext", "context.json");
    }
    addQuestion(text, severity = "important", category = "architecture", source = "system", options, validation, context, dependsOn) {
        const graph = this.getOrCreateGraph();
        const id = `q-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
        const node = (0, core_1.createQuestionNode)(id, text, severity, category, source, options, validation, context);
        graph.nodes.set(id, node);
        if (dependsOn) {
            for (const depId of dependsOn) {
                const exists = graph.nodes.has(depId);
                if (exists) {
                    graph.edges.push({
                        source: id,
                        target: depId,
                        type: "depends_on",
                    });
                }
            }
        }
        if (!graph.rootIds.includes(id)) {
            const hasIncoming = graph.edges.some(e => e.target === id && e.type === "depends_on");
            if (!hasIncoming) {
                graph.rootIds.push(id);
            }
        }
        return node;
    }
    answerQuestion(id, answer, resolvedBy) {
        const graph = this.getOrCreateGraph();
        const node = graph.nodes.get(id);
        if (!node)
            return false;
        node.status = "answered";
        node.answer = answer;
        node.resolvedAt = new Date().toISOString();
        node.resolvedBy = resolvedBy;
        return true;
    }
    skipQuestion(id) {
        const graph = this.getOrCreateGraph();
        const node = graph.nodes.get(id);
        if (!node)
            return false;
        node.status = "skipped";
        return true;
    }
    invalidateQuestion(id) {
        const graph = this.getOrCreateGraph();
        const node = graph.nodes.get(id);
        if (!node)
            return false;
        node.status = "outdated";
        return true;
    }
    getGraph() {
        return this.getOrCreateGraph();
    }
    getBlockers() {
        return this.getOrCreateGraph().getBlockers();
    }
    getUnanswered() {
        return this.getOrCreateGraph().getUnanswered();
    }
    isCompilationBlocked() {
        return this.getOrCreateGraph().isCompilationBlocked();
    }
    countBySeverity() {
        return this.getOrCreateGraph().countBySeverity();
    }
    async load() {
        if (!(await fs.pathExists(this.brainPath)))
            return;
        const brain = await fs.readJson(this.brainPath);
        const questionsData = brain?.context?.questions;
        if (!questionsData) {
            this.graph = (0, core_1.createQuestionGraph)([], []);
            return;
        }
        const nodes = (questionsData.nodes || []).map((n) => ({
            ...n,
            type: "question",
        }));
        const edges = (questionsData.edges || []).map((e) => ({
            ...e,
            type: e.type,
        }));
        this.graph = (0, core_1.createQuestionGraph)(nodes, edges);
    }
    async save() {
        if (!(await fs.pathExists(this.brainPath)))
            return;
        const graph = this.getOrCreateGraph();
        const brain = await fs.readJson(this.brainPath);
        const questionsData = {
            nodes: Array.from(graph.nodes.values()).map((n) => ({
                id: n.id,
                text: n.text,
                context: n.context,
                severity: n.severity,
                status: n.status,
                answer: n.answer,
                category: n.category,
                options: n.options,
                validation: n.validation,
                source: n.source,
                resolvedAt: n.resolvedAt,
                resolvedBy: n.resolvedBy,
                metadata: n.metadata,
            })),
            edges: graph.edges,
            rootIds: graph.rootIds,
            lastHarvested: new Date().toISOString(),
        };
        brain.context = brain.context || {};
        brain.context.questions = questionsData;
        await fs.writeJson(this.brainPath, brain, { spaces: 2 });
    }
    async harvestFromPrompt(prompt) {
        const generated = [];
        const authKeywords = [
            "auth", "login", "signup", "register", "password",
            "oauth", "jwt", "session", "permission", "role",
        ];
        const deploymentKeywords = [
            "deploy", "host", "production", "domain", "ssl", "https",
            "docker", "ci", "cd", "environment",
        ];
        const dataKeywords = [
            "database", "model", "entity", "schema", "api", "graphql",
            "rest", "crud", "query",
        ];
        const uiKeywords = [
            "design", "theme", "responsive", "mobile", "dark", "light",
            "component", "layout", "style",
        ];
        const lower = prompt.toLowerCase();
        if (authKeywords.some(k => lower.includes(k))) {
            generated.push(this.addQuestionIfNew("What authentication provider should be used?", "blocking", "auth", "prompt", [
                { value: "clerk", label: "Clerk" },
                { value: "next-auth", label: "NextAuth.js" },
                { value: "auth0", label: "Auth0" },
                { value: "supabase", label: "Supabase Auth" },
                { value: "custom", label: "Custom implementation" },
            ]));
            generated.push(this.addQuestionIfNew("What roles are needed in the system?", "important", "permissions", "prompt"));
        }
        if (deploymentKeywords.some(k => lower.includes(k))) {
            generated.push(this.addQuestionIfNew("What is the deployment target?", "blocking", "deployment", "prompt", [
                { value: "vercel", label: "Vercel" },
                { value: "netlify", label: "Netlify" },
                { value: "docker", label: "Docker / self-hosted" },
                { value: "cloudflare", label: "Cloudflare Pages" },
            ]));
        }
        if (dataKeywords.some(k => lower.includes(k))) {
            generated.push(this.addQuestionIfNew("What database / data layer should be used?", "blocking", "data", "prompt", [
                { value: "instantdb", label: "InstantDB" },
                { value: "postgres", label: "PostgreSQL" },
                { value: "sqlite", label: "SQLite" },
                { value: "mongodb", label: "MongoDB" },
                { value: "supabase", label: "Supabase" },
            ]));
        }
        if (uiKeywords.some(k => lower.includes(k))) {
            generated.push(this.addQuestionIfNew("What is the target platform / responsive breakpoints?", "important", "ui", "prompt", [
                { value: "desktop-first", label: "Desktop-first" },
                { value: "mobile-first", label: "Mobile-first" },
                { value: "all", label: "All screen sizes" },
            ]));
        }
        return generated;
    }
    addQuestionIfNew(text, severity, category, source, options) {
        const graph = this.getOrCreateGraph();
        const existing = Array.from(graph.nodes.values()).find((n) => n.text === text && n.status === "unanswered");
        if (existing)
            return existing;
        return this.addQuestion(text, severity, category, source, options);
    }
    getOrCreateGraph() {
        if (this.graph)
            return this.graph;
        this.graph = (0, core_1.createQuestionGraph)([], []);
        return this.graph;
    }
}
exports.QuestionGraphEngine = QuestionGraphEngine;
//# sourceMappingURL=QuestionGraphEngine.js.map