import { IEventBus } from '../subsystems/events/event-bus.protocol.js';
import '../types/drizzle.js';
import 'drizzle-orm/node-postgres';

/**
 * BaseService<TRepo, TEntity>
 *
 * Abstract base class providing 8 CRUD pass-through methods delegating to
 * an injected repository. Every generated service extends this class.
 *
 * Lifecycle event emission (LIFECYCLE + CHANGE categories) is built into
 * create/update/delete — matching pattern-stack's BaseService. Events are
 * fire-and-forget: emission never fails the CRUD operation. If no IEventBus
 * is injected (eventBus is undefined), emission is silently skipped.
 *
 * Generated services set `entityName` and optionally inject `eventBus` via
 * NestJS property injection (@Inject(EVENT_BUS) @Optional()).
 *
 * Note: @Injectable() is applied on concrete services (not here) so that
 * NestJS DI metadata is emitted at the concrete class level. This matches
 * the pattern established by BaseRepository.
 */

/**
 * Structural interface that BaseRepository satisfies.
 * Use this as the TRepo constraint so BaseService is not coupled to the
 * concrete Drizzle-backed BaseRepository.
 */
interface IBaseRepository<TEntity> {
    findById(id: string): Promise<TEntity | null>;
    findByIds(ids: string[]): Promise<TEntity[]>;
    list(options?: unknown): Promise<TEntity[]>;
    count(where?: unknown): Promise<number>;
    exists(id: string): Promise<boolean>;
    create(input: Partial<TEntity>, tx?: unknown): Promise<TEntity>;
    update(id: string, input: Partial<TEntity>, tx?: unknown): Promise<TEntity>;
    delete(id: string, tx?: unknown): Promise<void>;
}
declare abstract class BaseService<TRepo extends IBaseRepository<TEntity>, TEntity> {
    protected readonly repository: TRepo;
    /**
     * Entity name for event types (e.g., 'account' → 'account.created').
     * Set by generated services. If empty, lifecycle events are skipped.
     */
    protected entityName?: string;
    /**
     * Event bus for lifecycle/change event emission.
     * Injected via @Inject(EVENT_BUS) @Optional() on generated services.
     * If undefined (no events subsystem installed), emission is silently skipped.
     */
    protected eventBus?: IEventBus;
    /**
     * Whether to emit lifecycle events. Default: true.
     * Override to false in entity YAML via behaviors or in the service class.
     */
    protected emitLifecycleEvents: boolean;
    constructor(repository: TRepo);
    /**
     * Find a single entity by its primary key.
     * Returns null if not found.
     */
    findById(id: string): Promise<TEntity | null>;
    /**
     * Find multiple entities by their primary keys.
     */
    findByIds(ids: string[]): Promise<TEntity[]>;
    /**
     * List entities with optional filtering/pagination options.
     */
    list(options?: unknown): Promise<TEntity[]>;
    /**
     * Count entities matching an optional filter.
     */
    count(where?: unknown): Promise<number>;
    /**
     * Check whether an entity with the given id exists.
     */
    exists(id: string): Promise<boolean>;
    /**
     * Insert a new entity.
     * Emits a LIFECYCLE 'created' event with entity snapshot.
     */
    create(input: Partial<TEntity>, tx?: unknown): Promise<TEntity>;
    /**
     * Update an existing entity by id.
     * Emits a LIFECYCLE 'updated' event + CHANGE events for each modified field.
     */
    update(id: string, input: Partial<TEntity>, tx?: unknown): Promise<TEntity>;
    /**
     * Delete an entity by id.
     * Emits a LIFECYCLE 'deleted' event.
     */
    delete(id: string, tx?: unknown): Promise<void>;
    /** Check whether lifecycle event emission is active. */
    private _shouldEmit;
}

export { BaseService, type IBaseRepository };
