/**
 * Options for configuring the Azion client behavior.
 *
 * @property {boolean} [debug] - Enable debug mode for detailed logging.
 * @property {boolean} [force] - Force the operation even if it might be destructive.
 * @property {AzionEnvironment} [env] - Environment to use (dev, stage, prod).
 * @property {boolean} [external] - Force using external REST API instead of built-in runtime API.
 *
 * @example
 * const options: AzionClientOptions = {
 *   debug: true,
 *   force: false,
 *   env: 'dev',
 *   external: true
 * };
 */
export declare type AzionClientOptions = {
    /** Enable debug mode for detailed logging */
    debug?: boolean;
    /** Force the operation even if it might be destructive */
    force?: boolean;
    /** Environment to use (dev, stage, prod) */
    env?: AzionEnvironment;
    /** Force using external REST API instead of built-in runtime API */
    external?: boolean;
};

export declare type AzionDatabase = Database & {
    /**
     * Executes a query or multiple queries on the database.
     *
     * @param {string[]} statements - An array of SQL statements to execute.
     * @param {AzionClientOptions} [options] - Additional options for the query execution.
     * @returns {Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>} A promise that resolves to the query response or error if the operation faile>d.
     *
     * @example
     * const result = await database.query([
     *   'SELECT * FROM users WHERE id = ?',
     *   'UPDATE users SET last_login = NOW() WHERE id = ?'
     * ], { debug: true });
     */
    query: (statements: string[], options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;
    /**
     * Executes one or more SQL statements on the database.
     *
     * @param {string[]} statements - An array of SQL statements to execute.
     * @param {AzionClientOptions} [options] - Additional options for the execution.
     * @returns {Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>} A promise that resolves to the query response or error if the operation faile>d.
     *
     * @example
     * const result = await database.execute([
     *   'INSERT INTO users (name, email) VALUES (?, ?)',
     *   'DELETE FROM old_users WHERE last_login < ?'
     * ], { force: true });
     */
    execute: (statements: string[], options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;
    /**
     * Retrieves a list of tables in the database.
     *
     * @param {AzionClientOptions} [options] - Additional options for listing tables.
     * @returns {Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>} A promise that resolves to the query response or error if the operation faile>d.
     *
     * @example
     * const { data: tables, error } = await database.getTables({ debug: true });
     */
    getTables: (options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;
};

export declare type AzionDatabaseCollectionOptions = {
    ordering?: string;
    page?: number;
    page_size?: number;
    search?: string;
};

export declare type AzionDatabaseCollections = {
    databases?: AzionDatabase[];
    count?: number;
};

export declare type AzionDatabaseDeleteResponse = {
    state: 'pending' | 'failed' | 'executed';
};

export declare type AzionDatabaseExecutionResponse = AzionDatabaseQueryResponse;

export declare type AzionDatabaseQueryResponse = {
    state: 'pending' | 'failed' | 'executed' | 'executed-runtime';
    results?: QueryResult[];
    toObject: () => JsonObjectQueryExecutionResponse | null;
};

export declare type AzionDatabaseResponse<T> = {
    data?: T;
    error?: AzionSQLError;
};

/**
 * Defines the execution environment for the Azion client.
 *
 * @type {('development' | 'staging' | 'production')}
 *
 * @property {'development'} development - Development environment for local testing
 * @property {'staging'} staging - Staging/testing environment
 * @property {'production'} production - Production environment
 *
 * @example
 * const environment: AzionEnvironment = 'development';
 *
 * @example
 * const clientOptions = {
 *   env: 'production' as AzionEnvironment
 * };
 */
export declare type AzionEnvironment = 'development' | 'staging' | 'production';

export declare type AzionQueryExecutionParams = {
    statements: string[];
    params: Array<AzionQueryParams | Record<string, AzionQueryParams>>;
};

export declare type AzionQueryParams = string | number | boolean | null | {
    type: string;
    value: string | number | boolean | null;
};

export declare interface AzionSQLClient {
    /**
     * Creates a new database with the specified name.
     *
     * @param {string} name - Name of the database to create.
     * @returns {Promise<AzionDatabaseResponse>} Object confirming creation of the database or an error message.
     *
     * @example
     * const { data, error } = await sqlClient.createDatabase('my-db');
     * if (data) {
     *  console.log(`Database ${data.name} created successfully`);
     * } else {
     * console.error(`Failed to create database: ${error.message}`);
     *
     */
    createDatabase: (name: string) => Promise<AzionDatabaseResponse<AzionDatabase>>;
    /**
     * Deletes a database by its ID.
     *
     * @param {number} id - ID of the database to delete.
     * @returns {Promise<AzionDatabaseResponse<AzionDatabaseDeleteResponse>>} Object confirming deletion or error if the operation failed.
     *
     * @example
     * const { data, error } = await sqlClient.deleteDatabase(123);
     * if (data) {
     * console.log(`Database ${data.name} (ID: ${data.id}) deleted successfully`);
     * } else {
     * console.error(`Failed to delete database: ${error.message}`);
     *
     */
    deleteDatabase: (id: number) => Promise<AzionDatabaseResponse<AzionDatabaseDeleteResponse>>;
    /**
     * Retrieves a database by its Name.
     *
     * @param {string} name - Name of the database to retrieve.
     * @returns {Promise<AzionDatabaseResponse<AzionDatabase>>} The retrieved database object or null if not found.
     *
     * @example
     * const { data, error } = await sqlClient.getDatabase('my-db');
     * if (data) {
     *  console.log(`Retrieved database ${data.name} (ID: ${data.id})`);
     * } else {
     * console.error(`Failed to retrieve database: ${error.message}`);
     *
     */
    getDatabase: (name: string) => Promise<AzionDatabaseResponse<AzionDatabase>>;
    /**
     * Retrieves a list of databases with optional filtering and pagination.
     *
     * @param {AzionDatabaseCollectionOptions} [params] - Optional parameters for filtering and pagination.
     * @param {string} [params.ordering] - Field to order the results by.
     * @param {number} [params.page] - Page number for pagination.
     * @param {number} [params.page_size] - Number of items per page.
     * @param {string} [params.search] - Search term to filter databases.
     * @returns {Promise<AzionDatabaseResponse>} Array of database objects or error message.
     *
     * @example
     * const { data, error } = await sqlClient.getDatabases({ page: 1, page_size: 10, search: 'test' });
     * if (data) {
     * console.log(`Retrieved ${data.length} databases`);
     * } else {
     * console.error(`Failed to retrieve databases: ${error.message}`);
     *
     */
    getDatabases: (params?: {
        ordering?: string;
        page?: number;
        page_size?: number;
        search?: string;
    }) => Promise<AzionDatabaseResponse<AzionDatabaseCollections>>;
}

export declare type AzionSQLError = {
    message: string;
    operation: string;
    metadata?: Record<string, unknown>;
};

/**
 * Creates an SQL client with methods to interact with Azion SQL databases.
 *
 * @param {Partial<{ token?: string; options?: AzionClientOptions; }>} [config] - Configuration options for the SQL client.
 * @returns {AzionSQLClient} An object with methods to interact with SQL databases.
 *
 * @example
 * const sqlClient = createClient({ token: 'your-api-token', options: { debug: true } });
 *
 * // Create a new database
 * const { data: newDatabase } = await sqlClient.createDatabase('my-new-db');
 *
 * // Get all databases
 * const allDatabases = await sqlClient.getDatabases();
 *
 * // Query a database
 * const queryResult = await newDatabase.query(['SELECT * FROM users']);
 */
declare const client: CreateAzionSQLClient;
export { client as createClient }
export default client;

/**
 * Function type for creating an Azion SQL Client.
 *
 * @param {Object} [config] - Configuration options for the SQL client.
 * @param {string} [config.token] - Authentication token for Azion API. If not provided,
 * the client will attempt to use the AZION_TOKEN environment variable.
 * @param {AzionClientOptions} [config.options] - Additional client options.
 *
 * @returns {AzionSQLClient} An instance of the Azion SQL Client.
 *
 * @example
 * // Create an SQL client with a token and debug mode enabled
 * const sqlClient = createAzionSQLClient({
 *   token: 'your-api-token',
 *   options: { debug: true }
 * });
 *
 * @example
 * // Create an SQL client using environment variables for token
 * const sqlClient = createAzionSQLClient();
 */
export declare type CreateAzionSQLClient = (config?: Partial<{
    token?: string;
    options?: AzionClientOptions;
}>) => AzionSQLClient;

/**
 * Creates a new database.
 *
 * @param {string} name - Name of the database to create.
 * @param {AzionClientOptions} [options] - Optional parameters for the deletion.
 * @returns {Promise<AzionDatabaseResponse<AzionDatabase>>} The created database object or error if creation failed.
 *
 * @example
 * const { data, error } = await createDatabase('my-new-database', { debug: true });
 * if (data) {
 *  console.log(`Database ${data.id} created successfully`);
 * } else {
 *  console.error(`Failed to create database: ${error.message}`);
 * }
 */
export declare const createDatabase: (name: string, options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabase>>;

export declare type Database = {
    id: number;
    name: string;
    status: 'creating' | 'created' | 'deleting';
    active: boolean;
    lastModified: string;
    lastEditor: string | null;
    productVersion: string;
};

/**
 * Deletes a database by its ID.
 *
 * @param {number} id - ID of the database to delete.
 * @param {AzionClientOptions} [options] - Optional parameters for the deletion.
 * @returns {Promise<AzionDatabaseResponse<AzionDatabaseDeleteResponse>>} Object confirming deletion or error if deletion failed.
 *
 * @example
 * const { data, error } = await deleteDatabase(123, { debug: true });
 * if (data) {
 * console.log(`Database ${data.id} deleted successfully`);
 * } else {
 * console.error(`Failed to delete database: ${error.message}`);
 *
 */
export declare const deleteDatabase: (id: number, options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseDeleteResponse>>;

/**
 * Retrieves a database by its Name.
 *
 * @param {string} name - Name of the database to retrieve.
 * @param {AzionClientOptions} [options] - Optional parameters for the deletion.
 * @returns {Promise<AzionDatabaseResponse<AzionDatabase>>} The retrieved database object or error if not found.
 *
 * @example
 * const { data, error } = await getDatabase('my-db', { debug: true });
 * if (data) {
 *  console.log(`Retrieved database ${data.name} (ID: ${data.id})`);
 * } else {
 *  console.error(`Failed to retrieve database: ${error.message}`);
 * }
 */
export declare const getDatabase: (name: string, options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabase>>;

/**
 * Retrieves a list of databases with optional filtering and pagination.
 *
 * @param {Partial<AzionDatabaseCollectionOptions>} [params] - Optional parameters for filtering and pagination.
 * @param {AzionClientOptions} [options] - Optional parameters for the deletion.
 * @returns {Promise<AzionDatabaseResponse<AzionDatabaseCollections>>} Array of database objects or error if retrieval failed.
 *
 * @example
 * const { data: allDatabases, error } = await getDatabases({ page: 1, page_size: 10 }, { debug: true });
 * if (allDatabases) {
 * console.log(`Retrieved ${allDatabases.count} databases`);
 * allDatabases.results.forEach(db => console.log(`- ${db.name} (ID: ${db.id})`));
 * } else {
 * console.error('Failed to retrieve databases', error);
 * }
 *
 */
export declare const getDatabases: (params?: Partial<AzionDatabaseCollectionOptions>, options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseCollections>>;

/**
 * List tables from a database.
 * @param databaseName Name of the database to list tables from.
 * @param options Optional parameters for the query.
 * @returns The query response object or null if the query failed.
 */
export declare const getTables: (databaseName: string, options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;

declare type JsonObjectQueryExecutionResponse = {
    results?: {
        statement?: string;
        rows: {
            [key: string]: any;
        }[];
    }[];
};

export declare type QueryResult = {
    columns?: string[];
    rows?: (string | number)[][];
    statement?: string;
    error?: string;
};

export declare type ToObjectQueryExecution = {
    data: Array<{
        statement?: string;
        rows: Record<string, string | number>[];
    }>;
};

/**
 * Use Execute to execute a set of SQL statements on a database.
 * @param name Name of the database to execute the statements on.
 * @param statements Array of SQL statements to execute.
 * @param options.debug Debug mode for detailed logging.
 * @param options.force Force the query execution.
 * @returns The query response object or null if the query failed.
 *
 * @example
 * const { data, error } = await useExecute('my-db', ['INSERT INTO users (name) VALUES ("John")']);
 * if (data) {
 * console.log(`Statements executed with success`, data);
 * } else {
 * console.error(`Failed to execute statements: `, error);
 *
 */
export declare const useExecute: (name: string, statements: string[], options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;

/**
 * Use Query to execute a query on a database.
 * @param name Name of the database to query.
 * @param statements Array of SQL statements to execute.
 * @param options Optional parameters for the query.
 * @param options.debug Debug mode for detailed logging.
 * @param options.force Force the query execution.
 * @returns The query response object or null if the query failed.
 * @example
 * const { data, error } = await useQuery('my-db', ['SELECT * FROM users']);
 * if (data) {
 *  console.log(`Query executed with success`, data);
 * } else {
 * console.error(`Failed to execute query: ${error.message}`);
 *
 */
export declare const useQuery: (name: string, statements: string[], options?: AzionClientOptions) => Promise<AzionDatabaseResponse<AzionDatabaseQueryResponse>>;

export { }
