import jwt from 'jsonwebtoken';
import { EventEmitter } from 'events';
import { DeviceFingerprint } from './deviceFingerprint.js';
import { DigitalOceanClient } from './digitalOceanClient.js';
import { createHash, randomBytes } from 'crypto';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { join } from 'path';

/**
 * License Management System
 * Handles license validation, device binding, and usage tracking
 */
export class LicenseManager extends EventEmitter {
  constructor() {
    super();
    
    this.deviceFingerprint = new DeviceFingerprint();
    this.digitalOcean = new DigitalOceanClient();
    
    // License tiers configuration - ALL LIFETIME PURCHASES
    this.licenseTiers = {
      PERSONAL: {
        name: 'Personal',
        price: 5,
        maxDevices: 1,
        features: ['basic-ai-to-ai', 'local-storage'],
        lifetime: true
      },
      SMALL_TEAM: {
        name: 'Small Team',
        price: 25,
        maxDevices: 10,
        features: ['basic-ai-to-ai', 'shared-analytics', 'team-collaboration'],
        lifetime: true
      },
      BUSINESS: {
        name: 'Business',
        price: 50,
        maxDevices: 500,
        features: ['advanced-ai-to-ai', 'analytics-dashboard', 'priority-support'],
        lifetime: true
      },
      ENTERPRISE: {
        name: 'Enterprise',
        price: 100,
        maxDevices: 5000,
        features: ['enterprise-ai-to-ai', 'custom-integrations', 'dedicated-support'],
        lifetime: true
      }
    };

    // 🔐 SECURITY HARDENING: Use persistent JWT secret
    this.jwtSecret = process.env.LICENSE_JWT_SECRET || this.getOrCreatePersistentSecret();
    
    this.currentLicense = null;
    this.deviceId = null;
    
    console.log('🔐 License Manager initialized');
  }

  /**
   * Initialize license system
   */
  async initialize() {
    try {
      console.log('🚀 Initializing license system...');
      
      // Generate device fingerprint
      await this.deviceFingerprint.generateFingerprint();
      this.deviceId = this.deviceFingerprint.fingerprint.hardware;
      
      // Test DigitalOcean connection
      await this.digitalOcean.testConnection();
      
      // Load existing license
      await this.loadLicense();
      
      console.log('✅ License system initialized successfully');
      this.emit('initialized');
      
      return true;
    } catch (error) {
      console.error('❌ License system initialization failed:', error.message);
      throw error;
    }
  }

  /**
   * Generate a new license
   */
  async generateLicense(licenseData) {
    try {
      const {
        tier,
        userId,
        userEmail,
        userName,
        paymentId,
        deviceFingerprint
      } = licenseData;

      if (!this.licenseTiers[tier]) {
        throw new Error(`Invalid license tier: ${tier}`);
      }

      const tierConfig = this.licenseTiers[tier];
      const licenseId = this.generateLicenseId();
      
      const license = {
        licenseId,
        tier,
        tierConfig,
        userId,
        userEmail,
        userName,
        paymentId,
        deviceFingerprint,
        devices: [{
          deviceId: deviceFingerprint.hardware,
          deviceName: this.getDeviceName(deviceFingerprint),
          registeredAt: new Date().toISOString(),
          lastSeen: new Date().toISOString(),
          active: true
        }],
        usage: {
          totalSessions: 0,
          totalConversations: 0,
          totalMessages: 0,
          lastUsed: null
        },
        status: 'active',
        createdAt: new Date().toISOString(),
        expiresAt: null, // All licenses are now lifetime
        features: tierConfig.features,
        metadata: {
          version: '1.0',
          generatedBy: 'ZAI License Manager'
        }
      };

      // Generate JWT token (all licenses are lifetime)
      const token = jwt.sign(
        {
          licenseId,
          tier,
          userId,
          deviceId: deviceFingerprint.hardware,
          features: tierConfig.features,
          expiresAt: null
        },
        this.jwtSecret,
        {
          expiresIn: '100y', // All licenses are lifetime
          issuer: 'ZAI-License-Manager',
          subject: userId
        }
      );

      license.token = token;

      // Store license in DigitalOcean Spaces
      await this.digitalOcean.storeLicense(license);
      
      console.log(`✅ License generated: ${licenseId} (${tier})`);
      this.emit('licenseGenerated', license);
      
      return license;
    } catch (error) {
      console.error('❌ License generation failed:', error.message);
      throw error;
    }
  }

  /**
   * Validate license token
   */
  async validateLicense(token = null) {
    try {
      const licenseToken = token || this.currentLicense?.token;

      if (!licenseToken) {
        throw new Error('No license token provided');
      }

      // 🔐 SECURITY HARDENING: Restrict test license validation
      if (licenseToken.startsWith('ZAI-TEST-')) {
        // Only allow test licenses in development environment with specific flag
        if (process.env.NODE_ENV === 'test' && process.env.ZAI_ALLOW_TEST_LICENSES === 'true') {
          console.log('⚠️ WARNING: Test license validation enabled in test environment');
          return this.validateTestLicense(licenseToken);
        } else {
          throw new Error('Test licenses are not allowed in production environment');
        }
      }

      // 🔐 SECURITY: Remove NODE_ENV bypass vulnerability
      if (process.env.NODE_ENV === 'test' && !licenseToken.startsWith('ZAI-TEST-')) {
        throw new Error('Invalid license token format for test environment');
      }

      // Verify JWT token
      const decoded = jwt.verify(licenseToken, this.jwtSecret);
      
      // Load full license data
      const license = await this.digitalOcean.downloadData(`licenses/active/${decoded.licenseId}.json`);
      
      if (!license) {
        throw new Error('License not found');
      }

      // Check license status
      if (license.status !== 'active') {
        throw new Error(`License is ${license.status}`);
      }

      // Check expiry
      if (license.expiresAt && new Date(license.expiresAt) < new Date()) {
        throw new Error('License has expired');
      }

      // Validate device
      const deviceValidation = await this.validateDevice(license);
      
      if (!deviceValidation.isValid) {
        throw new Error(`Device validation failed (${deviceValidation.confidence}% confidence)`);
      }

      // Update last seen
      await this.updateDeviceLastSeen(license);

      console.log(`✅ License validated: ${license.licenseId} (${license.tier})`);
      this.currentLicense = license;
      this.emit('licenseValidated', license);
      
      return {
        isValid: true,
        license,
        deviceValidation
      };
    } catch (error) {
      console.error('❌ License validation failed:', error.message);
      this.emit('licenseValidationFailed', error);
      
      return {
        isValid: false,
        error: error.message
      };
    }
  }

  /**
   * Validate device against license
   */
  async validateDevice(license) {
    try {
      // Find device in license
      const device = license.devices.find(d => d.deviceId === this.deviceId);
      
      if (!device) {
        // Check if we can add this device
        if (license.devices.length >= license.tierConfig.maxDevices) {
          throw new Error('Maximum devices exceeded for this license');
        }
        
        // Add new device
        return await this.addDeviceToLicense(license);
      }

      // Validate existing device
      const validation = await this.deviceFingerprint.validateDevice(license.deviceFingerprint);
      
      return validation;
    } catch (error) {
      console.error('❌ Device validation failed:', error.message);
      throw error;
    }
  }

  /**
   * Add device to license
   */
  async addDeviceToLicense(license) {
    try {
      const deviceFingerprint = await this.deviceFingerprint.generateFingerprint();
      
      const newDevice = {
        deviceId: deviceFingerprint.hardware,
        deviceName: this.getDeviceName(this.deviceFingerprint.deviceInfo),
        registeredAt: new Date().toISOString(),
        lastSeen: new Date().toISOString(),
        active: true
      };

      license.devices.push(newDevice);
      license.lastUpdated = new Date().toISOString();

      // Update license in storage
      await this.digitalOcean.uploadData(`licenses/active/${license.licenseId}.json`, license);
      
      console.log(`✅ Device added to license: ${newDevice.deviceId}`);
      this.emit('deviceAdded', { license, device: newDevice });
      
      return {
        isValid: true,
        confidence: 100,
        newDevice: true
      };
    } catch (error) {
      console.error('❌ Failed to add device to license:', error.message);
      throw error;
    }
  }

  /**
   * Remove device from license (for admin dashboard)
   */
  async removeDeviceFromLicense(licenseId, deviceId) {
    try {
      const license = await this.digitalOcean.downloadData(`licenses/active/${licenseId}.json`);
      
      if (!license) {
        throw new Error('License not found');
      }

      const deviceIndex = license.devices.findIndex(d => d.deviceId === deviceId);
      
      if (deviceIndex === -1) {
        throw new Error('Device not found in license');
      }

      const removedDevice = license.devices.splice(deviceIndex, 1)[0];
      license.lastUpdated = new Date().toISOString();

      // Update license in storage
      await this.digitalOcean.uploadData(`licenses/active/${license.licenseId}.json`, license);
      
      console.log(`✅ Device removed from license: ${deviceId}`);
      this.emit('deviceRemoved', { license, device: removedDevice });
      
      return removedDevice;
    } catch (error) {
      console.error('❌ Failed to remove device from license:', error.message);
      throw error;
    }
  }

  /**
   * Track usage for billing and analytics
   */
  async trackUsage(usageData) {
    try {
      if (!this.currentLicense) {
        console.warn('⚠️ No active license for usage tracking');
        return;
      }

      // Update license usage
      this.currentLicense.usage.totalSessions++;
      this.currentLicense.usage.totalConversations += usageData.conversations || 0;
      this.currentLicense.usage.totalMessages += usageData.messages || 0;
      this.currentLicense.usage.lastUsed = new Date().toISOString();

      // Store usage data
      await this.digitalOcean.storeUserMetrics(this.currentLicense.userId, usageData);
      
      // Update license
      await this.digitalOcean.uploadData(
        `licenses/active/${this.currentLicense.licenseId}.json`, 
        this.currentLicense
      );

      this.emit('usageTracked', usageData);
    } catch (error) {
      console.error('❌ Usage tracking failed:', error.message);
    }
  }

  /**
   * Load existing license from local storage or DigitalOcean
   */
  async loadLicense() {
    try {
      // Try to load from environment or local config
      const licenseToken = process.env.ZAI_LICENSE_TOKEN;
      
      if (licenseToken) {
        const validation = await this.validateLicense(licenseToken);
        if (validation.isValid) {
          console.log('✅ License loaded from environment');
          return validation.license;
        }
      }

      console.log('ℹ️ No valid license found');
      return null;
    } catch (error) {
      console.error('❌ Failed to load license:', error.message);
      return null;
    }
  }

  /**
   * Helper methods
   */
  generateLicenseId() {
    return 'ZAI-' + randomBytes(16).toString('hex').toUpperCase();
  }

  /**
   * Validate test license tokens (for testing purposes)
   */
  async validateTestLicense(licenseToken) {
    console.log(`🧪 Validating test license: ${licenseToken}`);

    // Create mock license based on test token
    const testLicense = {
      licenseId: licenseToken,
      tier: licenseToken.includes('PERSONAL') ? 'PERSONAL' :
            licenseToken.includes('TEAM') ? 'TEAM' :
            licenseToken.includes('BUSINESS') ? 'BUSINESS' :
            licenseToken.includes('ENTERPRISE') ? 'ENTERPRISE' : 'TEAM',
      userId: 'test-user',
      features: ['ai_to_ai_communication', 'basic_features'],
      deviceLimit: 10,
      deviceCount: 1,
      issuedAt: Date.now() - 86400000, // 1 day ago
      expiresAt: null, // Lifetime
      status: 'active'
    };

    return {
      isValid: true,
      license: testLicense,
      message: 'Test license validation successful'
    };
  }

  generateSecret() {
    return randomBytes(64).toString('hex');
  }

  /**
   * 🔐 SECURITY: Get or create persistent JWT secret
   */
  getOrCreatePersistentSecret() {
    try {
      const secretPath = join(process.cwd(), '.zai-jwt-secret');

      // Try to read existing secret
      if (existsSync(secretPath)) {
        const secret = readFileSync(secretPath, 'utf8').trim();
        if (secret && secret.length >= 64) {
          console.log('🔐 Using persistent JWT secret');
          return secret;
        }
      }

      // Generate new persistent secret
      const newSecret = this.generateSecret();
      writeFileSync(secretPath, newSecret, { mode: 0o600 }); // Secure file permissions
      console.log('🔐 Generated new persistent JWT secret');
      return newSecret;

    } catch (error) {
      console.warn('⚠️ Failed to manage persistent JWT secret, using runtime secret:', error.message);
      return this.generateSecret();
    }
  }

  /**
   * Generate JWT token for a license
   */
  generateJWT(licenseData) {
    const { licenseId, tier, userId, maxDevices } = licenseData;

    return jwt.sign(
      {
        licenseId,
        tier,
        userId,
        maxDevices,
        features: this.licenseTiers[tier]?.features || [],
        expiresAt: null // All licenses are lifetime
      },
      this.jwtSecret,
      {
        expiresIn: '100y', // All licenses are lifetime
        issuer: 'ZAI-License-Manager',
        subject: userId
      }
    );
  }

  calculateExpiryDate(days) {
    const expiry = new Date();
    expiry.setDate(expiry.getDate() + days);
    return expiry.toISOString();
  }

  getDeviceName(deviceInfo) {
    if (!deviceInfo) return 'Unknown Device';
    
    const manufacturer = deviceInfo.system?.manufacturer || '';
    const model = deviceInfo.system?.model || '';
    const hostname = deviceInfo.os?.hostname || '';
    
    return `${manufacturer} ${model}`.trim() || hostname || 'Unknown Device';
  }

  async updateDeviceLastSeen(license) {
    try {
      const device = license.devices.find(d => d.deviceId === this.deviceId);
      if (device) {
        device.lastSeen = new Date().toISOString();
        await this.digitalOcean.uploadData(`licenses/active/${license.licenseId}.json`, license);
      }
    } catch (error) {
      console.error('❌ Failed to update device last seen:', error.message);
    }
  }

  /**
   * Get license status for display
   */
  getLicenseStatus() {
    if (!this.currentLicense) {
      return {
        status: 'unlicensed',
        message: 'No active license',
        tier: null,
        expiresAt: null,
        devicesUsed: 0,
        maxDevices: 0
      };
    }

    const license = this.currentLicense;
    const isExpired = license.expiresAt && new Date(license.expiresAt) < new Date();
    
    return {
      status: isExpired ? 'expired' : 'active',
      message: isExpired ? 'License has expired' : 'License is active',
      tier: license.tier,
      tierName: license.tierConfig.name,
      expiresAt: license.expiresAt,
      devicesUsed: license.devices.length,
      maxDevices: license.tierConfig.maxDevices,
      features: license.features,
      usage: license.usage
    };
  }
}
