/**
 * Soft Delete Plugin for Drizzle ORM
 * Provides Sequelize-style paranoid mode functionality
 *
 * Features:
 * - Automatic deletedAt field addition
 * - Query filtering to exclude soft-deleted records
 * - Restore functionality
 * - Force delete option
 */
import { timestamp } from 'drizzle-orm/pg-core';
import { and, isNull, isNotNull } from 'drizzle-orm';
/**
 * Add soft delete capability to a table schema
 * Usage:
 *   const users = softDeleteTable('users', {
 *     id: uuid('id').primaryKey(),
 *     name: varchar('name', { length: 255 })
 *   });
 */
export function withSoftDelete(tableName, columns, options = {}) {
    const deletedAtColumn = options.deletedAtColumn || 'deletedAt';
    return {
        ...columns,
        [deletedAtColumn]: timestamp(deletedAtColumn),
    };
}
/**
 * Soft Delete Query Helper
 * Provides methods to work with soft-deleted records
 */
export class SoftDeleteHelper {
    deletedAtColumn;
    constructor(deletedAtColumn = 'deletedAt') {
        this.deletedAtColumn = deletedAtColumn;
    }
    /**
     * Get filter to exclude soft-deleted records
     * Usage: where(table, softDelete.excludeDeleted(table))
     */
    excludeDeleted(table) {
        return isNull(table[this.deletedAtColumn]);
    }
    /**
     * Get filter to include only soft-deleted records
     * Usage: where(table, softDelete.onlyDeleted(table))
     */
    onlyDeleted(table) {
        return isNotNull(table[this.deletedAtColumn]);
    }
    /**
     * Add soft-delete filter to existing where clause
     * Usage: where(table, and(customFilter, softDelete.withSoftDelete(table)))
     */
    withSoftDelete(table, includeDeleted = false) {
        if (includeDeleted) {
            return undefined;
        }
        return this.excludeDeleted(table);
    }
    /**
     * Create a soft-delete timestamp
     * Returns current timestamp for deletedAt field
     */
    markAsDeleted() {
        return new Date();
    }
    /**
     * Create a restore value (null for deletedAt)
     * Returns null to restore a soft-deleted record
     */
    markAsRestored() {
        return null;
    }
}
/**
 * Soft Delete Middleware
 * Automatically applies soft-delete filters to queries
 */
export class SoftDeleteMiddleware {
    helper;
    paranoidMode;
    constructor(paranoidMode = true, deletedAtColumn = 'deletedAt') {
        this.helper = new SoftDeleteHelper(deletedAtColumn);
        this.paranoidMode = paranoidMode;
    }
    /**
     * Wrap a where clause with soft-delete filter
     */
    applyFilter(table, existingWhere, options = {}) {
        const useParanoid = options.paranoid ?? this.paranoidMode;
        if (!useParanoid) {
            return existingWhere;
        }
        const softDeleteFilter = this.helper.excludeDeleted(table);
        if (existingWhere) {
            return and(existingWhere, softDeleteFilter);
        }
        return softDeleteFilter;
    }
    /**
     * Soft delete a record (set deletedAt to current timestamp)
     */
    getSoftDeleteUpdate() {
        return {
            deletedAt: this.helper.markAsDeleted(),
        };
    }
    /**
     * Restore a soft-deleted record (set deletedAt to null)
     */
    getRestoreUpdate() {
        return {
            deletedAt: this.helper.markAsRestored(),
        };
    }
}
/**
 * Default soft delete helper instance
 */
export const softDeleteHelper = new SoftDeleteHelper();
/**
 * Default soft delete middleware instance
 */
export const softDeleteMiddleware = new SoftDeleteMiddleware();
/**
 * Utility functions for common soft-delete operations
 */
/**
 * Build a soft delete update object
 * Usage: db.update(users).set(softDelete(userId))
 */
export function softDelete(userId) {
    return {
        deletedAt: new Date(),
        ...(userId && { userDeleted_Id: userId }),
    };
}
/**
 * Build a restore update object
 * Usage: db.update(users).set(restore())
 */
export function restore() {
    return {
        deletedAt: null,
    };
}
/**
 * Check if a record is soft-deleted
 * Usage: if (isSoftDeleted(record)) { ... }
 */
export function isSoftDeleted(record, deletedAtColumn = 'deletedAt') {
    return record[deletedAtColumn] != null;
}
/**
 * Filter array of records to exclude soft-deleted
 * Usage: const active = filterSoftDeleted(allRecords)
 */
export function filterSoftDeleted(records, deletedAtColumn = 'deletedAt') {
    return records.filter(record => !isSoftDeleted(record, deletedAtColumn));
}
/**
 * Filter array of records to include only soft-deleted
 * Usage: const deleted = filterOnlyDeleted(allRecords)
 */
export function filterOnlyDeleted(records, deletedAtColumn = 'deletedAt') {
    return records.filter(record => isSoftDeleted(record, deletedAtColumn));
}
/**
 * Example usage in a query builder wrapper
 */
export class SoftDeleteQueryBuilder {
    table;
    middleware;
    withDeleted = false;
    onlyDeletedFlag = false;
    constructor(table, paranoidMode = true) {
        this.table = table;
        this.middleware = new SoftDeleteMiddleware(paranoidMode);
    }
    /**
     * Include soft-deleted records in results
     */
    includeDeleted() {
        this.withDeleted = true;
        return this;
    }
    /**
     * Only return soft-deleted records
     */
    onlyDeleted() {
        this.onlyDeletedFlag = true;
        this.withDeleted = true;
        return this;
    }
    /**
     * Get the appropriate where clause
     */
    getWhereClause(existingWhere) {
        if (this.withDeleted && !this.onlyDeletedFlag) {
            return existingWhere;
        }
        if (this.onlyDeletedFlag) {
            const onlyDeletedFilter = softDeleteHelper.onlyDeleted(this.table);
            return existingWhere ? and(existingWhere, onlyDeletedFilter) : onlyDeletedFilter;
        }
        return this.middleware.applyFilter(this.table, existingWhere);
    }
    /**
     * Perform soft delete
     */
    getSoftDeleteData(userId) {
        return softDelete(userId);
    }
    /**
     * Perform restore
     */
    getRestoreData() {
        return restore();
    }
}
export default {
    withSoftDelete,
    SoftDeleteHelper,
    SoftDeleteMiddleware,
    SoftDeleteQueryBuilder,
    softDeleteHelper,
    softDeleteMiddleware,
    softDelete,
    restore,
    isSoftDeleted,
    filterSoftDeleted,
    filterOnlyDeleted,
};
//# sourceMappingURL=softDelete.js.map