// MDM Integration - Mobile Device Management / Enterprise Device Management
// Integrates with enterprise.deviceAttributes API for managed configurations

export class MDMIntegration {
  constructor(config = {}) {
    this.config = config;
    this.enabled = config.mdmEnabled || false;
    this.deviceAttributes = null;
    this.managedConfig = null;
    this.enrollmentStatus = 'unknown';
    this.lastSyncTime = null;
    this.syncInterval = config.mdmSyncInterval || 3600000; // 1 hour default
  }

  /**
   * Initialize MDM integration
   */
  async initialize() {
    if (!this.enabled) {
      console.log('MDM integration disabled');
      return false;
    }

    // Check if running in enterprise/managed context
    const isManaged = await this.checkManagedStatus();

    if (!isManaged) {
      console.log('Device is not managed - MDM features unavailable');
      this.enrollmentStatus = 'unmanaged';
      return false;
    }

    // Fetch device attributes
    await this.fetchDeviceAttributes();

    // Load managed configuration
    await this.loadManagedConfiguration();

    // Set up periodic sync
    this.startPeriodicSync();

    this.enrollmentStatus = 'managed';
    console.log('MDM integration initialized successfully');
    return true;
  }

  /**
   * Check if device is managed by enterprise
   * @returns {boolean} - True if managed
   */
  async checkManagedStatus() {
    try {
      // Check for enterprise.deviceAttributes API availability
      if (!chrome.enterprise || !chrome.enterprise.deviceAttributes) {
        return false;
      }

      // Try to fetch device attributes to verify management
      const attributes = await chrome.enterprise.deviceAttributes.getDeviceSerialNumber();
      return attributes !== null && attributes !== undefined;
    } catch (error) {
      console.warn('Failed to check managed status:', error);
      return false;
    }
  }

  /**
   * Fetch device attributes from enterprise API
   */
  async fetchDeviceAttributes() {
    if (!chrome.enterprise || !chrome.enterprise.deviceAttributes) {
      console.warn('enterprise.deviceAttributes API not available');
      return null;
    }

    try {
      const [serialNumber, assetId, annotatedLocation, hostname] = await Promise.all([
        chrome.enterprise.deviceAttributes.getDeviceSerialNumber().catch(() => null),
        chrome.enterprise.deviceAttributes.getDeviceAssetId().catch(() => null),
        chrome.enterprise.deviceAttributes.getDeviceAnnotatedLocation().catch(() => null),
        chrome.enterprise.deviceAttributes.getDeviceHostname().catch(() => null)
      ]);

      this.deviceAttributes = {
        serialNumber,
        assetId,
        annotatedLocation,
        hostname,
        fetchedAt: Date.now()
      };

      console.log('Device attributes fetched successfully');
      return this.deviceAttributes;
    } catch (error) {
      console.error('Failed to fetch device attributes:', error);
      return null;
    }
  }

  /**
   * Load managed configuration from enterprise policy
   */
  async loadManagedConfiguration() {
    try {
      // Fetch managed storage (set by enterprise admin)
      const result = await chrome.storage.managed.get(null);

      if (result && Object.keys(result).length > 0) {
        this.managedConfig = result;
        this.lastSyncTime = Date.now();

        console.log('Managed configuration loaded:', {
          keys: Object.keys(result),
          timestamp: this.lastSyncTime
        });

        // Apply managed configuration to extension
        await this.applyManagedConfiguration(result);
        return result;
      } else {
        console.log('No managed configuration available');
        return null;
      }
    } catch (error) {
      console.error('Failed to load managed configuration:', error);
      return null;
    }
  }

  /**
   * Apply managed configuration to extension
   * @param {object} config - Managed configuration
   */
  async applyManagedConfiguration(config) {
    // Policy enforcement
    if (config.policyUrl) {
      console.log('Managed policy URL:', config.policyUrl);
      // Trigger policy load from URL
      this.dispatchConfigUpdate('policy', { url: config.policyUrl, source: 'mdm' });
    }

    // Feature flags
    if (config.enabledDetectors) {
      console.log('Managed detector configuration:', config.enabledDetectors);
      this.dispatchConfigUpdate('detectors', { enabled: config.enabledDetectors, source: 'mdm' });
    }

    // Risk thresholds
    if (config.riskThresholds) {
      console.log('Managed risk thresholds:', config.riskThresholds);
      this.dispatchConfigUpdate('riskThresholds', { thresholds: config.riskThresholds, source: 'mdm' });
    }

    // Telemetry settings
    if (config.telemetryEndpoint) {
      console.log('Managed telemetry endpoint:', config.telemetryEndpoint);
      this.dispatchConfigUpdate('telemetry', {
        endpoint: config.telemetryEndpoint,
        enabled: config.telemetryEnabled !== false,
        source: 'mdm'
      });
    }

    // Audit log settings
    if (config.auditLogEndpoint) {
      console.log('Managed audit log endpoint:', config.auditLogEndpoint);
      this.dispatchConfigUpdate('auditLog', {
        endpoint: config.auditLogEndpoint,
        enabled: config.auditLogEnabled !== false,
        source: 'mdm'
      });
    }

    // SIEM integration
    if (config.siemEndpoint) {
      console.log('Managed SIEM endpoint:', config.siemEndpoint);
      this.dispatchConfigUpdate('siem', {
        endpoint: config.siemEndpoint,
        format: config.siemFormat || 'cef',
        source: 'mdm'
      });
    }

    // User override permissions
    if (config.allowUserOverrides !== undefined) {
      console.log('User override permissions:', config.allowUserOverrides);
      this.dispatchConfigUpdate('permissions', {
        allowUserOverrides: config.allowUserOverrides,
        source: 'mdm'
      });
    }

    // Quarantine mode settings
    if (config.quarantineMode) {
      console.log('Quarantine mode settings:', config.quarantineMode);
      this.dispatchConfigUpdate('quarantine', {
        enabled: config.quarantineMode.enabled,
        restrictions: config.quarantineMode.restrictions,
        source: 'mdm'
      });
    }
  }

  /**
   * Dispatch configuration update event
   * @param {string} category - Configuration category
   * @param {object} data - Configuration data
   */
  dispatchConfigUpdate(category, data) {
    const event = new CustomEvent('mdm-config-update', {
      detail: {
        category,
        data,
        timestamp: Date.now()
      }
    });

    // Dispatch to background script
    if (chrome.runtime && chrome.runtime.sendMessage) {
      chrome.runtime.sendMessage({
        type: 'mdm-config-update',
        category,
        data
      }).catch(error => {
        console.warn('Failed to dispatch MDM config update:', error);
      });
    }
  }

  /**
   * Start periodic configuration sync
   */
  startPeriodicSync() {
    if (this.syncIntervalId) {
      clearInterval(this.syncIntervalId);
    }

    this.syncIntervalId = setInterval(async () => {
      console.log('Syncing managed configuration...');
      await this.loadManagedConfiguration();
    }, this.syncInterval);
  }

  /**
   * Stop periodic sync
   */
  stopPeriodicSync() {
    if (this.syncIntervalId) {
      clearInterval(this.syncIntervalId);
      this.syncIntervalId = null;
    }
  }

  /**
   * Get device attributes
   * @returns {object} - Device attributes
   */
  getDeviceAttributes() {
    return { ...this.deviceAttributes };
  }

  /**
   * Get managed configuration
   * @returns {object} - Managed configuration
   */
  getManagedConfiguration() {
    return { ...this.managedConfig };
  }

  /**
   * Get enrollment status
   * @returns {string} - Enrollment status (managed, unmanaged, unknown)
   */
  getEnrollmentStatus() {
    return this.enrollmentStatus;
  }

  /**
   * Check if specific configuration is managed
   * @param {string} key - Configuration key
   * @returns {boolean} - True if managed
   */
  isConfigurationManaged(key) {
    return this.managedConfig && this.managedConfig[key] !== undefined;
  }

  /**
   * Get managed configuration value
   * @param {string} key - Configuration key
   * @param {*} defaultValue - Default value if not managed
   * @returns {*} - Configuration value
   */
  getManagedConfigValue(key, defaultValue = null) {
    if (this.isConfigurationManaged(key)) {
      return this.managedConfig[key];
    }
    return defaultValue;
  }

  /**
   * Validate configuration against schema
   * @param {object} config - Configuration to validate
   * @returns {object} - Validation result
   */
  validateConfiguration(config) {
    const errors = [];
    const warnings = [];

    // Validate policy URL
    if (config.policyUrl) {
      try {
        new URL(config.policyUrl);
      } catch {
        errors.push('Invalid policyUrl: Must be a valid URL');
      }
    }

    // Validate telemetry endpoint
    if (config.telemetryEndpoint) {
      try {
        new URL(config.telemetryEndpoint);
      } catch {
        errors.push('Invalid telemetryEndpoint: Must be a valid URL');
      }
    }

    // Validate audit log endpoint
    if (config.auditLogEndpoint) {
      try {
        new URL(config.auditLogEndpoint);
      } catch {
        errors.push('Invalid auditLogEndpoint: Must be a valid URL');
      }
    }

    // Validate SIEM endpoint
    if (config.siemEndpoint) {
      try {
        new URL(config.siemEndpoint);
      } catch {
        errors.push('Invalid siemEndpoint: Must be a valid URL');
      }

      // Validate SIEM format
      const validFormats = ['cef', 'json', 'syslog'];
      if (config.siemFormat && !validFormats.includes(config.siemFormat)) {
        warnings.push(`Unknown siemFormat: ${config.siemFormat}. Expected: ${validFormats.join(', ')}`);
      }
    }

    // Validate risk thresholds
    if (config.riskThresholds) {
      const { critical, high, medium, low } = config.riskThresholds;

      if (critical !== undefined && (critical < 0 || critical > 100)) {
        errors.push('Invalid riskThresholds.critical: Must be between 0-100');
      }
      if (high !== undefined && (high < 0 || high > 100)) {
        errors.push('Invalid riskThresholds.high: Must be between 0-100');
      }
      if (medium !== undefined && (medium < 0 || medium > 100)) {
        errors.push('Invalid riskThresholds.medium: Must be between 0-100');
      }
      if (low !== undefined && (low < 0 || low > 100)) {
        errors.push('Invalid riskThresholds.low: Must be between 0-100');
      }
    }

    // Validate enabled detectors
    if (config.enabledDetectors && !Array.isArray(config.enabledDetectors)) {
      errors.push('Invalid enabledDetectors: Must be an array');
    }

    return {
      valid: errors.length === 0,
      errors,
      warnings
    };
  }

  /**
   * Export device and configuration status
   * @returns {object} - Status report
   */
  exportStatus() {
    return {
      enrollmentStatus: this.enrollmentStatus,
      deviceAttributes: this.deviceAttributes,
      managedConfigKeys: this.managedConfig ? Object.keys(this.managedConfig) : [],
      lastSyncTime: this.lastSyncTime,
      syncInterval: this.syncInterval,
      mdmEnabled: this.enabled
    };
  }

  /**
   * Force configuration sync
   */
  async forceSyncConfiguration() {
    console.log('Force syncing managed configuration...');
    await this.loadManagedConfiguration();
    await this.fetchDeviceAttributes();
    return this.exportStatus();
  }

  /**
   * Clean up and stop MDM integration
   */
  cleanup() {
    this.stopPeriodicSync();
    console.log('MDM integration cleaned up');
  }
}
