// Import types we need to extend
import type { JobOptions, QueueStats } from '@stock-bot/types';

// Re-export handler and queue types from shared types package
export type {
  HandlerConfig,
  HandlerConfigWithSchedule,
  JobHandler,
  ScheduledJob,
  TypedJobHandler,
  JobData,
  JobOptions,
  QueueWorkerConfig,
  QueueStats,
} from '@stock-bot/types';

export interface ProcessOptions {
  totalDelayHours: number;
  batchSize?: number;
  priority?: number;
  useBatching?: boolean;
  retries?: number;
  ttl?: number;
  removeOnComplete?: number;
  removeOnFail?: number;
  // Job routing information
  handler?: string;
  operation?: string;
}

export interface BatchResult {
  jobsCreated: number;
  mode: 'direct' | 'batch';
  totalItems: number;
  batchesCreated?: number;
  duration: number;
}

// New improved types for the refactored architecture
export interface RedisConfig {
  host: string;
  port: number;
  password?: string;
  db?: number;
}

// Extended job options specific to this queue implementation
export interface ExtendedJobOptions extends JobOptions {
  repeat?: {
    pattern?: string;
    key?: string;
    limit?: number;
    every?: number;
    immediately?: boolean;
  };
}

export interface QueueOptions {
  defaultJobOptions?: ExtendedJobOptions;
  workers?: number;
  concurrency?: number;
  enableMetrics?: boolean;
  enableDLQ?: boolean;
  enableRateLimit?: boolean;
  rateLimitRules?: RateLimitRule[]; // Queue-specific rate limit rules
  handlerRegistry?: any; // HandlerRegistry from @stock-bot/handler-registry
}

export interface QueueManagerConfig {
  redis: RedisConfig;
  defaultQueueOptions?: QueueOptions;
  enableScheduledJobs?: boolean;
  globalRateLimit?: RateLimitConfig;
  rateLimitRules?: RateLimitRule[]; // Global rate limit rules
  serviceName?: string; // For service discovery and namespacing
  autoDiscoverHandlers?: boolean; // Auto-discover queue routes from handler registry
}

// Queue-specific stats that extend the base types
export interface GlobalStats {
  queues: Record<string, QueueStats>;
  totalJobs: number;
  totalWorkers: number;
  uptime: number;
}

// Legacy type for backward compatibility
export interface QueueConfig extends QueueManagerConfig {
  queueName?: string;
  workers?: number;
  concurrency?: number;
  handlers?: HandlerInitializer[];
  dlqConfig?: DLQConfig;
  enableMetrics?: boolean;
}

// Extended batch job data for queue implementation
export interface BatchJobData {
  payloadKey: string;
  batchIndex: number;
  totalBatches: number;
  itemCount: number;
  totalDelayHours: number; // Total time to distribute all batches
}

export interface HandlerInitializer {
  (): void | Promise<void>;
}

// Rate limiting types
export interface RateLimitConfig {
  points: number;
  duration: number;
  blockDuration?: number;
}

export interface RateLimitRule {
  level: 'global' | 'queue' | 'handler' | 'operation';
  queueName?: string; // For queue-level limits
  handler?: string; // For handler-level limits
  operation?: string; // For operation-level limits (most specific)
  config: RateLimitConfig;
}

// DLQ types
export interface DLQConfig {
  maxRetries?: number;
  retryDelay?: number;
  alertThreshold?: number;
  cleanupAge?: number;
}

export interface DLQJobInfo {
  id: string;
  name: string;
  failedReason: string;
  attemptsMade: number;
  timestamp: number;
  data: unknown;
}

export interface ScheduleConfig {
  pattern: string;
  jobName: string;
  data?: unknown;
  options?: ExtendedJobOptions;
}

// Smart Queue Types
export interface SmartQueueConfig extends QueueManagerConfig {
  /** Name of the current service */
  serviceName: string;
  /** Whether to auto-discover handlers from registry */
  autoDiscoverHandlers?: boolean;
  /** Custom service registry (defaults to built-in) */
  serviceRegistry?: Record<string, any>;
}

export interface QueueRoute {
  /** Full queue name (now just the handler name, e.g., 'ceo') */
  fullName: string;
  /** Service that owns this queue */
  service: string;
  /** Handler name */
  handler: string;
  /** Redis DB number */
  db: number;
  /** Available operations */
  operations?: string[];
}
