// PhishProtect Cloud Query Client
// Client for cloud analysis service queries (medium-risk detections)

export class CloudQueryClient {
  constructor(config = {}) {
    this.cloudUrl = config.cloudUrl || 'https://cloud.nithic.ai';
    this.enabled = config.enabled || false;
    this.timeoutMs = config.timeoutMs || 5000;
    this.deviceId = config.deviceId || null;
    this.extensionVersion = config.extensionVersion || '2.0.0';
  }

  /**
   * Query the cloud analysis service for a detection
   * Returns: { determination, confidence, additionalQueries, sampleRequest }
   */
  async queryCloud(url, detection, pageFeatures = {}) {
    if (!this.enabled) {
      return { determination: 'unknown', confidence: 0, skipped: true };
    }

    const domain = this._extractDomain(url);
    const urlHash = await this._hashUrl(url);

    const requestBody = {
      url,
      url_hash: urlHash,
      domain,
      local_risk_score: detection.riskScore || 0,
      findings: (detection.findings || []).map(f => ({
        detector: f.detector,
        type: f.type,
        severity: f.severity,
        weight: f.weight,
        category: f.category
      })),
      page_features: pageFeatures,
      features: detection.features || null, // v3: full feature store snapshot
      metadata: {
        device_id: this.deviceId,
        extension_version: this.extensionVersion
      }
    };

    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);

      const response = await fetch(`${this.cloudUrl}/v1/analyze`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(requestBody),
        signal: controller.signal
      });

      clearTimeout(timeoutId);

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      const result = await response.json();

      console.log('CloudQueryClient: Analysis result:', {
        determination: result.determination,
        confidence: result.confidence,
        additionalQueries: result.additional_queries?.length || 0
      });

      // Handle additional queries if any
      if (result.additional_queries && result.additional_queries.length > 0) {
        const queryResults = await this._executeAdditionalQueries(result.additional_queries);
        // Could send follow-up with query results here if needed
      }

      return {
        determination: result.determination || 'unknown',
        confidence: result.confidence || 0,
        additionalQueries: result.additional_queries,
        sampleRequest: result.sample_request,
        markersToSet: result.markers_to_set
      };

    } catch (error) {
      if (error.name === 'AbortError') {
        console.warn('CloudQueryClient: Query timed out');
      } else {
        console.error('CloudQueryClient: Query failed:', error.message);
      }
      return { determination: 'unknown', confidence: 0, error: error.message };
    }
  }

  /**
   * Should this detection be escalated to the cloud?
   * Returns true for medium-risk detections that could benefit from cloud analysis
   */
  shouldEscalate(detection, decision) {
    if (!this.enabled) return false;

    // Escalate 'report' actions (medium risk)
    if (decision.action === 'report' || decision.action === 'warn') {
      return true;
    }

    // Escalate if risk is medium and we're not already blocking
    if (detection.riskLevel === 'medium' && decision.action !== 'block') {
      return true;
    }

    return false;
  }

  /**
   * Execute additional queries requested by the cloud service
   * These are injected into the page via content script messaging
   */
  async _executeAdditionalQueries(queries) {
    const results = [];
    for (const query of queries) {
      try {
        if (query.type === 'js_eval') {
          // Would need to send to content script to evaluate
          console.log('CloudQueryClient: JS eval query requested:', query.description);
          results.push({ type: query.type, status: 'pending', description: query.description });
        } else if (query.type === 'xpath') {
          console.log('CloudQueryClient: XPath query requested:', query.description);
          results.push({ type: query.type, status: 'pending', description: query.description });
        } else if (query.type === 'headers') {
          console.log('CloudQueryClient: Headers query requested:', query.description);
          results.push({ type: query.type, status: 'pending', description: query.description });
        }
      } catch (error) {
        results.push({ type: query.type, error: error.message });
      }
    }
    return results;
  }

  /**
   * Lookup CVE vulnerabilities for detected technologies.
   * Called after tech fingerprinting with the raw fingerprint data.
   * @param {Object} techFingerprint - Raw tech_fingerprint_report data from content script
   * @returns {{ vulnerabilities: Array, summary: Object|null }}
   */
  async lookupVulnerabilities(techFingerprint) {
    if (!this.enabled) {
      return { vulnerabilities: [], summary: null };
    }

    const technologies = [];

    // WordPress plugins
    if (techFingerprint.wpPlugins) {
      for (const p of techFingerprint.wpPlugins) {
        if (!p.version) continue;
        technologies.push({
          name: p.name,
          category: 'wpPlugins',
          version: p.version,
          slug: p.name,
          slugType: 'wp-plugin'
        });
      }
    }

    // WordPress themes
    if (techFingerprint.wpThemes) {
      for (const t of techFingerprint.wpThemes) {
        if (!t.version) continue;
        technologies.push({
          name: t.name,
          category: 'wpThemes',
          version: t.version,
          slug: t.name,
          slugType: 'wp-theme'
        });
      }
    }

    // CMS (WordPress core)
    if (techFingerprint.cms) {
      for (const c of techFingerprint.cms) {
        if (!c.version) continue;
        if (c.name === 'WordPress') {
          technologies.push({
            name: 'WordPress',
            category: 'cms',
            version: c.version,
            slug: 'wordpress',
            slugType: 'wp-core'
          });
        } else {
          technologies.push({
            name: c.name,
            category: 'cms',
            version: c.version,
            cpe: c.cpe || null
          });
        }
      }
    }

    // HTTP servers, client libs, frameworks — CPE-based
    for (const category of ['httpServer', 'clientLibs', 'frameworks', 'serverSide']) {
      if (!techFingerprint[category]) continue;
      for (const item of techFingerprint[category]) {
        if (!item.version) continue;
        technologies.push({
          name: item.name,
          category,
          version: item.version,
          cpe: item.cpe || null
        });
      }
    }

    if (technologies.length === 0) {
      return { vulnerabilities: [], summary: null };
    }

    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);

      const response = await fetch(`${this.cloudUrl}/v1/cve/lookup`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ technologies }),
        signal: controller.signal
      });

      clearTimeout(timeoutId);

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      const result = await response.json();

      if (result.summary?.total_cves > 0) {
        console.log('CloudQueryClient: CVE lookup result:', {
          total_cves: result.summary.total_cves,
          max_cvss: result.summary.max_cvss,
          critical: result.summary.critical,
          high: result.summary.high
        });
      }

      return result;
    } catch (error) {
      if (error.name === 'AbortError') {
        console.warn('CloudQueryClient: CVE lookup timed out');
      } else {
        console.error('CloudQueryClient: CVE lookup failed:', error.message);
      }
      return { vulnerabilities: [], summary: null };
    }
  }

  /**
   * Update configuration
   */
  updateConfig(config) {
    if (config.cloudUrl !== undefined) this.cloudUrl = config.cloudUrl;
    if (config.enabled !== undefined) this.enabled = config.enabled;
    if (config.timeoutMs !== undefined) this.timeoutMs = config.timeoutMs;
    if (config.deviceId !== undefined) this.deviceId = config.deviceId;
  }

  /**
   * Get client status
   */
  getStatus() {
    return {
      enabled: this.enabled,
      cloudUrl: this.cloudUrl,
      timeoutMs: this.timeoutMs
    };
  }

  // Private helpers

  async _hashUrl(url) {
    const encoder = new TextEncoder();
    const data = encoder.encode(url);
    const hashBuffer = await crypto.subtle.digest('SHA-256', data);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
  }

  _extractDomain(url) {
    try {
      return new URL(url).hostname;
    } catch {
      return null;
    }
  }
}
