// Stats Collector - Enhanced metrics and telemetry collection
// Tracks detector performance, risk distribution, and enterprise compliance metrics

export class StatsCollector {
  constructor(enableTelemetry = false) {
    this.enabled = enableTelemetry;
    this.stats = this.initializeStats();
    this.startTime = Date.now();
  }

  initializeStats() {
    return {
      // Legacy stats (backward compatibility)
      blockedUrls: 0,
      suspiciousResources: 0,
      permissionRequests: 0,
      clipboardAlerts: 0,

      // New: Per-detector metrics
      detectorHits: {},              // detector_name -> count
      detectorBlocks: {},            // detector_name -> block_count
      detectorLatencies: {},         // detector_name -> [latencies]

      // Risk distribution
      riskDistribution: {
        critical: 0,
        high: 0,
        medium: 0,
        low: 0,
        none: 0
      },

      // Performance metrics
      analysisLatency: [],
      cacheHitRate: 0,
      cacheHits: 0,
      cacheMisses: 0,

      // Policy & compliance
      policyViolations: 0,
      policyActions: {
        blocked: 0,
        warned: 0,
        allowed: 0
      },

      // Time-series data (last 24h)
      hourlyStats: Array(24).fill(0).map(() => ({
        detections: 0,
        blocks: 0,
        timestamp: null
      })),

      // Session info
      sessionStart: Date.now(),
      totalAnalyses: 0,
      uptime: 0
    };
  }

  recordDetection(detectorName, riskLevel, latencyMs, blocked = false) {
    if (!this.enabled && !this.isLegacyStat(detectorName)) return;

    // Update detector hits
    this.stats.detectorHits[detectorName] = (this.stats.detectorHits[detectorName] || 0) + 1;

    if (blocked) {
      this.stats.detectorBlocks[detectorName] = (this.stats.detectorBlocks[detectorName] || 0) + 1;
    }

    // Update latency
    if (!this.stats.detectorLatencies[detectorName]) {
      this.stats.detectorLatencies[detectorName] = [];
    }
    this.stats.detectorLatencies[detectorName].push(latencyMs);

    // Keep only last 100 latencies per detector
    if (this.stats.detectorLatencies[detectorName].length > 100) {
      this.stats.detectorLatencies[detectorName].shift();
    }

    // Update risk distribution
    if (riskLevel && this.stats.riskDistribution[riskLevel] !== undefined) {
      this.stats.riskDistribution[riskLevel]++;
    }

    // Update hourly stats
    const currentHour = new Date().getHours();
    this.stats.hourlyStats[currentHour].detections++;
    if (blocked) {
      this.stats.hourlyStats[currentHour].blocks++;
    }
    this.stats.hourlyStats[currentHour].timestamp = Date.now();

    // Update total
    this.stats.totalAnalyses++;
  }

  recordAnalysis(latencyMs, cacheHit = false) {
    this.stats.analysisLatency.push(latencyMs);

    // Keep only last 1000 latencies
    if (this.stats.analysisLatency.length > 1000) {
      this.stats.analysisLatency.shift();
    }

    // Update cache stats
    if (cacheHit) {
      this.stats.cacheHits++;
    } else {
      this.stats.cacheMisses++;
    }

    const totalCacheQueries = this.stats.cacheHits + this.stats.cacheMisses;
    this.stats.cacheHitRate = totalCacheQueries > 0
      ? this.stats.cacheHits / totalCacheQueries
      : 0;
  }

  recordPolicyAction(action, violation = false) {
    if (violation) {
      this.stats.policyViolations++;
    }

    if (this.stats.policyActions[action] !== undefined) {
      this.stats.policyActions[action]++;
    }
  }

  // Legacy compatibility methods
  incrementBlockedUrls() {
    this.stats.blockedUrls++;
  }

  incrementSuspiciousResources() {
    this.stats.suspiciousResources++;
  }

  incrementPermissionRequests() {
    this.stats.permissionRequests++;
  }

  incrementClipboardAlerts() {
    this.stats.clipboardAlerts++;
  }

  isLegacyStat(detectorName) {
    const legacyStats = ['blockedUrls', 'suspiciousResources', 'permissionRequests', 'clipboardAlerts'];
    return legacyStats.includes(detectorName);
  }

  getMetrics() {
    this.stats.uptime = Date.now() - this.startTime;

    return {
      ...this.stats,
      avgLatency: this.calculateAvgLatency(),
      p95Latency: this.calculatePercentile(95),
      topDetectors: this.getTopDetectors(5),
      detectorsActive: Object.keys(this.stats.detectorHits).length
    };
  }

  calculateAvgLatency() {
    if (this.stats.analysisLatency.length === 0) return 0;
    const sum = this.stats.analysisLatency.reduce((a, b) => a + b, 0);
    return sum / this.stats.analysisLatency.length;
  }

  calculatePercentile(percentile) {
    if (this.stats.analysisLatency.length === 0) return 0;
    const sorted = [...this.stats.analysisLatency].sort((a, b) => a - b);
    const index = Math.ceil((percentile / 100) * sorted.length) - 1;
    return sorted[index];
  }

  getTopDetectors(count = 5) {
    return Object.entries(this.stats.detectorHits)
      .sort(([, a], [, b]) => b - a)
      .slice(0, count)
      .map(([name, hits]) => ({ name, hits }));
  }

  async save() {
    try {
      await chrome.storage.local.set({ stats: this.stats });
    } catch (error) {
      console.error('[StatsCollector] Failed to save stats:', error);
    }
  }

  async load() {
    try {
      const result = await chrome.storage.local.get('stats');
      if (result.stats) {
        this.stats = { ...this.initializeStats(), ...result.stats };
      }
    } catch (error) {
      console.error('[StatsCollector] Failed to load stats:', error);
    }
  }

  reset() {
    this.stats = this.initializeStats();
    this.startTime = Date.now();
  }

  setEnabled(enabled) {
    this.enabled = enabled;
  }
}
