// Backend Routes for Anomaly Detection API
// This is a template - integrate with your backend framework

import express, { Router, Request, Response } from 'express';
import {
  Anomaly,
  AnomalyMetrics,
  AlertRule,
  SensorHealth,
} from '../modules/anomalyDetection/types';

const router: Router = express.Router();

// Mock data store (replace with actual database)
const anomalyStore: Map<string, Anomaly> = new Map();
const alertRuleStore: Map<string, AlertRule> = new Map();
const sensorHealthStore: Map<string, SensorHealth> = new Map();

/**
 * GET /api/ai/anomalies/active
 * Fetch all active anomalies
 */
router.get('/active', (req: Request, res: Response) => {
  const active = Array.from(anomalyStore.values()).filter(
    (a) => a.status === 'active'
  );
  res.json(active);
});

/**
 * GET /api/ai/anomalies/:id
 * Fetch single anomaly by ID
 */
router.get('/:id', (req: Request, res: Response) => {
  const anomaly = anomalyStore.get(req.params.id);
  if (!anomaly) {
    return res.status(404).json({ error: 'Anomaly not found' });
  }
  res.json(anomaly);
});

/**
 * GET /api/ai/anomalies/history?days=30
 * Fetch historical anomalies
 */
router.get('/history', (req: Request, res: Response) => {
  const days = parseInt(req.query.days as string) || 30;
  const cutoff = new Date();
  cutoff.setDate(cutoff.getDate() - days);

  const history = Array.from(anomalyStore.values()).filter(
    (a) => new Date(a.detectedAt) >= cutoff
  );
  res.json(history);
});

/**
 * GET /api/ai/anomalies/metrics
 * Get KPI metrics summary
 */
router.get('/metrics', (req: Request, res: Response) => {
  const anomalies = Array.from(anomalyStore.values());
  const active = anomalies.filter((a) => a.status === 'active');

  const metrics: AnomalyMetrics = {
    activeCount: active.length,
    avgConfidence:
      active.length > 0
        ? active.reduce((sum, a) => sum + a.confidence, 0) / active.length
        : 0,
    mttrMinutes: calculateMTTR(anomalies),
    falsePosRate: calculateFalsePositiveRate(anomalies),
    resolvedToday: anomalies.filter((a) => a.status === 'resolved').length,
    criticalCount: active.filter((a) => a.severity >= 9.0).length,
    highCount: active.filter((a) => a.severity >= 7.0 && a.severity < 9.0)
      .length,
    mediumCount: active.filter((a) => a.severity >= 5.0 && a.severity < 7.0)
      .length,
    lowCount: active.filter((a) => a.severity < 5.0).length,
  };

  res.json(metrics);
});

/**
 * POST /api/ai/anomalies/:id/dismiss
 * Dismiss an anomaly with reason
 */
router.post('/:id/dismiss', (req: Request, res: Response) => {
  const anomaly = anomalyStore.get(req.params.id);
  if (!anomaly) {
    return res.status(404).json({ error: 'Anomaly not found' });
  }

  const { reason } = req.body;

  anomaly.status = 'resolved';
  anomaly.auditTrail.push({
    timestamp: new Date(),
    action: `dismiss: ${reason || 'no reason provided'}`,
    actor: {
      userId: 'current_user',
      name: 'System User',
      role: 'operator',
    },
    details: `Dismissed with reason: ${reason}`,
  });

  anomalyStore.set(req.params.id, anomaly);
  res.json(anomaly);
});

/**
 * GET /api/ai/alert-rules
 * Get all alert rules
 */
router.get('/alert-rules', (req: Request, res: Response) => {
  res.json(Array.from(alertRuleStore.values()));
});

/**
 * POST /api/ai/alert-rules
 * Create new alert rule
 */
router.post('/alert-rules', (req: Request, res: Response) => {
  const rule: AlertRule = {
    id: `rule_${Date.now()}`,
    sensorType: req.body.sensorType,
    threshold: req.body.threshold,
    severity: req.body.severity,
    enabled: true,
    createdAt: new Date(),
    updatedBy: 'current_user',
  };

  alertRuleStore.set(rule.id, rule);
  res.status(201).json(rule);
});

/**
 * PUT /api/ai/alert-rules/:id
 * Update alert rule
 */
router.put('/alert-rules/:id', (req: Request, res: Response) => {
  const rule = alertRuleStore.get(req.params.id);
  if (!rule) {
    return res.status(404).json({ error: 'Rule not found' });
  }

  const updated: AlertRule = {
    ...rule,
    ...req.body,
    updatedBy: 'current_user',
  };

  alertRuleStore.set(req.params.id, updated);
  res.json(updated);
});

/**
 * DELETE /api/ai/alert-rules/:id
 * Delete alert rule
 */
router.delete('/alert-rules/:id', (req: Request, res: Response) => {
  alertRuleStore.delete(req.params.id);
  res.json({ success: true });
});

/**
 * GET /api/ai/sensors/health
 * Get sensor health scores
 */
router.get('/sensors/health', (req: Request, res: Response) => {
  res.json(Array.from(sensorHealthStore.values()));
});

/**
 * GET /api/ai/anomalies/export?format=csv&startDate=...&endDate=...
 * Export anomalies report
 */
router.get('/export', (req: Request, res: Response) => {
  const { format, startDate, endDate } = req.query;
  const start = new Date(startDate as string);
  const end = new Date(endDate as string);

  const filtered = Array.from(anomalyStore.values()).filter(
    (a) => new Date(a.detectedAt) >= start && new Date(a.detectedAt) <= end
  );

  if (format === 'csv') {
    // Generate CSV
    const csv = generateCSV(filtered);
    res.set('Content-Type', 'text/csv');
    res.set('Content-Disposition', 'attachment; filename="anomalies.csv"');
    res.send(csv);
  } else if (format === 'pdf') {
    // Generate PDF (would use a library like pdfkit)
    res.set('Content-Type', 'application/pdf');
    res.json({ error: 'PDF export not yet implemented' });
  }
});

// Helper functions
function calculateMTTR(anomalies: Anomaly[]): number {
  const resolved = anomalies.filter((a) => a.status === 'resolved');
  if (resolved.length === 0) return 0;

  const totalTime = resolved.reduce((sum, a) => {
    const lastAudit = a.auditTrail[a.auditTrail.length - 1];
    const detectedTime = new Date(a.detectedAt).getTime();
    const resolvedTime = lastAudit
      ? new Date(lastAudit.timestamp).getTime()
      : detectedTime;
    return sum + (resolvedTime - detectedTime);
  }, 0);

  return totalTime / (resolved.length * 60000); // minutes
}

function calculateFalsePositiveRate(anomalies: Anomaly[]): number {
  if (anomalies.length === 0) return 0;

  const dismissed = anomalies.filter(
    (a) =>
      a.status === 'resolved' &&
      a.auditTrail.some((e) => e.action.includes('dismiss'))
  );

  return (dismissed.length / anomalies.length) * 100;
}

function generateCSV(anomalies: Anomaly[]): string {
  const headers = [
    'ID',
    'Asset',
    'Severity',
    'Confidence',
    'Status',
    'Detected At',
  ];
  const rows = anomalies.map((a) => [
    a.id,
    a.assetName,
    a.severity,
    a.confidence,
    a.status,
    new Date(a.detectedAt).toISOString(),
  ]);

  return (
    headers.join(',') +
    '\n' +
    rows.map((row) => row.join(',')).join('\n')
  );
}

export default router;
