/**
 * SERP Pattern Analysis Type Definitions
 *
 * @module packages/seo-analysis/types/serp-analysis
 * @description Type definitions for SERP (Search Engine Results Page) pattern analysis
 * @version 1.0.0
 *
 * Provides comprehensive types for:
 * - SERP feature detection and analysis
 * - Ranking pattern identification
 * - Semantic clustering of results
 * - Content gap analysis
 * - Competitive positioning recommendations
 */

// ============================================================================
// CORE REQUEST/RESPONSE TYPES
// ============================================================================

/**
 * Configuration options for SERP analysis
 */
export interface SERPAnalysisOptions {
  /** Maximum results to analyze (default: 10) */
  maxResults?: number;

  /** Detect SERP features (snippets, PAQ, etc.) */
  detectFeatures?: boolean;

  /** Analyze ranking patterns and trends */
  analyzePatterns?: boolean;

  /** Extract semantic clusters from results */
  extractClusters?: boolean;

  /** Generate actionable recommendations */
  generateRecommendations?: boolean;
}

/**
 * Request to analyze SERP results for a target keyword
 */
export interface SERPAnalysisRequest {
  /** Target keyword to analyze */
  keyword: string;

  /** Geographic targeting (optional, e.g., "US", "UK", "CA") */
  location?: string;

  /** Language code (optional, e.g., "en", "es", "fr") */
  language?: string;

  /** Device type for SERP (desktop or mobile) */
  device?: 'desktop' | 'mobile';

  /** Optional list of competitor URLs to include in analysis */
  includeCompetitors?: string[];

  /** Analysis options and configuration */
  options?: SERPAnalysisOptions;
}

/**
 * Complete SERP analysis result
 */
export interface SERPAnalysisResult {
  /** Analyzed keyword */
  keyword: string;

  /** Analysis timestamp */
  analyzedAt: Date;

  /** SERP features detected in results */
  features: SERPFeatureAnalysis;

  /** Ranking patterns identified */
  rankings: RankingPatternAnalysis;

  /** Semantic clustering results */
  clusters: SemanticClusterAnalysis;

  /** Recommendations based on analysis */
  recommendations: SERPRecommendations;

  /** Analysis metadata and statistics */
  metadata: AnalysisMetadata;
}

// ============================================================================
// SERP FEATURES
// ============================================================================

/**
 * Featured snippet type variants
 */
export type FeaturedSnippetType = 'paragraph' | 'list' | 'table' | 'definition';

/**
 * Featured snippet metadata and content
 */
export interface FeaturedSnippet {
  /** Type of featured snippet */
  type: FeaturedSnippetType;

  /** Snippet content text */
  content: string;

  /** Source URL hosting the snippet */
  sourceUrl: string;

  /** Source domain */
  sourceDomain: string;

  /** Extracted structured data (if applicable) */
  extractedData?: FeaturedSnippetData;

  /** Position in SERP (always 0 for featured snippets) */
  position: 0;
}

/**
 * Structured data extracted from featured snippets
 */
export interface FeaturedSnippetData {
  /** List items (for list-type snippets) */
  listItems?: string[];

  /** Table headers (for table-type snippets) */
  tableHeaders?: string[];

  /** Table rows (for table-type snippets) */
  tableRows?: string[][];

  /** Definition (for definition-type snippets) */
  definition?: string;

  /** Item count (for list snippets) */
  itemCount?: number;
}

/**
 * People Also Ask (PAQ) section metadata
 */
export interface PeopleAlsoAsk {
  /** Questions in the PAQ section */
  questions: PAQQuestion[];

  /** Total count of questions available */
  totalCount: number;

  /** Whether more questions are available (pagination) */
  hasMoreQuestions: boolean;
}

/**
 * Individual question from People Also Ask
 */
export interface PAQQuestion {
  /** The question text */
  question: string;

  /** Answer to the question */
  answer: string;

  /** Source URL (if available) */
  sourceUrl?: string;

  /** Source domain */
  sourceDomain?: string;

  /** Ranking position of source in main results */
  sourcePosition?: number;
}

/**
 * Knowledge panel entity information
 */
export interface KnowledgePanel {
  /** Entity name displayed in panel */
  entityName: string;

  /** Entity type classification */
  entityType: string;

  /** Entity description */
  description: string;

  /** Entity attributes as key-value pairs */
  attributes: Record<string, string>;

  /** Entity images/logos */
  images?: string[];

  /** Related entities mentioned in panel */
  relatedEntities?: string[];

  /** Knowledge Graph ID (if available) */
  kgId?: string;
}

/**
 * Image pack/carousel results
 */
export interface ImagePack {
  /** Images in the pack */
  images: ImageResult[];

  /** Total image count (may be more than displayed) */
  totalCount?: number;
}

/**
 * Individual image result
 */
export interface ImageResult {
  /** Image URL */
  url: string;

  /** Alt text */
  alt: string;

  /** Source page URL */
  sourceUrl: string;

  /** Image title */
  title?: string;

  /** Image dimensions (if available) */
  dimensions?: {
    width: number;
    height: number;
  };
}

/**
 * Video carousel/pack results
 */
export interface VideoCarousel {
  /** Videos in the carousel */
  videos: VideoResult[];

  /** Total video count */
  totalCount?: number;
}

/**
 * Individual video result
 */
export interface VideoResult {
  /** Video title */
  title: string;

  /** Video page URL */
  url: string;

  /** Thumbnail image URL */
  thumbnail: string;

  /** Video platform */
  platform: 'youtube' | 'vimeo' | 'dailymotion' | 'other';

  /** Video duration (seconds, if available) */
  duration?: number;

  /** Upload date (if available) */
  uploadDate?: Date;

  /** Channel/source name */
  channel?: string;
}

/**
 * Local pack (Local 3-pack) results
 */
export interface LocalPack {
  /** Businesses in the local pack */
  businesses: LocalBusinessResult[];

  /** Total business count in area */
  totalCount?: number;

  /** Map region covered */
  mapRegion?: string;
}

/**
 * Individual local business result
 */
export interface LocalBusinessResult {
  /** Business name */
  name: string;

  /** Business address */
  address: string;

  /** Business phone (if available) */
  phone?: string;

  /** Business website */
  website?: string;

  /** Google Maps URL */
  mapsUrl?: string;

  /** Rating (0-5 stars) */
  rating?: number;

  /** Number of reviews */
  reviews?: number;

  /** Business hours status */
  status?: 'open' | 'closed' | 'closes-soon' | 'opens-soon';

  /** Distance from search location (if applicable) */
  distance?: string;
}

/**
 * Shopping results/product pack
 */
export interface ShoppingResults {
  /** Products in shopping results */
  products: ProductResult[];

  /** Total product count */
  totalCount?: number;

  /** Shopping platform */
  platform?: string;
}

/**
 * Individual product result
 */
export interface ProductResult {
  /** Product name */
  title: string;

  /** Product price */
  price?: string;

  /** Product rating */
  rating?: number;

  /** Number of reviews */
  reviews?: number;

  /** Retailer name */
  retailer: string;

  /** Product page URL */
  url: string;

  /** Product image URL */
  image?: string;

  /** Availability status */
  availability?: string;
}

/**
 * News box results
 */
export interface NewsBox {
  /** Articles in news results */
  articles: NewsArticle[];

  /** Total article count */
  totalCount?: number;
}

/**
 * Individual news article
 */
export interface NewsArticle {
  /** Article title */
  title: string;

  /** Article URL */
  url: string;

  /** News source/publication */
  source: string;

  /** Publish date */
  publishDate: Date;

  /** Article snippet */
  snippet?: string;

  /** Article image */
  image?: string;
}

/**
 * Complete SERP feature analysis
 */
export interface SERPFeatureAnalysis {
  /** Whether SERP has any special features */
  hasFeatures: boolean;

  /** Featured snippet (if present) */
  featuredSnippet?: FeaturedSnippet;

  /** People Also Ask section (if present) */
  peopleAlsoAsk?: PeopleAlsoAsk;

  /** Knowledge panel (if present) */
  knowledgePanel?: KnowledgePanel;

  /** Image pack/carousel (if present) */
  imagePack?: ImagePack;

  /** Video carousel (if present) */
  videoCarousel?: VideoCarousel;

  /** Local pack (if present) */
  localPack?: LocalPack;

  /** Shopping results (if present) */
  shoppingResults?: ShoppingResults;

  /** News box (if present) */
  newsBox?: NewsBox;

  /** Related searches shown at bottom */
  relatedSearches?: string[];

  /** Feature count summary */
  featureCount: number;

  /** Feature distribution */
  featureDistribution: Record<string, boolean>;
}

// ============================================================================
// RANKING PATTERNS
// ============================================================================

/**
 * Content type classification
 */
export type ContentType =
  | 'blog'
  | 'product'
  | 'guide'
  | 'news'
  | 'video'
  | 'forum'
  | 'landing-page'
  | 'resource'
  | 'tutorial'
  | 'tool'
  | 'directory'
  | 'other';

/**
 * Individual ranking result
 */
export interface RankingResult {
  /** Position in SERP (1-indexed) */
  position: number;

  /** Page URL */
  url: string;

  /** Domain/root domain */
  domain: string;

  /** Page title */
  title: string;

  /** Meta description */
  description: string;

  /** Estimated content type */
  contentType: ContentType;

  /** Estimated word count (if available) */
  estimatedWordCount?: number;

  /** Published date (if available) */
  publishedDate?: Date;

  /** Last modified date (if available) */
  lastModified?: Date;

  /** URL structure pattern */
  urlPattern?: string;

  /** Subdomain (if different from root) */
  subdomain?: string;
}

/**
 * Domain authority and ranking strength pattern
 */
export interface DomainAuthorityPattern {
  /** Count of high-authority domains (DA > 70) */
  highAuthority: number;

  /** Count of medium-authority domains (DA 40-70) */
  mediumAuthority: number;

  /** Count of low-authority domains (DA < 40) */
  lowAuthority: number;

  /** Domains with multiple positions in top 10 */
  dominantDomains: string[];

  /** Authority score of top result */
  topResultAuthority?: number;

  /** Authority requirement estimate */
  estimatedAuthorityRequired: 'low' | 'medium' | 'high';
}

/**
 * Content type distribution in rankings
 */
export interface ContentTypeDistribution {
  /** Type counts by content type */
  [key: string]: number | ContentType | undefined;

  /** Most common content type */
  mostCommon: ContentType;

  /** Content type diversity score (0-1) */
  diversityScore: number;
}

/**
 * Content metrics and patterns
 */
export interface ContentMetricsPattern {
  /** Average word count across top results */
  averageWordCount: number;

  /** Word count range [min, max] */
  wordCountRange: [number, number];

  /** Freshness importance assessment */
  freshnessImportance: 'critical' | 'high' | 'medium' | 'low';

  /** Percentage of results with multimedia */
  multimediaUsage: number;

  /** Average headings per page */
  avgHeadingCount?: number;

  /** Average images per page */
  avgImageCount?: number;

  /** Structured data usage rate */
  structuredDataUsage?: number;
}

/**
 * URL structure pattern analysis
 */
export interface URLStructurePattern {
  /** Common URL patterns found */
  commonPatterns: string[];

  /** Directory depth analysis */
  depthAnalysis: {
    /** Count of shallow URLs (1-2 levels) */
    shallow: number;

    /** Count of medium URLs (3-4 levels) */
    medium: number;

    /** Count of deep URLs (5+ levels) */
    deep: number;

    /** Average depth */
    average: number;
  };

  /** Common URL prefixes (e.g., "/blog/", "/guides/") */
  urlPrefixes: string[];

  /** Common URL slugs and structure patterns */
  slugPatterns: string[];
}

/**
 * Complete ranking pattern analysis
 */
export interface RankingPatternAnalysis {
  /** Top ranking results */
  topResults: RankingResult[];

  /** Domain authority patterns */
  domainAuthority: DomainAuthorityPattern;

  /** Content type distribution */
  contentTypes: ContentTypeDistribution;

  /** Content metrics patterns */
  contentMetrics: ContentMetricsPattern;

  /** URL structure patterns */
  urlStructure: URLStructurePattern;

  /** Pattern summary confidence score (0-1) */
  confidenceScore: number;
}

// ============================================================================
// SEMANTIC CLUSTERING
// ============================================================================

/**
 * Semantic cluster of related results
 */
export interface SemanticCluster {
  /** Unique cluster identifier */
  id: string;

  /** Cluster name/topic */
  name: string;

  /** Keywords associated with cluster */
  keywords: string[];

  /** Number of results in cluster */
  frequency: number;

  /** Related cluster IDs */
  relatedClusters: string[];

  /** Representative URLs from cluster */
  representativeUrls: string[];

  /** Cluster centroid (theme/topic center) */
  centroid?: string;

  /** Cluster size distribution */
  sizeDistribution: 'small' | 'medium' | 'large';
}

/**
 * Content gap opportunity
 */
export interface ContentGap {
  /** Topic/keyword for the gap */
  topic: string;

  /** Keywords missing from coverage */
  missingKeywords: string[];

  /** Opportunity level */
  opportunity: 'high' | 'medium' | 'low';

  /** Estimated search volume (if available) */
  estimatedSearchVolume?: number;

  /** Number of competitors covering this */
  competitorCoverage: number;

  /** Reasoning for gap identification */
  reasoning: string;

  /** Recommended content approach */
  recommendedApproach?: string;
}

/**
 * Topic coverage analysis
 */
export interface TopicCoverage {
  /** Total unique topics identified */
  totalTopics: number;

  /** Topics covered by top 3 results */
  coveredByTop3: string[];

  /** Topics covered by top 10 results */
  coveredByTop10: string[];

  /** Uncovered topics/gaps */
  uncovered: string[];

  /** Coverage percentage */
  coveragePercentage: number;
}

/**
 * Complete semantic clustering analysis
 */
export interface SemanticClusterAnalysis {
  /** Semantic clusters identified */
  clusters: SemanticCluster[];

  /** Keyword variations found */
  keywordVariations: string[];

  /** Content gaps identified */
  contentGaps: ContentGap[];

  /** Topic coverage analysis */
  topicCoverage: TopicCoverage;

  /** Cluster count summary */
  clusterCount: number;

  /** Cluster quality score (0-1) */
  qualityScore: number;
}

// ============================================================================
// RECOMMENDATIONS
// ============================================================================

/**
 * Featured snippet targeting recommendation
 */
export interface FeatureTargetingRecommendation {
  /** SERP feature type */
  feature: 'featured-snippet' | 'paq' | 'knowledge-panel' | 'image-pack' | 'video' | 'local';

  /** Implementation priority */
  priority: 'high' | 'medium' | 'low';

  /** Current status of this feature */
  currentStatus: 'not-present' | 'competitor-owned' | 'achievable' | 'already-owned';

  /** Specific action items to implement */
  actionItems: string[];

  /** Estimated impact on CTR/traffic */
  estimatedImpact: string;

  /** Implementation difficulty */
  difficulty: 'easy' | 'medium' | 'hard';

  /** Estimated timeframe for implementation */
  timeframe?: string;
}

/**
 * Content structure recommendation
 */
export interface ContentStructureRecommendation {
  /** Specific recommendation */
  recommendation: string;

  /** Why this is recommended */
  reasoning: string;

  /** Examples from top competitors */
  examples: string[];

  /** Implementation priority */
  priority: 'high' | 'medium' | 'low';

  /** Content elements affected */
  contentElements?: string[];
}

/**
 * Keyword strategy recommendation
 */
export interface KeywordStrategyRecommendation {
  /** Target keyword */
  keyword: string;

  /** Opportunity level for this keyword */
  opportunity: 'high' | 'medium' | 'low';

  /** Estimated monthly search volume */
  searchVolume?: number;

  /** Current competition level */
  competition: 'low' | 'medium' | 'high';

  /** Why target this keyword */
  rationale: string;

  /** Content approach for keyword */
  contentApproach?: string;

  /** Estimated ranking difficulty */
  difficulty?: 'easy' | 'medium' | 'hard';
}

/**
 * Competitive positioning recommendation
 */
export interface CompetitivePositioningRecommendation {
  /** Competitor domain */
  competitor: string;

  /** Competitor's key strengths */
  strengths: string[];

  /** Competitor's weaknesses/gaps */
  weaknesses: string[];

  /** Opportunities to differentiate */
  differentiationOpportunities: string[];

  /** Competitive advantage areas */
  advantageAreas?: string[];
}

/**
 * Complete recommendations package
 */
export interface SERPRecommendations {
  /** SERP feature targeting recommendations */
  featureTargeting: FeatureTargetingRecommendation[];

  /** Content structure recommendations */
  contentStructure: ContentStructureRecommendation[];

  /** Keyword strategy recommendations */
  keywordStrategy: KeywordStrategyRecommendation[];

  /** Competitive positioning recommendations */
  competitivePositioning: CompetitivePositioningRecommendation[];

  /** Quick wins (easy, high-impact actions) */
  quickWins?: string[];

  /** Long-term strategy recommendations */
  longTermStrategy?: string[];

  /** Priority rank of all recommendations */
  priorityOrder: string[];
}

// ============================================================================
// METADATA & CONFIGURATION
// ============================================================================

/**
 * SERP analysis provider
 */
export type SERPProvider = 'google' | 'serpapi' | 'firecrawl' | 'valuserp' | 'other';

/**
 * Analysis metadata and statistics
 */
export interface AnalysisMetadata {
  /** Schema version */
  version: string;

  /** SERP data provider used */
  apiProvider: SERPProvider;

  /** Number of results analyzed */
  resultsCount: number;

  /** Total processing time (milliseconds) */
  processingTime: number;

  /** Overall confidence score (0.0-1.0) */
  confidence: number;

  /** Analysis completion status */
  status: 'completed' | 'partial' | 'failed';

  /** Errors encountered during analysis (if any) */
  errors?: string[];

  /** Warnings (non-critical issues) */
  warnings?: string[];

  /** Request parameters used */
  requestMetadata: {
    keyword: string;
    location?: string;
    language?: string;
    device: 'desktop' | 'mobile';
  };
}

/**
 * SERP Pattern Analyst configuration
 */
export interface SERPPatternAnalystConfig {
  /** API key for SERP provider (optional, uses env var if not provided) */
  apiKey?: string;

  /** Selected SERP data provider */
  apiProvider: SERPProvider;

  /** Rate limiting configuration */
  rateLimit: {
    /** Requests allowed per minute */
    requestsPerMinute: number;

    /** Requests allowed per day */
    requestsPerDay: number;

    /** Backoff strategy */
    backoffStrategy?: 'exponential' | 'linear';
  };

  /** Caching configuration */
  cache: {
    /** Enable caching of results */
    enabled: boolean;

    /** Cache TTL in seconds */
    ttl: number;

    /** Cache backend */
    backend?: 'memory' | 'redis' | 'filesystem';
  };

  /** Default analysis options */
  defaults: SERPAnalysisOptions;

  /** Timeout for individual requests (milliseconds) */
  requestTimeoutMs?: number;

  /** Maximum retries on failure */
  maxRetries?: number;
}

// ============================================================================
// ERROR TYPES
// ============================================================================

/**
 * SERP analysis error codes
 */
export enum SERPAnalysisErrorCode {
  INVALID_KEYWORD = 'INVALID_KEYWORD',
  API_ERROR = 'API_ERROR',
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
  REQUEST_TIMEOUT = 'REQUEST_TIMEOUT',
  INVALID_LOCATION = 'INVALID_LOCATION',
  INVALID_LANGUAGE = 'INVALID_LANGUAGE',
  ANALYSIS_FAILED = 'ANALYSIS_FAILED',
  INSUFFICIENT_DATA = 'INSUFFICIENT_DATA',
  CACHE_ERROR = 'CACHE_ERROR',
}

/**
 * SERP analysis error with detailed context
 */
export class SERPAnalysisError extends Error {
  /**
   * Create a SERP analysis error
   * @param code Error code
   * @param message Error message
   * @param details Additional error details
   */
  constructor(
    public readonly code: SERPAnalysisErrorCode,
    message: string,
    public readonly details?: Record<string, unknown>
  ) {
    super(message);
    this.name = 'SERPAnalysisError';
    Object.setPrototypeOf(this, SERPAnalysisError.prototype);
  }
}

// ============================================================================
// TYPE GUARDS
// ============================================================================

/**
 * Type guard: Check if result has featured snippet
 */
export function hasFeaturedSnippet(
  features: SERPFeatureAnalysis
): features is SERPFeatureAnalysis & { featuredSnippet: FeaturedSnippet } {
  return features.featuredSnippet !== undefined;
}

/**
 * Type guard: Check if result has People Also Ask
 */
export function hasPeopleAlsoAsk(
  features: SERPFeatureAnalysis
): features is SERPFeatureAnalysis & { peopleAlsoAsk: PeopleAlsoAsk } {
  return features.peopleAlsoAsk !== undefined;
}

/**
 * Type guard: Check if result has knowledge panel
 */
export function hasKnowledgePanel(
  features: SERPFeatureAnalysis
): features is SERPFeatureAnalysis & { knowledgePanel: KnowledgePanel } {
  return features.knowledgePanel !== undefined;
}

/**
 * Type guard: Check if featured snippet is of specific type
 */
export function isFeaturedSnippetType(
  snippet: FeaturedSnippet,
  type: FeaturedSnippetType
): snippet is FeaturedSnippet & { type: typeof type } {
  return snippet.type === type;
}

/**
 * Type guard: Check if content gap is high opportunity
 */
export function isHighOpportunityGap(gap: ContentGap): boolean {
  return gap.opportunity === 'high';
}

/**
 * Type guard: Check if recommendation is high priority
 */
export function isHighPriorityRecommendation(
  rec: FeatureTargetingRecommendation | ContentStructureRecommendation
): boolean {
  return rec.priority === 'high';
}

/**
 * Type guard: Check if cluster is large
 */
export function isLargeCluster(cluster: SemanticCluster, threshold: number = 5): boolean {
  return cluster.frequency >= threshold;
}

/**
 * Type guard: Validate SERP analysis result completeness
 */
export function isCompleteAnalysis(result: SERPAnalysisResult): boolean {
  return (
    result.features !== undefined &&
    result.rankings !== undefined &&
    result.clusters !== undefined &&
    result.recommendations !== undefined &&
    result.metadata.status === 'completed'
  );
}

/**
 * Type guard: Check if keyword is highly competitive
 */
export function isHighlyCompetitiveKeyword(
  rec: KeywordStrategyRecommendation
): rec is KeywordStrategyRecommendation & { competition: 'high' } {
  return rec.competition === 'high';
}

// ============================================================================
// UTILITY TYPES
// ============================================================================

/**
 * Readonly version of SERP analysis result for immutable data
 */
export type ReadonlySERPAnalysisResult = Readonly<SERPAnalysisResult>;

/**
 * Discriminated union for SERP feature types
 */
export type SERPFeature =
  | { readonly type: 'featured-snippet'; readonly data: FeaturedSnippet }
  | { readonly type: 'paq'; readonly data: PeopleAlsoAsk }
  | { readonly type: 'knowledge-panel'; readonly data: KnowledgePanel }
  | { readonly type: 'image-pack'; readonly data: ImagePack }
  | { readonly type: 'video-carousel'; readonly data: VideoCarousel }
  | { readonly type: 'local-pack'; readonly data: LocalPack }
  | { readonly type: 'shopping'; readonly data: ShoppingResults }
  | { readonly type: 'news'; readonly data: NewsBox };

/**
 * Recommendation type union
 */
export type RecommendationType =
  | FeatureTargetingRecommendation
  | ContentStructureRecommendation
  | KeywordStrategyRecommendation
  | CompetitivePositioningRecommendation;

/**
 * Pattern type union
 */
export type AnalysisPattern =
  | DomainAuthorityPattern
  | ContentTypeDistribution
  | ContentMetricsPattern
  | URLStructurePattern
  | SemanticCluster;
