import type { Client, PoolClient } from 'pg';
import type { FixtureBusinesses, FixtureTaxCategories } from './fixture-types.js';
/**
 * Valid financial entity types based on database schema
 */
export type FinancialEntityType = 'business' | 'tax_category' | 'tag';
export interface EnsureFinancialEntityParams {
    id?: string;
    name: string;
    type: FinancialEntityType;
    ownerId?: string;
}
export interface FinancialEntityResult {
    id: string;
}
/**
 * Ensure a financial entity exists in the database (idempotent)
 *
 * **Idempotency Behavior:**
 * - If an entity with matching (name, type, owner_id) exists, returns existing entity ID
 * - Does NOT update existing entities - preserves all existing field values
 * - If no match found, inserts new entity and returns new ID
 * - Safe to call multiple times with same parameters
 *
 * **NULL Handling:**
 * - `ownerId: undefined` and `ownerId: null` are treated identically (as NULL in DB)
 * - Correctly handles SQL NULL semantics in uniqueness check
 *
 * @param client - PostgreSQL client (must be within a transaction for rollback safety)
 * @param params - Entity parameters
 * @param params.name - Entity name (required, non-empty)
 * @param params.type - Entity type (must be 'business', 'tax_category', or 'tag')
 * @param params.ownerId - Optional owner entity ID (must exist in financial_entities if provided)
 * @returns Promise resolving to object containing entity id
 * @throws {EntityValidationError} If name is empty or type is invalid
 * @throws {SeedError} If database operation fails
 *
 * @example
 * ```typescript
 * // Create standalone business entity
 * const { id: adminId } = await ensureFinancialEntity(client, {
 *   name: 'Admin Business',
 *   type: 'business',
 * });
 *
 * // Create owned tax category
 * const { id: taxId } = await ensureFinancialEntity(client, {
 *   name: 'VAT Category',
 *   type: 'tax_category',
 *   ownerId: adminId,
 * });
 *
 * // Calling again returns same ID (idempotent)
 * const { id: sameId } = await ensureFinancialEntity(client, {
 *   name: 'Admin Business',
 *   type: 'business',
 * });
 * // sameId === adminId
 * ```
 */
export declare function ensureFinancialEntity(client: PoolClient | Client, params: EnsureFinancialEntityParams): Promise<FinancialEntityResult>;
export type EnsureBusinessForEntityOptions = Partial<Omit<FixtureBusinesses['businesses'][number], 'id'>>;
/**
 * Ensure a business row exists for a given financial entity id (idempotent)
 *
 * **Idempotency Behavior:**
 * - If business already exists for the given entity ID, does nothing
 * - Does NOT update existing business configuration - preserves all existing values
 * - If business doesn't exist, creates new row with provided options
 * - Safe to call multiple times with same entityId
 *
 * **Foreign Key Requirement:**
 * - The entityId MUST correspond to an existing financial_entities record
 * - Will validate entity exists before attempting insert
 *
 * @param client - PostgreSQL client (must be within a transaction for rollback safety)
 * @param entityId - Financial entity ID to use as business ID (must exist in financial_entities)
 * @param options - Optional business configuration
 * @param options.noInvoicesRequired - Whether invoices are required (default: false)
 * @returns Promise resolving when complete
 * @throws {EntityValidationError} If entityId is invalid format
 * @throws {EntityNotFoundError} If financial entity doesn't exist
 * @throws {SeedError} If database operation fails
 *
 * @example
 * ```typescript
 * // First create financial entity
 * const { id: entityId } = await ensureFinancialEntity(client, {
 *   name: 'My Business',
 *   type: 'business',
 * });
 *
 * // Then create business record
 * await ensureBusinessForEntity(client, entityId, {
 *   noInvoicesRequired: true,
 * });
 *
 * // Calling again is safe (no-op)
 * await ensureBusinessForEntity(client, entityId, {
 *   noInvoicesRequired: false, // Ignored - existing value preserved
 * });
 * ```
 */
export declare function ensureBusinessForEntity(client: PoolClient | Client, entityId: string, options?: EnsureBusinessForEntityOptions): Promise<void>;
export type EnsureTaxCategoryForEntityOptions = Partial<Omit<FixtureTaxCategories['taxCategories'][number], 'id'>> & {
    sortCode?: number;
};
/**
 * Ensure a tax_categories row exists for a given financial entity id (idempotent)
 *
 * **Idempotency Behavior:**
 * - If tax category already exists for the given entity ID, does nothing
 * - Does NOT update existing tax category - preserves all existing values
 * - If tax category doesn't exist, creates new row
 * - Safe to call multiple times with same entityId
 *
 * **Foreign Key Requirement:**
 * - The entityId MUST correspond to an existing financial_entities record
 * - Will validate entity exists before attempting insert
 *
 * **Name Handling:**
 * - Tax category names live on the financial_entities table
 * - This table only ensures the linkage row exists
 *
 * @param client - PostgreSQL client (must be within a transaction for rollback safety)
 * @param entityId - Financial entity ID to use as tax category ID (must exist in financial_entities)
 * @param options - Optional tax category configuration
 * @param options.sortCode - Optional sort code for accounting systems
 * @returns Promise resolving when complete
 * @throws {EntityValidationError} If entityId is invalid format
 * @throws {EntityNotFoundError} If financial entity doesn't exist
 * @throws {SeedError} If database operation fails
 *
 * @example
 * ```typescript
 * // First create financial entity
 * const { id: entityId } = await ensureFinancialEntity(client, {
 *   name: 'VAT Category',
 *   type: 'tax_category',
 * });
 *
 * // Then create tax category record
 * await ensureTaxCategoryForEntity(client, entityId, {
 *   sortCode: 1000,
 * });
 *
 * // Calling again is safe (no-op)
 * await ensureTaxCategoryForEntity(client, entityId, {
 *   sortCode: 2000, // Ignored - existing value preserved
 * });
 * ```
 */
export declare function ensureTaxCategoryForEntity(client: PoolClient | Client, entityId: string, options?: EnsureTaxCategoryForEntityOptions): Promise<void>;
export declare function setAdminEntity(client: PoolClient): Promise<string>;
