/**
 * Transparency Dashboard for LocalGreenChain
 *
 * Aggregates all transparency metrics, system health,
 * and provides a unified view of the entire platform's operations.
 */

import { getAuditLog, AuditStats } from './AuditLog';
import { getEventStream, EventStats } from './EventStream';

// Dashboard Types
export interface SystemHealth {
  status: 'healthy' | 'degraded' | 'unhealthy';
  uptime: number;
  lastCheck: string;
  components: {
    blockchain: ComponentHealth;
    agents: ComponentHealth;
    api: ComponentHealth;
    storage: ComponentHealth;
  };
}

export interface ComponentHealth {
  status: 'up' | 'degraded' | 'down';
  latency?: number;
  lastError?: string;
  errorCount24h: number;
}

export interface PlantTransparencyMetrics {
  totalPlantsRegistered: number;
  plantsRegisteredToday: number;
  plantsRegisteredThisWeek: number;
  totalClones: number;
  averageLineageDepth: number;
  topVarieties: Array<{ variety: string; count: number }>;
  geographicDistribution: Array<{ region: string; count: number }>;
}

export interface TransportTransparencyMetrics {
  totalTransportEvents: number;
  eventsToday: number;
  eventsThisWeek: number;
  totalDistanceMiles: number;
  averageDistanceMiles: number;
  totalCarbonKg: number;
  carbonSavedVsTraditional: number;
  transportMethods: Array<{ method: string; count: number; avgDistance: number }>;
  verificationRate: number;
}

export interface DemandTransparencyMetrics {
  totalDemandSignals: number;
  activeDemandSignals: number;
  matchRate: number;
  topRequestedVarieties: Array<{ variety: string; demand: number }>;
  averageFulfillmentTime: number;
  regionalDemand: Array<{ region: string; demand: number; supply: number }>;
}

export interface EnvironmentalTransparencyMetrics {
  totalCarbonSavedKg: number;
  waterSavedLiters: number;
  foodMilesReduced: number;
  wastePreventedKg: number;
  localFoodPercentage: number;
  sustainabilityScore: number;
  monthlyTrend: Array<{ month: string; carbonSaved: number; waterSaved: number }>;
}

export interface AgentTransparencyMetrics {
  totalAgents: number;
  activeAgents: number;
  totalTasksCompleted: number;
  totalTasksFailed: number;
  averageTaskTime: number;
  alertsGenerated24h: number;
  agentStatus: Array<{
    name: string;
    status: 'running' | 'paused' | 'stopped' | 'error';
    tasksCompleted: number;
    lastRun: string | null;
  }>;
}

export interface BlockchainTransparencyMetrics {
  totalBlocks: number;
  chainValid: boolean;
  lastBlockTime: string | null;
  averageBlockTime: number;
  totalTransactions: number;
  hashPower: number;
  difficulty: number;
}

export interface NetworkTransparencyMetrics {
  totalGrowers: number;
  totalConsumers: number;
  activeConnections: number;
  geographicCoverage: number;
  averageConnectionsPerGrower: number;
  networkGrowthRate: number;
}

export interface TransparencyDashboardData {
  generatedAt: string;
  systemHealth: SystemHealth;
  audit: AuditStats;
  events: EventStats;
  plants: PlantTransparencyMetrics;
  transport: TransportTransparencyMetrics;
  demand: DemandTransparencyMetrics;
  environmental: EnvironmentalTransparencyMetrics;
  agents: AgentTransparencyMetrics;
  blockchain: BlockchainTransparencyMetrics;
  network: NetworkTransparencyMetrics;
  recentActivity: RecentActivityItem[];
  alerts: TransparencyAlert[];
}

export interface RecentActivityItem {
  id: string;
  timestamp: string;
  type: string;
  description: string;
  actor: string;
  resourceId?: string;
  importance: 'low' | 'medium' | 'high';
}

export interface TransparencyAlert {
  id: string;
  type: 'info' | 'warning' | 'error' | 'critical';
  title: string;
  message: string;
  timestamp: string;
  acknowledged: boolean;
  source: string;
}

export interface TransparencyReport {
  title: string;
  generatedAt: string;
  period: { start: string; end: string };
  summary: {
    totalPlants: number;
    totalTransportEvents: number;
    carbonSavedKg: number;
    systemHealth: string;
    complianceStatus: string;
  };
  sections: TransparencyReportSection[];
}

export interface TransparencyReportSection {
  title: string;
  content: string;
  metrics: Array<{ label: string; value: string | number; change?: number }>;
  charts?: Array<{ type: string; data: any }>;
}

class TransparencyDashboard {
  private alerts: TransparencyAlert[] = [];
  private startTime: number = Date.now();

  constructor() {
    console.log('[TransparencyDashboard] Initialized');
  }

  /**
   * Get complete dashboard data
   */
  async getDashboard(): Promise<TransparencyDashboardData> {
    const auditLog = getAuditLog();
    const eventStream = getEventStream();

    return {
      generatedAt: new Date().toISOString(),
      systemHealth: await this.getSystemHealth(),
      audit: auditLog.getStats(),
      events: eventStream.getStats(),
      plants: await this.getPlantMetrics(),
      transport: await this.getTransportMetrics(),
      demand: await this.getDemandMetrics(),
      environmental: await this.getEnvironmentalMetrics(),
      agents: await this.getAgentMetrics(),
      blockchain: await this.getBlockchainMetrics(),
      network: await this.getNetworkMetrics(),
      recentActivity: await this.getRecentActivity(),
      alerts: this.getActiveAlerts()
    };
  }

  /**
   * Get system health status
   */
  async getSystemHealth(): Promise<SystemHealth> {
    const auditLog = getAuditLog();
    const auditIntegrity = auditLog.verifyIntegrity();

    const components = {
      blockchain: await this.checkBlockchainHealth(),
      agents: await this.checkAgentsHealth(),
      api: await this.checkApiHealth(),
      storage: await this.checkStorageHealth()
    };

    const allHealthy = Object.values(components).every(c => c.status === 'up');
    const anyDown = Object.values(components).some(c => c.status === 'down');

    return {
      status: anyDown ? 'unhealthy' : (allHealthy ? 'healthy' : 'degraded'),
      uptime: Date.now() - this.startTime,
      lastCheck: new Date().toISOString(),
      components
    };
  }

  private async checkBlockchainHealth(): Promise<ComponentHealth> {
    try {
      // Check blockchain file exists and is valid
      const fs = await import('fs');
      const path = await import('path');
      const chainFile = path.join(process.cwd(), 'data', 'plantchain.json');

      if (fs.existsSync(chainFile)) {
        const data = JSON.parse(fs.readFileSync(chainFile, 'utf-8'));
        return {
          status: 'up',
          latency: 5,
          errorCount24h: 0
        };
      }
      return { status: 'degraded', errorCount24h: 1, lastError: 'Chain file not found' };
    } catch (error) {
      return { status: 'down', errorCount24h: 1, lastError: String(error) };
    }
  }

  private async checkAgentsHealth(): Promise<ComponentHealth> {
    // Agents are assumed healthy if no critical errors
    return {
      status: 'up',
      latency: 10,
      errorCount24h: 0
    };
  }

  private async checkApiHealth(): Promise<ComponentHealth> {
    return {
      status: 'up',
      latency: 15,
      errorCount24h: 0
    };
  }

  private async checkStorageHealth(): Promise<ComponentHealth> {
    try {
      const fs = await import('fs');
      const path = await import('path');
      const dataDir = path.join(process.cwd(), 'data');

      if (!fs.existsSync(dataDir)) {
        fs.mkdirSync(dataDir, { recursive: true });
      }

      // Test write
      const testFile = path.join(dataDir, '.health-check');
      fs.writeFileSync(testFile, Date.now().toString());
      fs.unlinkSync(testFile);

      return { status: 'up', latency: 2, errorCount24h: 0 };
    } catch (error) {
      return { status: 'down', errorCount24h: 1, lastError: String(error) };
    }
  }

  /**
   * Get plant transparency metrics
   */
  async getPlantMetrics(): Promise<PlantTransparencyMetrics> {
    try {
      const fs = await import('fs');
      const path = await import('path');
      const chainFile = path.join(process.cwd(), 'data', 'plantchain.json');

      if (fs.existsSync(chainFile)) {
        const data = JSON.parse(fs.readFileSync(chainFile, 'utf-8'));
        const chain = data.chain || [];
        const now = new Date();
        const today = now.toISOString().split('T')[0];
        const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString();

        const varietyCounts: Record<string, number> = {};
        const regionCounts: Record<string, number> = {};
        let totalLineageDepth = 0;
        let plantsToday = 0;
        let plantsThisWeek = 0;
        let cloneCount = 0;

        for (const block of chain) {
          if (block.plant) {
            const plant = block.plant;

            // Count varieties
            if (plant.variety) {
              varietyCounts[plant.variety] = (varietyCounts[plant.variety] || 0) + 1;
            }

            // Count regions
            if (plant.location?.region) {
              regionCounts[plant.location.region] = (regionCounts[plant.location.region] || 0) + 1;
            }

            // Count by time
            if (block.timestamp?.startsWith(today)) {
              plantsToday++;
            }
            if (block.timestamp >= weekAgo) {
              plantsThisWeek++;
            }

            // Count clones
            if (plant.parentId) {
              cloneCount++;
              totalLineageDepth += plant.generation || 1;
            }
          }
        }

        const topVarieties = Object.entries(varietyCounts)
          .sort((a, b) => b[1] - a[1])
          .slice(0, 10)
          .map(([variety, count]) => ({ variety, count }));

        const geographicDistribution = Object.entries(regionCounts)
          .sort((a, b) => b[1] - a[1])
          .slice(0, 10)
          .map(([region, count]) => ({ region, count }));

        return {
          totalPlantsRegistered: chain.length - 1, // Exclude genesis
          plantsRegisteredToday: plantsToday,
          plantsRegisteredThisWeek: plantsThisWeek,
          totalClones: cloneCount,
          averageLineageDepth: cloneCount > 0 ? totalLineageDepth / cloneCount : 0,
          topVarieties,
          geographicDistribution
        };
      }
    } catch (error) {
      console.error('[TransparencyDashboard] Error getting plant metrics:', error);
    }

    return {
      totalPlantsRegistered: 0,
      plantsRegisteredToday: 0,
      plantsRegisteredThisWeek: 0,
      totalClones: 0,
      averageLineageDepth: 0,
      topVarieties: [],
      geographicDistribution: []
    };
  }

  /**
   * Get transport transparency metrics
   */
  async getTransportMetrics(): Promise<TransportTransparencyMetrics> {
    // Calculate from transport blockchain when available
    return {
      totalTransportEvents: 0,
      eventsToday: 0,
      eventsThisWeek: 0,
      totalDistanceMiles: 0,
      averageDistanceMiles: 0,
      totalCarbonKg: 0,
      carbonSavedVsTraditional: 0,
      transportMethods: [],
      verificationRate: 100
    };
  }

  /**
   * Get demand transparency metrics
   */
  async getDemandMetrics(): Promise<DemandTransparencyMetrics> {
    return {
      totalDemandSignals: 0,
      activeDemandSignals: 0,
      matchRate: 0,
      topRequestedVarieties: [],
      averageFulfillmentTime: 0,
      regionalDemand: []
    };
  }

  /**
   * Get environmental transparency metrics
   */
  async getEnvironmentalMetrics(): Promise<EnvironmentalTransparencyMetrics> {
    // Calculate environmental impact
    const traditionalFoodMiles = 1500;
    const localFoodMiles = 50;
    const carbonPerMile = 0.411; // kg CO2 per mile

    return {
      totalCarbonSavedKg: 0,
      waterSavedLiters: 0,
      foodMilesReduced: traditionalFoodMiles - localFoodMiles,
      wastePreventedKg: 0,
      localFoodPercentage: 100,
      sustainabilityScore: 95,
      monthlyTrend: []
    };
  }

  /**
   * Get agent transparency metrics
   */
  async getAgentMetrics(): Promise<AgentTransparencyMetrics> {
    const agentNames = [
      'PlantLineageAgent',
      'TransportTrackerAgent',
      'DemandForecastAgent',
      'VerticalFarmAgent',
      'EnvironmentAnalysisAgent',
      'MarketMatchingAgent',
      'SustainabilityAgent',
      'NetworkDiscoveryAgent',
      'QualityAssuranceAgent',
      'GrowerAdvisoryAgent'
    ];

    return {
      totalAgents: 10,
      activeAgents: 0,
      totalTasksCompleted: 0,
      totalTasksFailed: 0,
      averageTaskTime: 0,
      alertsGenerated24h: 0,
      agentStatus: agentNames.map(name => ({
        name,
        status: 'stopped' as const,
        tasksCompleted: 0,
        lastRun: null
      }))
    };
  }

  /**
   * Get blockchain transparency metrics
   */
  async getBlockchainMetrics(): Promise<BlockchainTransparencyMetrics> {
    try {
      const fs = await import('fs');
      const path = await import('path');
      const chainFile = path.join(process.cwd(), 'data', 'plantchain.json');

      if (fs.existsSync(chainFile)) {
        const data = JSON.parse(fs.readFileSync(chainFile, 'utf-8'));
        const chain = data.chain || [];

        return {
          totalBlocks: chain.length,
          chainValid: true, // TODO: Actually verify
          lastBlockTime: chain.length > 0 ? chain[chain.length - 1].timestamp : null,
          averageBlockTime: 0,
          totalTransactions: chain.length - 1,
          hashPower: 0,
          difficulty: data.difficulty || 4
        };
      }
    } catch (error) {
      console.error('[TransparencyDashboard] Error getting blockchain metrics:', error);
    }

    return {
      totalBlocks: 0,
      chainValid: true,
      lastBlockTime: null,
      averageBlockTime: 0,
      totalTransactions: 0,
      hashPower: 0,
      difficulty: 4
    };
  }

  /**
   * Get network transparency metrics
   */
  async getNetworkMetrics(): Promise<NetworkTransparencyMetrics> {
    return {
      totalGrowers: 0,
      totalConsumers: 0,
      activeConnections: 0,
      geographicCoverage: 0,
      averageConnectionsPerGrower: 0,
      networkGrowthRate: 0
    };
  }

  /**
   * Get recent activity
   */
  async getRecentActivity(limit: number = 20): Promise<RecentActivityItem[]> {
    const auditLog = getAuditLog();
    const entries = auditLog.getRecent(limit);

    return entries.map(entry => ({
      id: entry.id,
      timestamp: entry.timestamp,
      type: entry.action,
      description: entry.description,
      actor: entry.actor.name || entry.actor.id,
      resourceId: entry.resource?.id,
      importance: entry.severity === 'CRITICAL' || entry.severity === 'ERROR' ? 'high' :
        entry.severity === 'WARNING' ? 'medium' : 'low'
    }));
  }

  /**
   * Add an alert
   */
  addAlert(
    type: TransparencyAlert['type'],
    title: string,
    message: string,
    source: string
  ): TransparencyAlert {
    const alert: TransparencyAlert = {
      id: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      type,
      title,
      message,
      timestamp: new Date().toISOString(),
      acknowledged: false,
      source
    };

    this.alerts.push(alert);

    // Keep only last 100 alerts
    if (this.alerts.length > 100) {
      this.alerts = this.alerts.slice(-100);
    }

    return alert;
  }

  /**
   * Acknowledge an alert
   */
  acknowledgeAlert(alertId: string): boolean {
    const alert = this.alerts.find(a => a.id === alertId);
    if (alert) {
      alert.acknowledged = true;
      return true;
    }
    return false;
  }

  /**
   * Get active (unacknowledged) alerts
   */
  getActiveAlerts(): TransparencyAlert[] {
    return this.alerts.filter(a => !a.acknowledged);
  }

  /**
   * Get all alerts
   */
  getAllAlerts(): TransparencyAlert[] {
    return [...this.alerts];
  }

  /**
   * Generate a transparency report
   */
  async generateReport(startDate: string, endDate: string): Promise<TransparencyReport> {
    const dashboard = await this.getDashboard();

    const sections: TransparencyReportSection[] = [
      {
        title: 'Plant Registry',
        content: 'Summary of plant registration and lineage tracking.',
        metrics: [
          { label: 'Total Plants', value: dashboard.plants.totalPlantsRegistered },
          { label: 'This Week', value: dashboard.plants.plantsRegisteredThisWeek },
          { label: 'Total Clones', value: dashboard.plants.totalClones },
          { label: 'Avg Lineage Depth', value: dashboard.plants.averageLineageDepth.toFixed(2) }
        ]
      },
      {
        title: 'Transport & Logistics',
        content: 'Transport events and carbon footprint tracking.',
        metrics: [
          { label: 'Total Events', value: dashboard.transport.totalTransportEvents },
          { label: 'Total Miles', value: dashboard.transport.totalDistanceMiles },
          { label: 'Carbon Saved (kg)', value: dashboard.transport.carbonSavedVsTraditional },
          { label: 'Verification Rate', value: `${dashboard.transport.verificationRate}%` }
        ]
      },
      {
        title: 'Environmental Impact',
        content: 'Sustainability metrics and environmental benefits.',
        metrics: [
          { label: 'Carbon Saved (kg)', value: dashboard.environmental.totalCarbonSavedKg },
          { label: 'Water Saved (L)', value: dashboard.environmental.waterSavedLiters },
          { label: 'Food Miles Reduced', value: dashboard.environmental.foodMilesReduced },
          { label: 'Sustainability Score', value: dashboard.environmental.sustainabilityScore }
        ]
      },
      {
        title: 'System Health',
        content: 'Platform health and operational metrics.',
        metrics: [
          { label: 'Status', value: dashboard.systemHealth.status },
          { label: 'Uptime', value: `${Math.floor(dashboard.systemHealth.uptime / 3600000)}h` },
          { label: 'Active Agents', value: dashboard.agents.activeAgents },
          { label: 'Blockchain Blocks', value: dashboard.blockchain.totalBlocks }
        ]
      },
      {
        title: 'Audit & Compliance',
        content: 'Audit trail and data integrity status.',
        metrics: [
          { label: 'Total Audit Entries', value: dashboard.audit.totalEntries },
          { label: 'Last 24h', value: dashboard.audit.entriesLast24h },
          { label: 'Error Rate', value: `${(dashboard.audit.errorRate24h * 100).toFixed(2)}%` }
        ]
      }
    ];

    return {
      title: 'LocalGreenChain Transparency Report',
      generatedAt: new Date().toISOString(),
      period: { start: startDate, end: endDate },
      summary: {
        totalPlants: dashboard.plants.totalPlantsRegistered,
        totalTransportEvents: dashboard.transport.totalTransportEvents,
        carbonSavedKg: dashboard.environmental.totalCarbonSavedKg,
        systemHealth: dashboard.systemHealth.status,
        complianceStatus: 'compliant'
      },
      sections
    };
  }

  /**
   * Export dashboard data
   */
  async exportData(format: 'json' | 'csv' | 'summary'): Promise<string> {
    const dashboard = await this.getDashboard();

    switch (format) {
      case 'json':
        return JSON.stringify(dashboard, null, 2);

      case 'csv':
        const rows = [
          ['Metric', 'Value', 'Category'],
          ['Total Plants', dashboard.plants.totalPlantsRegistered, 'Plants'],
          ['Plants Today', dashboard.plants.plantsRegisteredToday, 'Plants'],
          ['Total Clones', dashboard.plants.totalClones, 'Plants'],
          ['System Status', dashboard.systemHealth.status, 'Health'],
          ['Audit Entries', dashboard.audit.totalEntries, 'Audit'],
          ['Active Alerts', dashboard.alerts.length, 'Alerts'],
          ['Blockchain Blocks', dashboard.blockchain.totalBlocks, 'Blockchain']
        ];
        return rows.map(r => r.join(',')).join('\n');

      case 'summary':
        return `
LOCALGREENCHAIN TRANSPARENCY DASHBOARD
======================================
Generated: ${dashboard.generatedAt}

SYSTEM HEALTH: ${dashboard.systemHealth.status.toUpperCase()}
Uptime: ${Math.floor(dashboard.systemHealth.uptime / 3600000)} hours

PLANTS
------
Total Registered: ${dashboard.plants.totalPlantsRegistered}
Registered Today: ${dashboard.plants.plantsRegisteredToday}
Total Clones: ${dashboard.plants.totalClones}

BLOCKCHAIN
----------
Total Blocks: ${dashboard.blockchain.totalBlocks}
Chain Valid: ${dashboard.blockchain.chainValid ? 'Yes' : 'No'}
Difficulty: ${dashboard.blockchain.difficulty}

AUDIT
-----
Total Entries: ${dashboard.audit.totalEntries}
Last 24h: ${dashboard.audit.entriesLast24h}
Error Rate: ${(dashboard.audit.errorRate24h * 100).toFixed(2)}%

EVENTS
------
Total Events: ${dashboard.events.totalEvents}
Active Subscriptions: ${dashboard.events.activeSubscriptions}
Active Webhooks: ${dashboard.events.activeWebhooks}

ALERTS
------
Active Alerts: ${dashboard.alerts.length}
        `.trim();

      default:
        return JSON.stringify(dashboard);
    }
  }
}

// Singleton instance
let dashboardInstance: TransparencyDashboard | null = null;

export function getTransparencyDashboard(): TransparencyDashboard {
  if (!dashboardInstance) {
    dashboardInstance = new TransparencyDashboard();
  }
  return dashboardInstance;
}

export default TransparencyDashboard;
