/**
 * Base entity type with common fields
 * @invariant updatedAt >= createdAt
 */
export interface BaseEntity {
  readonly id: string;
  readonly createdAt: Date;
  updatedAt: Date;
}

/**
 * API response wrapper - discriminated union for type-safe error handling
 *
 * Usage:
 * ```typescript
 * if (response.success) {
 *   // TypeScript knows response.data exists
 *   console.log(response.data);
 * } else {
 *   // TypeScript knows response.message exists
 *   console.error(response.message);
 * }
 * ```
 */
export type ApiResponse<T> =
  | { success: true; data: T; message?: string }
  | { success: false; data?: never; message: string; errorCode?: string };

/**
 * Helper to create a successful API response
 */
export function successResponse<T>(data: T, message?: string): ApiResponse<T> {
  if (message !== undefined) {
    return { success: true, data, message };
  }
  return { success: true, data };
}

/**
 * Helper to create an error API response
 */
export function errorResponse<T>(message: string, errorCode?: string): ApiResponse<T> {
  if (errorCode !== undefined) {
    return { success: false, message, errorCode };
  }
  return { success: false, message };
}

/**
 * Pagination parameters
 */
export interface PaginationParams<SortableFields extends string = string> {
  /** Page number (1-indexed) */
  page: number;
  /** Items per page */
  limit: number;
  /** Field to sort by */
  sortBy?: SortableFields;
  /** Sort direction */
  sortOrder?: "asc" | "desc";
}

/**
 * Paginated response
 * @invariant totalPages === Math.ceil(total / limit)
 * @invariant data.length <= limit
 * @invariant page >= 1 && page <= totalPages (when total > 0)
 */
export interface PaginatedResponse<T> {
  readonly data: readonly T[];
  readonly total: number;
  readonly page: number;
  readonly limit: number;
  readonly totalPages: number;
}

/**
 * Helper to create a paginated response with calculated totalPages
 */
export function createPaginatedResponse<T>(
  data: T[],
  total: number,
  page: number,
  limit: number
): PaginatedResponse<T> {
  if (limit <= 0) {
    throw new Error("limit must be positive");
  }
  if (page < 1) {
    throw new Error("page must be >= 1");
  }

  return {
    data,
    total,
    page,
    limit,
    totalPages: Math.ceil(total / limit) || 1,
  };
}

/**
 * Health check status values
 */
export type HealthState = "healthy" | "degraded" | "unhealthy";

/**
 * Health check response
 */
export interface HealthStatus {
  status: HealthState;
  timestamp: string;
  version?: string;
  checks?: Record<
    string,
    {
      status: HealthState;
      message?: string;
    }
  >;
}

// Export database enums
export * from "./enums";

// Export database entity types
export * from "./database.types";

// Export authentication types
export * from "./auth.types";

// Export widget types
export * from "./widget.types";

// Export WebSocket types
export * from "./websocket.types";

// Export agent provider types
export * from "./agent-provider.types";
