import { getDatabase, getSqlClient } from "../utils/db.js";
import { schemaManager } from "../utils/schemaManager.js";
import env from "../utils/env.js";
/**
 * Migration status enum
 */
export type MigrationStatus = "pending" | "running" | "completed" | "failed" | "rolled_back";
/**
 * Migration type enum
 */
export type MigrationType = "system" | "schema" | "data" | "custom";
/**
 * Migration record interface
 */
export interface MigrationRecord {
    id?: string;
    version: string;
    name: string;
    description?: string;
    type: MigrationType;
    status: MigrationStatus;
    batch?: number;
    executedAt?: Date;
    executionTimeMs?: number;
    errorMessage?: string;
    errorStack?: string;
    metadata?: Record<string, any>;
    checksum?: string;
    canRollback?: boolean;
    rolledBackAt?: Date;
    createdAt?: Date;
    updatedAt?: Date;
}
/**
 * Migration script interface
 */
export interface MigrationScript {
    version: string;
    name: string;
    description?: string;
    type?: MigrationType;
    canRollback?: boolean;
    /**
     * The up function to run the migration
     */
    up: (context: MigrationContext) => Promise<MigrationResult>;
    /**
     * The down function to rollback the migration (optional)
     */
    down?: (context: MigrationContext) => Promise<MigrationResult>;
}
/**
 * Migration context passed to migration scripts
 */
export interface MigrationContext {
    db: ReturnType<typeof getDatabase>;
    sql: ReturnType<typeof getSqlClient>;
    schemaManager: typeof schemaManager;
    env: typeof env;
    log: (message: string) => void;
}
/**
 * Migration result from a script execution
 */
export interface MigrationResult {
    success: boolean;
    message?: string;
    metadata?: Record<string, any>;
}
/**
 * Migration run options
 */
export interface MigrationRunOptions {
    /** Run only specific migration version */
    version?: string;
    /** Run migrations up to and including this version */
    toVersion?: string;
    /** Number of migrations to run */
    step?: number;
    /** Only run pending migrations */
    pendingOnly?: boolean;
    /** Dry run - don't actually execute migrations */
    dryRun?: boolean;
}
/**
 * MigrationService - Handles database migration execution and tracking
 */
declare class MigrationService {
    private initialized;
    private migrationsDir;
    private systemMigrationsDir;
    private logs;
    private isUpgradeFromSequelize;
    constructor();
    /**
     * Detect if this is an upgrade from Sequelize version
     * MUST be called BEFORE schemaManager.initialize() because that creates the migration table
     *
     * Detection logic:
     * - If baasix_User exists but baasix_Migration does NOT exist → Sequelize upgrade
     * - If neither exists → Fresh installation
     * - If both exist → Already on Drizzle version
     */
    detectUpgradeBeforeSchemaInit(): Promise<boolean>;
    /**
     * Initialize the migration service
     * @param isUpgradeFromSequelize - Pass true if detectUpgradeBeforeSchemaInit() returned true
     */
    init(isUpgradeFromSequelize?: boolean): Promise<void>;
    /**
     * Check if this instance is an upgrade from Sequelize
     */
    isSequelizeUpgrade(): boolean;
    /**
     * Ensure migration directories exist
     */
    private ensureMigrationDirs;
    /**
     * Get all recorded migrations from database
     */
    getMigrations(options?: {
        status?: MigrationStatus;
        type?: MigrationType;
    }): Promise<MigrationRecord[]>;
    /**
     * Get the last executed migration
     */
    getLastMigration(): Promise<MigrationRecord | null>;
    /**
     * Get migration by version
     */
    getMigrationByVersion(version: string): Promise<MigrationRecord | null>;
    /**
     * Get pending migrations (scripts that haven't been executed)
     */
    getPendingMigrations(): Promise<MigrationScript[]>;
    /**
     * Load migration scripts from directory
     */
    loadMigrationScripts(directory?: string): Promise<MigrationScript[]>;
    /**
     * Load scripts from a specific directory
     */
    private loadScriptsFromDir;
    /**
     * Compare two version strings
     * Supports semver (1.0.0, 1.0.0-alpha.1) and timestamp (20240101_001) formats
     */
    private compareVersions;
    /**
     * Calculate checksum for a migration script
     */
    private calculateChecksum;
    /**
     * Run pending migrations
     */
    runPendingMigrations(options?: MigrationRunOptions): Promise<MigrationRecord[]>;
    /**
     * Run a single migration
     */
    runMigration(script: MigrationScript, batch?: number, dryRun?: boolean): Promise<MigrationRecord>;
    /**
     * Rollback a migration
     */
    rollbackMigration(version: string): Promise<MigrationRecord | null>;
    /**
     * Rollback the last batch of migrations
     */
    rollbackLastBatch(): Promise<MigrationRecord[]>;
    /**
     * Get the next batch number
     */
    private getNextBatchNumber;
    /**
     * Get migration status summary
     */
    getStatus(): Promise<{
        lastMigration: MigrationRecord | null;
        pendingCount: number;
        completedCount: number;
        failedCount: number;
        pending: MigrationScript[];
    }>;
    /**
     * Create a new migration file
     */
    createMigration(name: string, options?: {
        type?: MigrationType;
        description?: string;
        version?: string;
    }): Promise<string>;
    /**
     * Check and run migrations on startup if enabled
     * This should be called during app initialization
     */
    runStartupMigrations(): Promise<void>;
    /**
     * Handle upgrade from Sequelize version
     * This runs the baseline migration (to handle fullName, etc.) and marks
     * all other migrations up to the upgrade baseline as completed
     */
    private handleSequelizeUpgrade;
    /**
     * Set the user migrations directory
     */
    setMigrationsDir(dir: string): void;
    /**
     * Get the current migrations directory
     */
    getMigrationsDir(): string;
    /**
     * Mark a migration as completed without running it
     * Useful for existing installations that already have the changes
     */
    markAsCompleted(version: string, options?: {
        metadata?: Record<string, any>;
    }): Promise<MigrationRecord | null>;
    /**
     * Mark all migrations up to a version as completed
     * Useful for bringing an existing database up to date without running migrations
     */
    markAllAsCompleted(toVersion?: string): Promise<MigrationRecord[]>;
    /**
     * Get the current Baasix version from package.json
     */
    getCurrentBaasixVersion(): Promise<string>;
    /**
     * Check if database needs migrations based on current version
     */
    checkMigrationNeeded(): Promise<{
        needed: boolean;
        lastVersion: string | null;
        currentVersion: string;
        pendingCount: number;
    }>;
}
declare global {
    var __baasix_migrationService: MigrationService | undefined;
}
declare const migrationService: MigrationService;
export default migrationService;
export { MigrationService };
//# sourceMappingURL=MigrationService.d.ts.map