/**
 * Type definitions for SEO Research Service
 *
 * @module planning/seo/types/research
 * @description Core types for ResearchService integration with WebSearch/WebFetch MCP tools
 */

/**
 * Research query configuration
 */
export interface ResearchQuery {
  /** Search query text */
  query: string;

  /** Query type determines which MCP tool to use */
  type: 'serp' | 'content' | 'hybrid';

  /** Optional query parameters */
  options?: {
    /** Maximum number of results to return */
    maxResults?: number;

    /** Target domain for content fetch (WebFetch only) */
    targetUrl?: string;

    /** Enable deep crawling for content analysis */
    deepCrawl?: boolean;

    /** Custom cache TTL in seconds */
    cacheTtl?: number;

    /** Request priority for rate limiting queue */
    priority?: 'low' | 'normal' | 'high';
  };

  /** Correlation ID for tracking across pipeline */
  correlationId?: string;
}

/**
 * Normalized SERP result from WebSearch
 */
export interface SerpResult {
  /** Result title */
  title: string;

  /** Result URL */
  url: string;

  /** Meta description or snippet */
  description: string;

  /** Result position in SERP (1-indexed) */
  position: number;

  /** SERP features present (featured snippet, people also ask, etc.) */
  features?: string[];

  /** Raw result data from MCP tool */
  raw?: Record<string, unknown>;
}

/**
 * Normalized content result from WebFetch
 */
export interface ContentResult {
  /** Page URL */
  url: string;

  /** Page title */
  title: string;

  /** Extracted text content */
  content: string;

  /** Page metadata */
  metadata: {
    /** Word count */
    wordCount: number;

    /** Heading structure (H1, H2, H3 counts) */
    headings: {
      h1: number;
      h2: number;
      h3: number;
    };

    /** Internal link count */
    internalLinks: number;

    /** External link count */
    externalLinks: number;

    /** Image count */
    images: number;

    /** Schema markup types found */
    schema?: string[];
  };

  /** HTTP status code */
  statusCode: number;

  /** Fetch timestamp */
  fetchedAt: Date;
}

/**
 * Unified research result combining SERP and content data
 */
export interface ResearchResult {
  /** Original query */
  query: ResearchQuery;

  /** SERP results (if type is 'serp' or 'hybrid') */
  serpResults?: SerpResult[];

  /** Content results (if type is 'content' or 'hybrid') */
  contentResults?: ContentResult[];

  /** Result metadata */
  metadata: {
    /** Total results returned */
    resultCount: number;

    /** Execution time in milliseconds */
    executionTime: number;

    /** Whether result was served from cache */
    fromCache: boolean;

    /** Cache key used */
    cacheKey?: string;

    /** Rate limit status at time of request */
    rateLimitStatus?: {
      remaining: number;
      resetAt: Date;
    };
  };

  /** Timestamp when research was executed */
  timestamp: Date;
}

/**
 * Cache entry structure
 */
export interface CacheEntry<T = unknown> {
  /** Cache key */
  key: string;

  /** Cached data */
  data: T;

  /** Entry creation timestamp */
  createdAt: Date;

  /** Entry expiration timestamp */
  expiresAt: Date;

  /** Access count for cache analytics */
  accessCount: number;

  /** Last access timestamp */
  lastAccessedAt: Date;

  /** Entry metadata */
  metadata?: {
    /** Original query hash */
    queryHash?: string;

    /** Result type */
    resultType?: 'serp' | 'content' | 'hybrid';

    /** Result count */
    resultCount?: number;
  };
}

/**
 * Rate limit configuration
 */
export interface RateLimitConfig {
  /** Maximum requests allowed per time window */
  maxRequests: number;

  /** Time window in milliseconds */
  windowMs: number;

  /** Service identifier (websearch, webfetch) */
  service: 'websearch' | 'webfetch';

  /** Enable request queuing when limit reached */
  enableQueue?: boolean;

  /** Maximum queue size */
  maxQueueSize?: number;

  /** Backoff strategy when rate limited */
  backoffStrategy?: 'linear' | 'exponential';

  /** Initial backoff delay in milliseconds */
  backoffDelay?: number;

  /** Maximum backoff delay in milliseconds */
  maxBackoffDelay?: number;
}

/**
 * Rate limiter state
 */
export interface RateLimiterState {
  /** Current token count */
  tokens: number;

  /** Maximum tokens (bucket size) */
  maxTokens: number;

  /** Token refill rate (tokens per second) */
  refillRate: number;

  /** Last refill timestamp */
  lastRefill: Date;

  /** Queued requests */
  queue: QueuedRequest[];

  /** Total requests processed */
  totalRequests: number;

  /** Total requests throttled */
  throttledRequests: number;
}

/**
 * Queued request for rate limiting
 */
export interface QueuedRequest {
  /** Request ID */
  id: string;

  /** Request query */
  query: ResearchQuery;

  /** Queue entry timestamp */
  queuedAt: Date;

  /** Request priority */
  priority: 'low' | 'normal' | 'high';

  /** Retry count */
  retries: number;

  /** Maximum retry attempts */
  maxRetries: number;

  /** Promise resolver */
  resolve: (result: ResearchResult) => void;

  /** Promise rejecter */
  reject: (error: Error) => void;
}

/**
 * Research service error types
 */
export class ResearchError extends Error {
  constructor(
    message: string,
    public code: ResearchErrorCode,
    public details?: Record<string, unknown>
  ) {
    super(message);
    this.name = 'ResearchError';
  }
}

/**
 * Research error codes
 */
export enum ResearchErrorCode {
  /** Rate limit exceeded */
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',

  /** MCP tool unavailable */
  TOOL_UNAVAILABLE = 'TOOL_UNAVAILABLE',

  /** Invalid query parameters */
  INVALID_QUERY = 'INVALID_QUERY',

  /** Network/fetch error */
  FETCH_ERROR = 'FETCH_ERROR',

  /** Parse/normalization error */
  PARSE_ERROR = 'PARSE_ERROR',

  /** Cache operation error */
  CACHE_ERROR = 'CACHE_ERROR',

  /** Timeout error */
  TIMEOUT_ERROR = 'TIMEOUT_ERROR',

  /** Unknown error */
  UNKNOWN_ERROR = 'UNKNOWN_ERROR',
}

/**
 * Cache statistics for monitoring
 */
export interface CacheStats {
  /** Total cache hits */
  hits: number;

  /** Total cache misses */
  misses: number;

  /** Cache hit rate (0-1) */
  hitRate: number;

  /** Total entries in cache */
  totalEntries: number;

  /** Cache size in bytes */
  sizeBytes: number;

  /** Oldest entry age in seconds */
  oldestEntryAge?: number;

  /** Average access count per entry */
  avgAccessCount?: number;
}

/**
 * Rate limiter statistics for monitoring
 */
export interface RateLimiterStats {
  /** Current token count */
  currentTokens: number;

  /** Requests in current window */
  requestsInWindow: number;

  /** Queue length */
  queueLength: number;

  /** Total requests processed */
  totalRequests: number;

  /** Total throttled requests */
  throttledRequests: number;

  /** Throttle rate (0-1) */
  throttleRate: number;

  /** Average queue wait time in milliseconds */
  avgQueueWaitMs?: number;
}
