export class MemoryGraph {
    entities = [];
    relations = [];
    nextId = 1;
    genId(prefix) {
        return `${prefix}-${this.nextId++}`;
    }
    now() {
        return new Date().toISOString();
    }
    getEntities() {
        return this.entities;
    }
    getRelations() {
        return this.relations;
    }
    getEntity(id) {
        return this.entities.find((e) => e.id === id) ?? null;
    }
    addEntity(name, type, source) {
        const entity = {
            id: this.genId("entity"),
            name,
            type,
            source,
            createdAt: this.now(),
            observations: [],
        };
        this.entities.push(entity);
        return entity;
    }
    addObservation(entityId, content) {
        const entity = this.getEntity(entityId);
        if (!entity)
            throw new Error(`Entity ${entityId} not found`);
        const obs = {
            id: this.genId("obs"),
            content,
            validFrom: this.now(),
            validTo: null,
        };
        entity.observations.push(obs);
        return obs;
    }
    expireObservation(obsId) {
        for (const entity of this.entities) {
            const obs = entity.observations.find((o) => o.id === obsId);
            if (obs) {
                obs.validTo = this.now();
                return;
            }
        }
    }
    addRelation(fromId, toId, type, source) {
        const rel = {
            id: this.genId("rel"),
            from: fromId,
            to: toId,
            type,
            source,
            validFrom: this.now(),
            validTo: null,
        };
        this.relations.push(rel);
        return rel;
    }
    expireRelation(relId) {
        const rel = this.relations.find((r) => r.id === relId);
        if (rel)
            rel.validTo = this.now();
    }
    findEntityByName(name) {
        const lower = name.toLowerCase();
        return this.entities.find((e) => e.name.toLowerCase() === lower) ?? null;
    }
    findEntitiesByType(type) {
        return this.entities.filter((e) => e.type === type);
    }
    getCurrentObservations(entityId) {
        const entity = this.getEntity(entityId);
        if (!entity)
            return [];
        return entity.observations.filter((o) => o.validTo === null);
    }
    getRelationsFrom(entityId) {
        return this.relations.filter((r) => r.from === entityId && r.validTo === null);
    }
    getRelationsTo(entityId) {
        return this.relations.filter((r) => r.to === entityId && r.validTo === null);
    }
    toCompactIndex() {
        const lines = [];
        for (const entity of this.entities) {
            const current = this.getCurrentObservations(entity.id);
            const obsStr = current.map((o) => o.content).join("; ");
            const relFrom = this.getRelationsFrom(entity.id);
            const relStr = relFrom
                .map((r) => {
                const target = this.getEntity(r.to);
                return `${r.type} → ${target?.name ?? r.to}`;
            })
                .join("; ");
            let line = `${entity.name} (${entity.type})`;
            if (obsStr)
                line += `: ${obsStr}`;
            if (relStr)
                line += ` [${relStr}]`;
            lines.push(line);
        }
        return lines.join("\n");
    }
    toJSON() {
        return {
            entities: this.entities,
            relations: this.relations,
            nextId: this.nextId,
        };
    }
    static fromJSON(data) {
        const graph = new MemoryGraph();
        graph.entities = data.entities;
        graph.relations = data.relations;
        graph.nextId = data.nextId;
        return graph;
    }
}
