import { normalizeDoc, normalizeDocs } from './normalizer.js';
export class BaseRepository {
    schema;
    dialect;
    constructor(schema, dialect) {
        this.schema = schema;
        this.dialect = dialect;
    }
    async findAll(filter = {}, options) {
        const docs = await this.dialect.find(this.schema, filter, options);
        return normalizeDocs(docs);
    }
    async findOne(filter, options) {
        const doc = await this.dialect.findOne(this.schema, filter, options);
        return doc ? normalizeDoc(doc) : null;
    }
    async findById(id, options) {
        const doc = await this.dialect.findById(this.schema, id, options);
        return doc ? normalizeDoc(doc) : null;
    }
    async findByIdWithRelations(id, relations, options) {
        if (!relations || relations.length === 0) {
            return this.findById(id, options);
        }
        const doc = await this.dialect.findByIdWithRelations(this.schema, id, relations, options);
        return doc ? normalizeDoc(doc) : null;
    }
    async create(data) {
        const doc = await this.dialect.create(this.schema, data);
        return normalizeDoc(doc);
    }
    async update(id, data) {
        const doc = await this.dialect.update(this.schema, id, data);
        return doc ? normalizeDoc(doc) : null;
    }
    async updateMany(filter, data) {
        return this.dialect.updateMany(this.schema, filter, data);
    }
    async delete(id) {
        return this.dialect.delete(this.schema, id);
    }
    async deleteMany(filter) {
        return this.dialect.deleteMany(this.schema, filter);
    }
    async count(filter = {}) {
        return this.dialect.count(this.schema, filter);
    }
    async search(query, options) {
        // Default: search all string fields — subclasses override with specific fields
        const fields = Object.entries(this.schema.fields)
            .filter(([, f]) => f.type === 'string')
            .map(([name]) => name);
        const docs = await this.dialect.search(this.schema, query, fields, options);
        return normalizeDocs(docs);
    }
    async distinct(field, filter = {}) {
        return this.dialect.distinct(this.schema, field, filter);
    }
    async aggregate(stages) {
        return this.dialect.aggregate(this.schema, stages);
    }
    async upsert(filter, data) {
        const doc = await this.dialect.upsert(this.schema, filter, data);
        return normalizeDoc(doc);
    }
    async increment(id, field, amount) {
        const doc = await this.dialect.increment(this.schema, id, field, amount);
        return doc ? normalizeDoc(doc) : null;
    }
    async addToSet(id, field, value) {
        const doc = await this.dialect.addToSet(this.schema, id, field, value);
        return doc ? normalizeDoc(doc) : null;
    }
    async pull(id, field, value) {
        const doc = await this.dialect.pull(this.schema, id, field, value);
        return doc ? normalizeDoc(doc) : null;
    }
    async findWithRelations(filter, relations, options) {
        const docs = await this.dialect.findWithRelations(this.schema, filter, relations, options);
        return normalizeDocs(docs);
    }
}
