import { z } from 'zod';

type ValidatorConfig<T> = {
    schema: z.ZodType<T>;
    transform?: (value: string) => unknown;
};
type EnvConfig<T> = {
    [K in keyof T]: ValidatorConfig<T[K]>;
};

/**
 * Creates a strongly-typed environment configuration object with runtime validation.
 *
 * @template T - Type of the resulting environment object. Must be a record of string keys to unknown values.
 * @param {EnvConfig<T>} config - Configuration object mapping environment keys to their validators
 * @returns {T} A validated environment object matching the type parameter
 * @throws {EnvValidationError} When environment variables are missing or fail validation
 *
 * @example
 * ```ts
 * const env = createClientEnv({
 * MY_ENV_VAR: z.string(),
 * MY_OTHER_ENV_VAR: z.number(),
 * });
 * // env is now typed as { MY_ENV_VAR: string, MY_OTHER_ENV_VAR: number }
 * ```
 */
declare const createClientEnv: <T extends Record<string, unknown>>(config: EnvConfig<T>) => T;

/**
 * Creates a strongly-typed environment configuration object with runtime validation.
 *
 * @template T - Type of the resulting environment object. Must be a record of string keys to unknown values.
 * @param {EnvConfig<T>} config - Configuration object mapping environment keys to their validators
 * @returns {T} A validated environment object matching the type parameter
 * @throws {Error} When accessed from client-side code (server.ts only)
 * @throws {EnvValidationError} When environment variables are missing or fail validation
 *
 * @example
 * ```ts
 * const env = createServerEnv({
 *   DATABASE_URL: { schema: z.string().url() },
 *   PORT: {
 *     schema: z.number(),
 *     transform: (val) => parseInt(val, 10)
 *   }
 * });
 * // env is now typed as { DATABASE_URL: string, PORT: number }
 * ```
 */
declare const createServerEnv: <T extends Record<string, unknown>>(config: EnvConfig<T>) => T;

declare class EnvValidationError extends Error {
    errors: Array<{
        key: string;
        message: string;
    }>;
    constructor(message: string, errors: Array<{
        key: string;
        message: string;
    }>);
}

/**
 * Transformers are helper functions that can be used to transform the value of an environment variable.
 * They are useful for converting strings to other types, such as numbers or booleans.
 */
declare const transformers: {
    number: (val: string) => number;
    optionalNumber: (val: string | undefined) => number | undefined;
    boolean: (val: string) => val is "true";
    optionalBoolean: (val: string | undefined) => boolean | undefined;
    json: <T>(val: string) => T;
};

export { type EnvConfig, EnvValidationError, createClientEnv, createServerEnv, transformers };
