export class SynapseRepository {
    db;
    stmts;
    constructor(db) {
        this.db = db;
        this.stmts = {
            create: db.prepare(`
        INSERT INTO synapses (source_type, source_id, target_type, target_id, synapse_type, weight, metadata)
        VALUES (@source_type, @source_id, @target_type, @target_id, @synapse_type, @weight, @metadata)
      `),
            getById: db.prepare('SELECT * FROM synapses WHERE id = ?'),
            delete: db.prepare('DELETE FROM synapses WHERE id = ?'),
            getOutgoing: db.prepare('SELECT * FROM synapses WHERE source_type = ? AND source_id = ? ORDER BY weight DESC'),
            getIncoming: db.prepare('SELECT * FROM synapses WHERE target_type = ? AND target_id = ? ORDER BY weight DESC'),
            findConnected: db.prepare(`
        SELECT * FROM synapses
        WHERE (source_type = ? AND source_id = ?) OR (target_type = ? AND target_id = ?)
        ORDER BY weight DESC
      `),
            findBySourceTarget: db.prepare(`
        SELECT * FROM synapses
        WHERE source_type = ? AND source_id = ? AND target_type = ? AND target_id = ? AND synapse_type = ?
      `),
            findInactiveSince: db.prepare(`
        SELECT * FROM synapses WHERE last_activated_at < ?
      `),
            countNodes: db.prepare(`
        SELECT COUNT(*) as count FROM (
          SELECT source_type, source_id FROM synapses
          UNION
          SELECT target_type, target_id FROM synapses
        )
      `),
            avgWeight: db.prepare('SELECT AVG(weight) as avg_weight FROM synapses'),
            countByType: db.prepare('SELECT synapse_type, COUNT(*) as count FROM synapses GROUP BY synapse_type'),
            totalCount: db.prepare('SELECT COUNT(*) as count FROM synapses'),
            topByWeight: db.prepare('SELECT * FROM synapses ORDER BY weight DESC LIMIT ?'),
            topDiverse: db.prepare(`
        SELECT * FROM (
          SELECT *, ROW_NUMBER() OVER (PARTITION BY synapse_type ORDER BY weight DESC) as rn
          FROM synapses
        ) WHERE rn <= ? ORDER BY weight DESC
      `),
        };
    }
    create(data) {
        const result = this.stmts.create.run({
            source_type: data.source_type,
            source_id: data.source_id,
            target_type: data.target_type,
            target_id: data.target_id,
            synapse_type: data.synapse_type,
            weight: data.weight,
            metadata: data.metadata ?? null,
        });
        return result.lastInsertRowid;
    }
    getById(id) {
        return this.stmts.getById.get(id);
    }
    update(id, data) {
        const fields = Object.keys(data).filter((key) => data[key] !== undefined);
        if (fields.length === 0)
            return false;
        const setClauses = fields.map((field) => `${field} = @${field}`).join(', ');
        const stmt = this.db.prepare(`UPDATE synapses SET ${setClauses}, updated_at = datetime('now') WHERE id = @id`);
        const result = stmt.run({ ...data, id });
        return result.changes > 0;
    }
    delete(id) {
        const result = this.stmts.delete.run(id);
        return result.changes > 0;
    }
    getOutgoing(sourceType, sourceId) {
        return this.stmts.getOutgoing.all(sourceType, sourceId);
    }
    getIncoming(targetType, targetId) {
        return this.stmts.getIncoming.all(targetType, targetId);
    }
    findBySourceTarget(sourceType, sourceId, targetType, targetId, synapseType) {
        return this.stmts.findBySourceTarget.get(sourceType, sourceId, targetType, targetId, synapseType);
    }
    findByWeight(minWeight, maxWeight) {
        if (maxWeight !== undefined) {
            const stmt = this.db.prepare('SELECT * FROM synapses WHERE weight >= ? AND weight <= ? ORDER BY weight DESC');
            return stmt.all(minWeight, maxWeight);
        }
        const stmt = this.db.prepare('SELECT * FROM synapses WHERE weight >= ? ORDER BY weight DESC');
        return stmt.all(minWeight);
    }
    findConnected(nodeType, nodeId) {
        return this.stmts.findConnected.all(nodeType, nodeId, nodeType, nodeId);
    }
    findInactiveSince(cutoff) {
        return this.stmts.findInactiveSince.all(cutoff);
    }
    topByWeight(limit) {
        return this.stmts.topByWeight.all(limit);
    }
    topDiverse(perType) {
        return this.stmts.topDiverse.all(perType);
    }
    countNodes() {
        const row = this.stmts.countNodes.get();
        return row.count;
    }
    totalCount() {
        const row = this.stmts.totalCount.get();
        return row.count;
    }
    avgWeight() {
        const row = this.stmts.avgWeight.get();
        return row.avg_weight ?? 0;
    }
    countByType() {
        const rows = this.stmts.countByType.all();
        const result = {};
        for (const row of rows) {
            result[row.synapse_type] = row.count;
        }
        return result;
    }
}
//# sourceMappingURL=synapse.repository.js.map