#!/usr/bin/env bun
/**
 * NetworkDiscoveryAgent Deployment Script
 * Agent 8 - Geographic Network Discovery and Analysis
 *
 * This script provides standalone deployment for the NetworkDiscoveryAgent,
 * which maps and analyzes the geographic distribution of the plant network.
 *
 * Responsibilities:
 * - Map plant distribution across regions
 * - Identify network hotspots and clusters
 * - Suggest grower/consumer connections
 * - Track network growth patterns
 * - Detect coverage gaps
 *
 * Usage:
 *   bun run deploy/NetworkDiscoveryAgent.ts
 *   bun run deploy:network-discovery
 *
 * Environment Variables:
 *   AGENT_INTERVAL_MS    - Execution interval (default: 600000 = 10 min)
 *   AGENT_LOG_LEVEL      - Log level: debug, info, warn, error (default: info)
 *   AGENT_AUTO_RESTART   - Auto-restart on failure (default: true)
 *   AGENT_MAX_RETRIES    - Max retry attempts (default: 3)
 */

import { getNetworkDiscoveryAgent, NetworkDiscoveryAgent } from '../lib/agents/NetworkDiscoveryAgent';

// Configuration from environment
const config = {
  intervalMs: parseInt(process.env.AGENT_INTERVAL_MS || '600000'),
  logLevel: process.env.AGENT_LOG_LEVEL || 'info',
  autoRestart: process.env.AGENT_AUTO_RESTART !== 'false',
  maxRetries: parseInt(process.env.AGENT_MAX_RETRIES || '3'),
};

// Logger utility
const log = {
  debug: (...args: any[]) => config.logLevel === 'debug' && console.log('[DEBUG]', ...args),
  info: (...args: any[]) => ['debug', 'info'].includes(config.logLevel) && console.log('[INFO]', ...args),
  warn: (...args: any[]) => ['debug', 'info', 'warn'].includes(config.logLevel) && console.warn('[WARN]', ...args),
  error: (...args: any[]) => console.error('[ERROR]', ...args),
};

/**
 * Format uptime as human-readable string
 */
function formatUptime(ms: number): string {
  const seconds = Math.floor(ms / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
  if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
  if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
  return `${seconds}s`;
}

/**
 * Display agent status
 */
function displayStatus(agent: NetworkDiscoveryAgent): void {
  const metrics = agent.getMetrics();
  const analysis = agent.getNetworkAnalysis();
  const clusters = agent.getClusters();
  const gaps = agent.getCoverageGaps();
  const suggestions = agent.getConnectionSuggestions();
  const growth = agent.getGrowthHistory();
  const regions = agent.getRegionalStats();

  console.log('\n' + '='.repeat(60));
  console.log('  NETWORK DISCOVERY AGENT - STATUS REPORT');
  console.log('='.repeat(60));

  // Agent Metrics
  console.log('\n  AGENT METRICS');
  console.log('  ' + '-'.repeat(40));
  console.log(`  Status:           ${agent.status}`);
  console.log(`  Uptime:           ${formatUptime(metrics.uptime)}`);
  console.log(`  Tasks Completed:  ${metrics.tasksCompleted}`);
  console.log(`  Tasks Failed:     ${metrics.tasksFailed}`);
  console.log(`  Avg Execution:    ${Math.round(metrics.averageExecutionMs)}ms`);
  console.log(`  Last Run:         ${metrics.lastRunAt || 'Never'}`);

  // Network Analysis
  console.log('\n  NETWORK ANALYSIS');
  console.log('  ' + '-'.repeat(40));
  console.log(`  Total Nodes:      ${analysis.totalNodes}`);
  console.log(`  Connections:      ${analysis.totalConnections}`);
  console.log(`  Clusters:         ${clusters.length}`);
  console.log(`  Hotspots:         ${analysis.hotspots.length}`);
  console.log(`  Coverage Gaps:    ${gaps.length}`);
  console.log(`  Suggestions:      ${suggestions.length}`);

  // Cluster Details
  if (clusters.length > 0) {
    console.log('\n  TOP CLUSTERS');
    console.log('  ' + '-'.repeat(40));
    const topClusters = clusters.slice(0, 5);
    for (const cluster of topClusters) {
      console.log(`  - ${cluster.activityLevel.toUpperCase()} activity cluster`);
      console.log(`    Nodes: ${cluster.nodes.length}, Radius: ${cluster.radius}km`);
      if (cluster.dominantSpecies.length > 0) {
        console.log(`    Species: ${cluster.dominantSpecies.slice(0, 3).join(', ')}`);
      }
    }
  }

  // Coverage Gaps
  if (gaps.length > 0) {
    console.log('\n  COVERAGE GAPS');
    console.log('  ' + '-'.repeat(40));
    for (const gap of gaps.slice(0, 3)) {
      console.log(`  - ${gap.populationDensity.toUpperCase()} area`);
      console.log(`    Distance to nearest: ${gap.distanceToNearest}km`);
      console.log(`    Potential demand: ${gap.potentialDemand}`);
    }
  }

  // Top Suggestions
  if (suggestions.length > 0) {
    console.log('\n  TOP CONNECTION SUGGESTIONS');
    console.log('  ' + '-'.repeat(40));
    for (const suggestion of suggestions.slice(0, 3)) {
      console.log(`  - Strength: ${suggestion.strength}%`);
      console.log(`    Distance: ${suggestion.distance}km`);
      console.log(`    Reason: ${suggestion.reason}`);
    }
  }

  // Regional Stats
  if (regions.length > 0) {
    console.log('\n  REGIONAL STATISTICS');
    console.log('  ' + '-'.repeat(40));
    for (const region of regions) {
      if (region.nodeCount > 0) {
        console.log(`  ${region.region}:`);
        console.log(`    Nodes: ${region.nodeCount}, Plants: ${region.plantCount}`);
        console.log(`    Species: ${region.uniqueSpecies}, Activity: ${region.avgActivityScore}`);
      }
    }
  }

  // Growth Trend
  if (growth.length > 0) {
    const latest = growth[growth.length - 1];
    console.log('\n  NETWORK GROWTH');
    console.log('  ' + '-'.repeat(40));
    console.log(`  Total Nodes:        ${latest.totalNodes}`);
    console.log(`  Total Connections:  ${latest.totalConnections}`);
    console.log(`  New Nodes/Week:     ${latest.newNodesWeek}`);
    console.log(`  Geographic Span:    ${latest.geographicExpansion}km`);
  }

  // Alerts
  const alerts = agent.getAlerts();
  const unacknowledged = alerts.filter(a => !a.acknowledged);
  if (unacknowledged.length > 0) {
    console.log('\n  ACTIVE ALERTS');
    console.log('  ' + '-'.repeat(40));
    for (const alert of unacknowledged.slice(0, 5)) {
      console.log(`  [${alert.severity.toUpperCase()}] ${alert.title}`);
      console.log(`    ${alert.message}`);
    }
  }

  console.log('\n' + '='.repeat(60));
}

/**
 * Main deployment function
 */
async function deploy(): Promise<void> {
  console.log('\n' + '='.repeat(60));
  console.log('  DEPLOYING NETWORK DISCOVERY AGENT (Agent 8)');
  console.log('='.repeat(60));
  console.log(`\n  Configuration:`);
  console.log(`  - Interval:     ${config.intervalMs}ms (${config.intervalMs / 60000} min)`);
  console.log(`  - Log Level:    ${config.logLevel}`);
  console.log(`  - Auto Restart: ${config.autoRestart}`);
  console.log(`  - Max Retries:  ${config.maxRetries}`);
  console.log('');

  // Get agent instance
  const agent = getNetworkDiscoveryAgent();

  // Register event handlers
  agent.on('task_completed', (data) => {
    log.info(`Task completed: ${JSON.stringify(data.result)}`);
  });

  agent.on('task_failed', (data) => {
    log.error(`Task failed: ${data.error}`);
  });

  agent.on('agent_started', () => {
    log.info('Network Discovery Agent started');
  });

  agent.on('agent_stopped', () => {
    log.info('Network Discovery Agent stopped');
  });

  // Start the agent
  log.info('Starting Network Discovery Agent...');

  try {
    await agent.start();
    log.info('Agent started successfully');

    // Run initial discovery
    log.info('Running initial network discovery...');
    await agent.runOnce();
    log.info('Initial discovery complete');

    // Display initial status
    displayStatus(agent);

    // Set up periodic status display
    const statusInterval = setInterval(() => {
      displayStatus(agent);
    }, config.intervalMs);

    // Handle shutdown signals
    const shutdown = async (signal: string) => {
      log.info(`Received ${signal}, shutting down...`);
      clearInterval(statusInterval);

      try {
        await agent.stop();
        log.info('Agent stopped gracefully');
        process.exit(0);
      } catch (error) {
        log.error('Error during shutdown:', error);
        process.exit(1);
      }
    };

    process.on('SIGINT', () => shutdown('SIGINT'));
    process.on('SIGTERM', () => shutdown('SIGTERM'));

    // Keep the process running
    log.info(`Agent running. Press Ctrl+C to stop.`);
    log.info(`Next discovery in ${config.intervalMs / 60000} minutes...`);

  } catch (error) {
    log.error('Failed to start agent:', error);

    if (config.autoRestart) {
      log.info('Auto-restart enabled, retrying in 10 seconds...');
      setTimeout(() => deploy(), 10000);
    } else {
      process.exit(1);
    }
  }
}

// Run deployment
deploy().catch((error) => {
  console.error('Deployment failed:', error);
  process.exit(1);
});
