import { Alepha, KIND, Middleware, Primitive } from "alepha";
import "dayjs/plugin/relativeTime.js";
import dayjsDuration, { DurationUnitType } from "dayjs/plugin/duration.js";
import "dayjs/plugin/utc.js";
import "dayjs/plugin/timezone.js";
import "dayjs/plugin/localizedFormat.js";
import "dayjs/locale/ar.js";
import "dayjs/locale/fr.js";
import { Dayjs, ManipulateType, OpUnitType, PluginFunc, QUnitType } from "dayjs";
//#region ../../src/datetime/providers/DateTimeProvider.d.ts
type DateTimeInput = string | number | Date | DateTime | Dayjs;
type DurationLike = number | Duration | [number, ManipulateType];
/**
 * Immutable wrapper around the underlying date-time engine.
 *
 * Designed to isolate consumers from the engine in use (currently dayjs).
 * Methods that produce a new value return a new `DateTime` instance.
 */
declare class DateTime {
  protected readonly inner: Dayjs;
  constructor(inner: Dayjs);
  /**
   * Add a duration to this date-time.
   */
  add(amount: number, unit?: ManipulateType): DateTime;
  add(duration: Duration): DateTime;
  /**
   * Subtract a duration from this date-time.
   */
  subtract(amount: number, unit?: ManipulateType): DateTime;
  subtract(duration: Duration): DateTime;
  startOf(unit: OpUnitType): DateTime;
  endOf(unit: OpUnitType): DateTime;
  isAfter(other: DateTimeInput): boolean;
  isBefore(other: DateTimeInput): boolean;
  isSame(other: DateTimeInput, unit?: OpUnitType): boolean;
  diff(other: DateTimeInput, unit?: QUnitType | OpUnitType): number;
  tz(timezone: string): DateTime;
  locale(lang: string): DateTime;
  format(template?: string): string;
  fromNow(withoutSuffix?: boolean): string;
  toISOString(): string;
  toDate(): Date;
  valueOf(): number;
  unix(): number;
  toJSON(): string;
  toString(): string;
  /**
   * Escape hatch for the underlying dayjs instance.
   *
   * Use sparingly — anything calling this becomes coupled to dayjs and
   * will need to migrate when the engine is replaced.
   */
  toDayjs(): Dayjs;
}
/**
 * Immutable wrapper around the underlying duration engine.
 */
declare class Duration {
  protected readonly inner: dayjsDuration.Duration;
  constructor(inner: dayjsDuration.Duration);
  asMilliseconds(): number;
  asSeconds(): number;
  asMinutes(): number;
  asHours(): number;
  asDays(): number;
  as(unit: DurationUnitType): number;
  toISOString(): string;
  /**
   * Escape hatch for the underlying dayjs duration.
   */
  toDayjs(): dayjsDuration.Duration;
}
declare const isDateTime: (value: unknown) => value is DateTime;
declare class DateTimeProvider {
  static PLUGINS: Array<PluginFunc<any>>;
  protected alepha: Alepha;
  protected ref: DateTime | null;
  protected readonly timeouts: Timeout[];
  protected readonly intervals: Interval[];
  constructor();
  protected readonly onStart: import("alepha").HookPrimitive<"start">;
  protected readonly onStop: import("alepha").HookPrimitive<"stop">;
  setLocale(locale: string): void;
  isDateTime(value: unknown): value is DateTime;
  /**
   * Create a new UTC DateTime instance.
   */
  utc(date: DateTimeInput | null | undefined): DateTime;
  /**
   * Create a new DateTime instance.
   */
  of(date: DateTimeInput | null | undefined): DateTime;
  /**
   * Get the current date as a string.
   */
  toISOString(date?: DateTimeInput): string;
  /**
   * Get the current date.
   */
  now(): DateTime;
  /**
   * Get the current date as a string.
   *
   * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.
   */
  nowISOString(): string;
  /**
   * Get the current date as milliseconds since epoch.
   *
   * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.
   */
  nowMillis(): number;
  /**
   * Get the current date as a string.
   *
   * @protected
   */
  protected getCurrentDate(): DateTime;
  /**
   * Create a new Duration instance.
   */
  duration: (duration: DurationLike, unit?: ManipulateType) => Duration;
  isDurationLike(value: unknown): value is DurationLike;
  /**
   * Return a promise that resolves after the next tick.
   * It uses `setTimeout` with 0 ms delay.
   */
  tick(): Promise<void>;
  /**
   * Wait for a certain duration.
   *
   * You can clear the timeout by using the `AbortSignal` API.
   * Aborted signal will resolve the promise immediately, it does not reject it.
   */
  wait(duration: DurationLike, options?: {
    signal?: AbortSignal;
    now?: number;
  }): Promise<void>;
  createInterval(run: () => unknown, duration: DurationLike, start?: boolean): Interval;
  /**
   * Run a callback after a certain duration.
   */
  createTimeout(callback: () => void, duration: DurationLike, now?: number): Timeout;
  clearTimeout(timeout: Timeout): void;
  clearInterval(interval: Interval): void;
  /**
   * Run a function with a deadline.
   */
  deadline<T>(fn: (signal: AbortSignal) => Promise<T>, duration: DurationLike): Promise<T>;
  /**
   * Add time to the current date.
   */
  travel(duration: DurationLike, unit?: ManipulateType): Promise<void>;
  /**
   * Stop the time.
   */
  pause(): DateTime;
  /**
   * Reset the reference date.
   */
  reset(): void;
}
interface Interval {
  timer?: any;
  duration: number;
  run: () => unknown;
}
interface Timeout {
  now: number;
  timer?: any;
  duration: number;
  callback: () => void;
  clear: () => void;
}
//#endregion
//#region ../../src/datetime/primitives/$debounce.d.ts
interface DebounceOptions {
  /**
   * Coalescing window. Concurrent calls within this window share one execution.
   */
  delay: DurationLike;
  /**
   * Key function to group calls. Calls with the same key are coalesced.
   * Defaults to `JSON.stringify(args)`.
   */
  key?: (...args: any[]) => string;
}
/**
 * Middleware that coalesces concurrent calls with the same key into a single handler execution.
 *
 * All callers within the delay window receive the same result. No storage —
 * once the handler finishes, the next call starts fresh. Process-local.
 *
 * **Use case**: thundering herd protection — cache expires, 100 requests
 * hit the same endpoint, debounce ensures one rebuild.
 *
 * ```typescript
 * class SearchController {
 *   search = $action({
 *     use: [$debounce({ delay: [200, "ms"], key: (req) => req.query.q })],
 *     handler: async ({ query }) => this.searchService.search(query.q),
 *   });
 * }
 * ```
 */
declare const $debounce: (options: DebounceOptions) => Middleware;
//#endregion
//#region ../../src/datetime/primitives/$interval.d.ts
/**
 * Run a function periodically.
 * It uses the `setInterval` internally.
 * It starts by default when the context starts and stops when the context stops.
 */
declare const $interval: {
  (options: IntervalPrimitiveOptions): IntervalPrimitive;
  [KIND]: typeof IntervalPrimitive;
};
interface IntervalPrimitiveOptions {
  /**
   * The interval handler.
   */
  handler: () => unknown;
  /**
   * The interval duration.
   */
  duration: DurationLike;
}
declare class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {
  protected readonly dateTimeProvider: DateTimeProvider;
  called: number;
  protected onInit(): void;
}
//#endregion
//#region ../../src/datetime/primitives/$throttle.d.ts
interface ThrottleOptions {
  /**
   * Max calls per window.
   */
  rate: number;
  /**
   * Window duration.
   */
  per: DurationLike;
}
/**
 * Middleware that rate-controls handler execution using a token bucket.
 *
 * Excess calls are **delayed** until capacity is available — never rejected.
 * Process-local (not distributed) — it cannot rate-limit across instances.
 *
 * **Limitation**: the token refill is time-based and re-checked only when a
 * waiter wakes, so a burst of *concurrent* calls can wake in the same window
 * and briefly exceed `rate`. Treat it as traffic smoothing, not a hard cap —
 * do not rely on it to enforce a strict quota.
 *
 * **Use case**: protect an external API from your own traffic.
 *
 * ```typescript
 * class PaymentController {
 *   charge = $action({
 *     use: [$throttle({ rate: 80, per: [1, "second"] })],
 *     handler: async ({ body }) => this.stripe.charges.create(body),
 *   });
 * }
 * ```
 */
declare const $throttle: (options: ThrottleOptions) => Middleware;
//#endregion
//#region ../../src/datetime/primitives/$timeout.d.ts
/**
 * Middleware that aborts handler execution if it exceeds a duration limit.
 *
 * Uses `Promise.race` with a managed timeout from `DateTimeProvider` —
 * if the handler doesn't resolve before the deadline, the promise rejects.
 * Uses managed timeouts so it works with `DateTimeProvider.travel()` in tests.
 *
 * ```typescript
 * class OrderService {
 *   processOrder = $pipeline({
 *     use: [$timeout([30, "seconds"])],
 *     handler: async (orderId: string) => {
 *       return await this.orders.updateById(orderId, { status: "paid" });
 *     },
 *   });
 * }
 * ```
 */
declare const $timeout: (duration: DurationLike) => Middleware;
//#endregion
//#region ../../src/datetime/index.d.ts
/**
 * Date and time operations.
 *
 * **Features:**
 * - Recurring interval definitions
 * - Duration parsing (ISO 8601, human-readable)
 * - Timezone support
 * - Dayjs integration
 *
 * @module alepha.datetime
 */
declare const AlephaDateTime: import("alepha").Service<import("alepha").Module>;
//#endregion
export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTime, DateTimeInput, DateTimeProvider, DebounceOptions, Duration, DurationLike, type DurationUnitType, Interval, IntervalPrimitive, IntervalPrimitiveOptions, type ManipulateType, type OpUnitType, type QUnitType, ThrottleOptions, Timeout, isDateTime };
//# sourceMappingURL=index.d.ts.map