/**
 * SERP Pattern Analysis Type Definitions
 *
 * @module @claude-flow-novice/seo-analysis/types/serp-analysis
 * @description Type definitions for SERP pattern analysis (Phase 2 Sprint 2)
 * @version 1.0.0
 *
 * Provides comprehensive types for:
 * - SERP feature detection (featured snippets, PAA, knowledge panels)
 * - Ranking pattern analysis across top 10 results
 * - Semantic clustering and topic extraction
 * - Actionable recommendation generation
 */

// ============================================================================
// CORE ANALYSIS TYPES
// ============================================================================

/**
 * Configuration for SERP pattern analysis
 */
export interface SERPAnalysisConfig {
  /** Target keyword to analyze */
  keyword: string;

  /** Google Custom Search API key (optional, uses env var if not provided) */
  googleApiKey?: string;

  /** Google Custom Search Engine ID (optional, uses env var if not provided) */
  googleSearchEngineId?: string;

  /** SerpAPI key as alternative to Google Custom Search */
  serpApiKey?: string;

  /** Maximum number of results to analyze (default: 10) */
  maxResults?: number;

  /** Enable detailed content scraping for semantic analysis */
  enableContentScraping?: boolean;

  /** Timeout for individual requests (ms, default: 30000) */
  requestTimeoutMs?: number;

  /** Enable verbose logging */
  verbose?: boolean;

  /** Rate limit delay between requests (ms, default: 1000) */
  rateLimitMs?: number;
}

/**
 * SERP feature types that can be detected
 */
export enum SERPFeatureType {
  FEATURED_SNIPPET = 'featured_snippet',
  PEOPLE_ALSO_ASK = 'people_also_ask',
  KNOWLEDGE_PANEL = 'knowledge_panel',
  IMAGE_PACK = 'image_pack',
  VIDEO_CAROUSEL = 'video_carousel',
  LOCAL_PACK = 'local_pack',
  SHOPPING_RESULTS = 'shopping_results',
  RELATED_SEARCHES = 'related_searches',
  TOP_STORIES = 'top_stories',
  SITE_LINKS = 'site_links',
  TWITTER_CAROUSEL = 'twitter_carousel',
  RECIPES = 'recipes',
  FLIGHTS = 'flights',
  HOTELS = 'hotels',
  JOBS = 'jobs',
  EVENTS = 'events',
}

/**
 * Featured snippet subtypes
 */
export enum FeaturedSnippetType {
  PARAGRAPH = 'paragraph',
  LIST = 'list',
  TABLE = 'table',
  VIDEO = 'video',
}

/**
 * Detected SERP feature with metadata
 */
export interface SERPFeature {
  /** Feature type */
  type: SERPFeatureType;

  /** Featured snippet subtype (if applicable) */
  snippetType?: FeaturedSnippetType;

  /** Position in SERP (0-based) */
  position: number;

  /** Domain owning the feature (if applicable) */
  domain?: string;

  /** Full URL owning the feature */
  url?: string;

  /** Feature content/text */
  content?: string;

  /** Feature title (for knowledge panels, etc.) */
  title?: string;

  /** Related questions (for PAA boxes) */
  questions?: string[];

  /** Related searches (for related searches box) */
  relatedSearches?: string[];

  /** Confidence score for detection (0.0-1.0) */
  confidence: number;

  /** Additional metadata */
  metadata?: Record<string, unknown>;
}

/**
 * Content type classification
 */
export enum ContentType {
  BLOG = 'blog',
  PRODUCT = 'product',
  GUIDE = 'guide',
  NEWS = 'news',
  VIDEO = 'video',
  LANDING_PAGE = 'landing_page',
  FORUM = 'forum',
  DOCUMENTATION = 'documentation',
  ECOMMERCE = 'ecommerce',
  SOCIAL = 'social',
  OTHER = 'other',
}

/**
 * Freshness signal types
 */
export enum FreshnessSignal {
  DATE_IN_TITLE = 'date_in_title',
  DATE_IN_URL = 'date_in_url',
  RECENT_PUBLICATION = 'recent_publication',
  FREQUENT_UPDATES = 'frequent_updates',
  NEWS_ARTICLE = 'news_article',
  NONE = 'none',
}

/**
 * Individual search result data
 */
export interface SearchResult {
  /** Result position (1-10+) */
  position: number;

  /** Page title */
  title: string;

  /** Page URL */
  url: string;

  /** Domain name */
  domain: string;

  /** Meta description or snippet */
  snippet: string;

  /** Estimated domain authority (if available) */
  domainAuthority?: number;

  /** Detected content type */
  contentType: ContentType;

  /** Word count (if content scraped) */
  wordCount?: number;

  /** Title length in characters */
  titleLength: number;

  /** Meta description length */
  snippetLength: number;

  /** Detected freshness signals */
  freshnessSignals: FreshnessSignal[];

  /** URL structure pattern */
  urlPattern: string;

  /** Extracted headings (if content scraped) */
  headings?: {
    h1: string[];
    h2: string[];
    h3: string[];
  };

  /** Detected schema types */
  schemaTypes?: string[];

  /** Site links present */
  hasSiteLinks: boolean;

  /** Rich snippet features */
  richSnippetFeatures: string[];
}

/**
 * Ranking pattern extracted from top results
 */
export interface RankingPattern {
  /** Pattern type identifier */
  patternType: string;

  /** Pattern description */
  description: string;

  /** Prevalence across top results (0.0-1.0) */
  prevalence: number;

  /** Positions where pattern appears */
  positions: number[];

  /** Example results demonstrating pattern */
  examples: {
    position: number;
    url: string;
    title: string;
  }[];

  /** Pattern insights */
  insights: string[];

  /** Confidence score (0.0-1.0) */
  confidence: number;
}

/**
 * Domain authority pattern
 */
export interface DomainAuthorityPattern {
  /** Average domain authority in top 10 */
  averageDA: number;

  /** Minimum DA in top 10 */
  minDA: number;

  /** Maximum DA in top 10 */
  maxDA: number;

  /** Standard deviation */
  standardDeviation: number;

  /** Authority distribution */
  distribution: {
    high: number; // 70-100
    medium: number; // 40-69
    low: number; // 0-39
  };

  /** Insight on required authority */
  insight: string;
}

/**
 * Content length pattern
 */
export interface ContentLengthPattern {
  /** Average word count */
  averageWordCount: number;

  /** Minimum word count */
  minWordCount: number;

  /** Maximum word count */
  maxWordCount: number;

  /** Standard deviation */
  standardDeviation: number;

  /** Recommended range */
  recommendedRange: {
    min: number;
    max: number;
  };

  /** Insight on content length */
  insight: string;
}

/**
 * Title and meta pattern
 */
export interface TitleMetaPattern {
  /** Average title length */
  avgTitleLength: number;

  /** Title length range */
  titleLengthRange: {
    min: number;
    max: number;
  };

  /** Average meta description length */
  avgMetaLength: number;

  /** Meta length range */
  metaLengthRange: {
    min: number;
    max: number;
  };

  /** Common title patterns */
  commonTitlePatterns: string[];

  /** Common title structures */
  titleStructures: {
    pattern: string;
    count: number;
    examples: string[];
  }[];

  /** Keyword placement analysis */
  keywordPlacement: {
    inTitle: number; // Percentage
    atTitleStart: number; // Percentage
    inMeta: number; // Percentage
  };

  /** Insights */
  insights: string[];
}

/**
 * URL structure pattern
 */
export interface URLStructurePattern {
  /** Common URL patterns */
  patterns: {
    pattern: string;
    count: number;
    examples: string[];
  }[];

  /** Average URL length */
  avgUrlLength: number;

  /** URL component analysis */
  components: {
    hasKeyword: number; // Percentage
    pathDepth: number; // Average
    hasHyphens: number; // Percentage
    hasNumbers: number; // Percentage
    hasCategory: number; // Percentage
  };

  /** Insights */
  insights: string[];
}

/**
 * Semantic cluster of related topics
 */
export interface SemanticCluster {
  /** Cluster identifier */
  clusterId: string;

  /** Main topic/theme */
  mainTopic: string;

  /** Related keywords and phrases */
  keywords: string[];

  /** Topic prevalence across results (0.0-1.0) */
  prevalence: number;

  /** Positions where topic appears */
  positions: number[];

  /** Subtopics within cluster */
  subtopics: string[];

  /** Related entities (people, places, concepts) */
  entities: string[];

  /** Content coverage score (0.0-1.0) */
  coverageScore: number;

  /** Example content demonstrating cluster */
  examples: {
    position: number;
    url: string;
    snippet: string;
  }[];
}

/**
 * Content gap identified through SERP analysis
 */
export interface ContentGap {
  /** Gap type */
  gapType: 'missing_topic' | 'insufficient_depth' | 'outdated_content' | 'format_mismatch';

  /** Topic or angle missing */
  topic: string;

  /** Opportunity score (0.0-1.0) */
  opportunityScore: number;

  /** Current SERP coverage */
  currentCoverage: number;

  /** Recommended content type */
  recommendedContentType: ContentType;

  /** Reasoning */
  reasoning: string;

  /** Priority */
  priority: 'high' | 'medium' | 'low';
}

/**
 * Recommendation type
 */
export enum RecommendationType {
  SERP_FEATURE = 'serp_feature',
  CONTENT_STRUCTURE = 'content_structure',
  KEYWORD_VARIATION = 'keyword_variation',
  COMPETITIVE_POSITIONING = 'competitive_positioning',
  TECHNICAL_SEO = 'technical_seo',
  CONTENT_STRATEGY = 'content_strategy',
}

/**
 * Actionable recommendation
 */
export interface Recommendation {
  /** Recommendation type */
  type: RecommendationType;

  /** Recommendation title */
  title: string;

  /** Detailed description */
  description: string;

  /** Expected impact (high, medium, low) */
  impact: 'high' | 'medium' | 'low';

  /** Implementation effort (high, medium, low) */
  effort: 'high' | 'medium' | 'low';

  /** Priority score (0.0-1.0) */
  priority: number;

  /** Supporting data/evidence */
  evidence: string[];

  /** Actionable steps */
  actionSteps: string[];

  /** Related SERP features or patterns */
  relatedFeatures?: string[];
}

/**
 * Complete SERP analysis result
 */
export interface SERPAnalysisResult {
  /** Analyzed keyword */
  keyword: string;

  /** Analysis timestamp */
  analyzedAt: Date;

  /** Total time for analysis (ms) */
  totalTimeMs: number;

  /** Search results analyzed */
  results: SearchResult[];

  /** Detected SERP features */
  features: SERPFeature[];

  /** Ranking patterns */
  rankingPatterns: {
    domainAuthority: DomainAuthorityPattern;
    contentLength: ContentLengthPattern;
    titleMeta: TitleMetaPattern;
    urlStructure: URLStructurePattern;
    contentTypes: {
      type: ContentType;
      count: number;
      positions: number[];
    }[];
    freshnessSignals: {
      signal: FreshnessSignal;
      count: number;
      positions: number[];
    }[];
  };

  /** Semantic clusters */
  semanticClusters: SemanticCluster[];

  /** Content gaps */
  contentGaps: ContentGap[];

  /** Recommendations */
  recommendations: Recommendation[];

  /** Overall analysis confidence (0.0-1.0) */
  confidence: number;

  /** Warnings encountered */
  warnings: string[];

  /** Metadata */
  metadata: {
    apiProvider: 'google' | 'serpapi' | 'scraping';
    totalResults: number;
    cacheHit: boolean;
  };
}

// ============================================================================
// ERROR HANDLING
// ============================================================================

/**
 * SERP analysis error codes
 */
export enum SERPAnalysisErrorCode {
  INVALID_KEYWORD = 'INVALID_KEYWORD',
  INVALID_CONFIG = 'INVALID_CONFIG',
  API_KEY_MISSING = 'API_KEY_MISSING',
  API_REQUEST_FAILED = 'API_REQUEST_FAILED',
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
  TIMEOUT = 'TIMEOUT',
  PARSE_ERROR = 'PARSE_ERROR',
  INSUFFICIENT_DATA = 'INSUFFICIENT_DATA',
  NETWORK_ERROR = 'NETWORK_ERROR',
}

/**
 * SERP analysis error
 */
export class SERPAnalysisError extends Error {
  constructor(
    public code: SERPAnalysisErrorCode,
    message: string,
    public details?: Record<string, unknown>
  ) {
    super(message);
    this.name = 'SERPAnalysisError';
    Object.setPrototypeOf(this, SERPAnalysisError.prototype);
  }
}

// ============================================================================
// API RESPONSE TYPES
// ============================================================================

/**
 * Google Custom Search API response
 */
export interface GoogleSearchResponse {
  kind: string;
  items?: GoogleSearchItem[];
  searchInformation?: {
    totalResults: string;
    searchTime: number;
  };
  error?: {
    code: number;
    message: string;
  };
}

/**
 * Google Custom Search result item
 */
export interface GoogleSearchItem {
  title: string;
  link: string;
  snippet: string;
  displayLink: string;
  htmlSnippet?: string;
  pagemap?: {
    metatags?: Array<Record<string, string>>;
    cse_thumbnail?: Array<{ src: string }>;
    cse_image?: Array<{ src: string }>;
  };
}

/**
 * SerpAPI response
 */
export interface SerpAPIResponse {
  search_metadata?: {
    status: string;
    created_at: string;
    processed_at: string;
    total_time_taken: number;
  };
  search_parameters?: {
    q: string;
    engine: string;
  };
  organic_results?: SerpAPIOrganicResult[];
  answer_box?: Record<string, unknown>;
  knowledge_graph?: Record<string, unknown>;
  related_questions?: Array<{ question: string; snippet: string }>;
  related_searches?: Array<{ query: string }>;
  error?: string;
}

/**
 * SerpAPI organic result
 */
export interface SerpAPIOrganicResult {
  position: number;
  title: string;
  link: string;
  snippet: string;
  displayed_link?: string;
  rich_snippet?: Record<string, unknown>;
  sitelinks?: Array<{ title: string; link: string }>;
}

// ============================================================================
// UTILITY TYPES
// ============================================================================

/**
 * Type guard for successful Google search response
 */
export function isSuccessfulGoogleSearch(
  response: GoogleSearchResponse
): response is Required<GoogleSearchResponse> & { items: GoogleSearchItem[] } {
  return !response.error && Array.isArray(response.items) && response.items.length > 0;
}

/**
 * Type guard for successful SerpAPI response
 */
export function isSuccessfulSerpAPISearch(
  response: SerpAPIResponse
): response is Required<SerpAPIResponse> & { organic_results: SerpAPIOrganicResult[] } {
  return (
    !response.error &&
    Array.isArray(response.organic_results) &&
    response.organic_results.length > 0
  );
}

/**
 * Cache entry for SERP data
 */
export interface SERPCacheEntry {
  keyword: string;
  result: SERPAnalysisResult;
  cachedAt: Date;
  expiresAt: Date;
}

/**
 * Pattern extraction configuration
 */
export interface PatternExtractionConfig {
  /** Minimum instances required to establish pattern */
  minInstances: number;

  /** Minimum confidence threshold (0.0-1.0) */
  minConfidence: number;

  /** Enable fuzzy matching for pattern detection */
  fuzzyMatching: boolean;

  /** Similarity threshold for fuzzy matching (0.0-1.0) */
  similarityThreshold: number;
}
