/**
 * SERP Feature Detection Service
 * Detects and tracks SERP features for keywords including featured snippets, PAA, and AI Overviews
 */

import { PrismaClient } from '@prisma/client';
import { ComplianceService } from '../../compliance';

const prisma = new PrismaClient();

// SERP Feature Types
export type SERPFeatureType =
  | 'snippet'      // Featured snippet (position 0)
  | 'paa'          // People Also Ask
  | 'ai_overview'  // AI Overview (Google SGE)
  | 'local_pack'   // Local 3-pack
  | 'knowledge_panel'
  | 'image_pack'
  | 'video_carousel';

// Detection result for a single feature
export interface FeatureDetectionResult {
  featureType: SERPFeatureType;
  detected: boolean;
  weOwnIt: boolean;
  position?: number;
  contentSnippet?: string;
  questions?: string[];  // For PAA
  citationContext?: string;  // For AI Overview
}

// Full SERP analysis for a keyword
export interface SERPAnalysisResult {
  keyword: string;
  ourPosition?: number;
  features: FeatureDetectionResult[];
  analyzedAt: string;
}

// Capture tracking
export interface CaptureReport {
  siteId: string;
  period: { start: Date; end: Date };
  snippetsCaptured: number;
  snippetsLost: number;
  paaCaptures: number;
  aiOverviewMentions: number;
  totalFeaturesTracked: number;
}

/**
 * SERP Feature Service
 * Detects, tracks, and reports on SERP feature captures
 */
export class SERPFeatureService {
  private mcpUrl: string;
  private siteId?: string;

  constructor(siteId?: string) {
    this.mcpUrl = process.env.MCP_HTTP_URL || 'http://127.0.0.1:3001/rpc';
    this.siteId = siteId;
  }

  /**
   * Detect featured snippet presence for a keyword
   */
  async detectFeaturedSnippet(keyword: string): Promise<FeatureDetectionResult> {
    // In production, this would call a SERP API like DataForSEO, SerpAPI, etc.
    // For now, we simulate detection based on keyword patterns

    const result: FeatureDetectionResult = {
      featureType: 'snippet',
      detected: false,
      weOwnIt: false,
    };

    try {
      // Check if keyword is likely to have a featured snippet
      const snippetTriggers = [
        'what is', 'what are', 'how to', 'how do', 'why', 'when',
        'best', 'top', 'steps to', 'guide to', 'definition', 'meaning'
      ];

      const keywordLower = keyword.toLowerCase();
      const hasSnippetPotential = snippetTriggers.some(trigger =>
        keywordLower.includes(trigger)
      );

      if (hasSnippetPotential) {
        result.detected = true;

        // Check if we own it (would require actual SERP data)
        const existingCapture = await prisma.sERPFeature.findFirst({
          where: {
            keyword,
            featureType: 'snippet',
            captured: true,
          },
        });

        result.weOwnIt = !!existingCapture;
        result.position = result.weOwnIt ? 0 : undefined;
      }

      await ComplianceService.log('AGENT', 'SERP_SNIPPET_CHECK', 'SERPFeatureService', {
        keyword,
        detected: result.detected,
        weOwnIt: result.weOwnIt,
      });

    } catch (error) {
      console.error('[SERPFeatureService] Featured snippet detection error:', error);
    }

    return result;
  }

  /**
   * Detect People Also Ask questions for a keyword
   */
  async detectPAAQuestions(keyword: string): Promise<FeatureDetectionResult> {
    const result: FeatureDetectionResult = {
      featureType: 'paa',
      detected: false,
      weOwnIt: false,
      questions: [],
    };

    try {
      // Generate likely PAA questions based on keyword
      const baseTopic = keyword
        .toLowerCase()
        .replace(/^(what is|how to|best|top)\s+/i, '')
        .trim();

      const generatedQuestions = [
        `What is ${baseTopic}?`,
        `How does ${baseTopic} work?`,
        `Why is ${baseTopic} important?`,
        `What are the benefits of ${baseTopic}?`,
        `How do you use ${baseTopic}?`,
      ];

      result.detected = true;
      result.questions = generatedQuestions;

      // Check if we appear in any PAA for this keyword
      const existingCapture = await prisma.sERPFeature.findFirst({
        where: {
          keyword,
          featureType: 'paa',
          captured: true,
        },
      });

      result.weOwnIt = !!existingCapture;

      await ComplianceService.log('AGENT', 'SERP_PAA_CHECK', 'SERPFeatureService', {
        keyword,
        questionsFound: result.questions?.length || 0,
        weOwnIt: result.weOwnIt,
      });

    } catch (error) {
      console.error('[SERPFeatureService] PAA detection error:', error);
    }

    return result;
  }

  /**
   * Detect AI Overview mentions for a keyword
   */
  async detectAIOverview(keyword: string): Promise<FeatureDetectionResult> {
    const result: FeatureDetectionResult = {
      featureType: 'ai_overview',
      detected: false,
      weOwnIt: false,
    };

    try {
      // AI Overviews tend to appear for informational queries
      const aiOverviewTriggers = [
        'what is', 'how to', 'explain', 'definition', 'meaning',
        'difference between', 'vs', 'compared to', 'best way',
        'should i', 'can you', 'why does'
      ];

      const keywordLower = keyword.toLowerCase();
      const hasAIOverviewPotential = aiOverviewTriggers.some(trigger =>
        keywordLower.includes(trigger)
      );

      if (hasAIOverviewPotential) {
        result.detected = true;

        // Check if our content is cited
        const existingMention = await prisma.sERPFeature.findFirst({
          where: {
            keyword,
            featureType: 'ai_overview',
            aiOverviewMention: true,
          },
        });

        result.weOwnIt = !!existingMention;
        result.citationContext = existingMention?.citationContext || undefined;
      }

      await ComplianceService.log('AGENT', 'SERP_AI_OVERVIEW_CHECK', 'SERPFeatureService', {
        keyword,
        detected: result.detected,
        weOwnIt: result.weOwnIt,
      });

    } catch (error) {
      console.error('[SERPFeatureService] AI Overview detection error:', error);
    }

    return result;
  }

  /**
   * Detect local pack presence
   */
  async detectLocalPack(keyword: string): Promise<FeatureDetectionResult> {
    const result: FeatureDetectionResult = {
      featureType: 'local_pack',
      detected: false,
      weOwnIt: false,
    };

    // Local pack detection would require location context
    // Skip for EventheOdds as we're not a local business
    return result;
  }

  /**
   * Perform full SERP analysis for a keyword
   */
  async analyzeSERP(keyword: string): Promise<SERPAnalysisResult> {
    const [snippet, paa, aiOverview, localPack] = await Promise.all([
      this.detectFeaturedSnippet(keyword),
      this.detectPAAQuestions(keyword),
      this.detectAIOverview(keyword),
      this.detectLocalPack(keyword),
    ]);

    return {
      keyword,
      features: [snippet, paa, aiOverview, localPack].filter(f => f.detected),
      analyzedAt: new Date().toISOString(),
    };
  }

  /**
   * Record a SERP feature capture
   */
  async recordCapture(
    keyword: string,
    featureType: SERPFeatureType,
    contentHash?: string,
    citationContext?: string
  ): Promise<string> {
    const now = new Date();

    // Update or create feature record
    const existing = await prisma.sERPFeature.findFirst({
      where: { keyword, featureType },
    });

    if (existing) {
      await prisma.sERPFeature.update({
        where: { id: existing.id },
        data: {
          captured: true,
          capturedAt: now,
          contentHash,
          aiOverviewMention: featureType === 'ai_overview',
          citationContext,
          updatedAt: now,
        },
      });

      await ComplianceService.log('AGENT', 'SERP_FEATURE_CAPTURED', 'SERPFeatureService', {
        keyword,
        featureType,
        action: 'updated',
      });

      return existing.id;
    }

    const newFeature = await prisma.sERPFeature.create({
      data: {
        siteId: this.siteId,
        keyword,
        featureType,
        captured: true,
        capturedAt: now,
        contentHash,
        aiOverviewMention: featureType === 'ai_overview',
        citationContext,
        detectedAt: now,
      },
    });

    await ComplianceService.log('AGENT', 'SERP_FEATURE_CAPTURED', 'SERPFeatureService', {
      keyword,
      featureType,
      action: 'created',
    });

    return newFeature.id;
  }

  /**
   * Record a SERP feature loss
   */
  async recordLoss(keyword: string, featureType: SERPFeatureType): Promise<void> {
    const existing = await prisma.sERPFeature.findFirst({
      where: { keyword, featureType, captured: true },
    });

    if (existing) {
      await prisma.sERPFeature.update({
        where: { id: existing.id },
        data: {
          captured: false,
          aiOverviewMention: false,
          updatedAt: new Date(),
        },
      });

      await ComplianceService.log('AGENT', 'SERP_FEATURE_LOST', 'SERPFeatureService', {
        keyword,
        featureType,
      });
    }
  }

  /**
   * Track captures for a site over a time period
   */
  async trackCaptures(siteId: string, days: number = 30): Promise<CaptureReport> {
    const endDate = new Date();
    const startDate = new Date(endDate.getTime() - days * 24 * 60 * 60 * 1000);

    const features = await prisma.sERPFeature.findMany({
      where: {
        siteId,
        OR: [
          { capturedAt: { gte: startDate } },
          { detectedAt: { gte: startDate } },
        ],
      },
    });

    const snippetsCaptured = features.filter(
      f => f.featureType === 'snippet' && f.captured && f.capturedAt && f.capturedAt >= startDate
    ).length;

    const snippetsLost = features.filter(
      f => f.featureType === 'snippet' && !f.captured && f.updatedAt >= startDate
    ).length;

    const paaCaptures = features.filter(
      f => f.featureType === 'paa' && f.captured
    ).length;

    const aiOverviewMentions = features.filter(
      f => f.featureType === 'ai_overview' && f.aiOverviewMention
    ).length;

    return {
      siteId,
      period: { start: startDate, end: endDate },
      snippetsCaptured,
      snippetsLost,
      paaCaptures,
      aiOverviewMentions,
      totalFeaturesTracked: features.length,
    };
  }

  /**
   * Get uncaptured feature opportunities
   */
  async getOpportunities(siteId?: string, limit: number = 50): Promise<Array<{
    keyword: string;
    featureType: string;
    detectedAt: Date;
    priority: number;
  }>> {
    const features = await prisma.sERPFeature.findMany({
      where: {
        siteId: siteId || this.siteId,
        captured: false,
      },
      orderBy: { detectedAt: 'desc' },
      take: limit,
    });

    return features.map(f => ({
      keyword: f.keyword,
      featureType: f.featureType,
      detectedAt: f.detectedAt,
      priority: f.featureType === 'ai_overview' ? 10 : f.featureType === 'snippet' ? 9 : 8,
    }));
  }

  /**
   * Bulk detect SERP features for multiple keywords
   */
  async bulkAnalyze(keywords: string[]): Promise<SERPAnalysisResult[]> {
    const results: SERPAnalysisResult[] = [];

    // Process in batches of 10 to avoid rate limits
    const batchSize = 10;
    for (let i = 0; i < keywords.length; i += batchSize) {
      const batch = keywords.slice(i, i + batchSize);
      const batchResults = await Promise.all(
        batch.map(keyword => this.analyzeSERP(keyword))
      );
      results.push(...batchResults);

      // Small delay between batches
      if (i + batchSize < keywords.length) {
        await new Promise(resolve => setTimeout(resolve, 500));
      }
    }

    return results;
  }
}

export default SERPFeatureService;
