import { Router, Request, Response, NextFunction } from 'express';
import { authenticate } from '../../middleware/auth.middleware';
import { requireRole } from '../../middleware/rbac.middleware';
import { ADMIN_ROLES } from '../../utils/roles';
import {
  getDashboardSummary,
  getSystemInfo,
  getContainerStatuses,
  getWeather,
  getApiMetrics,
  getTimeSeries,
  getContainerResources,
  getActivityFeed,
  getConnectivity,
  getTodayEvents,
  getChatSummary,
  getTopVideos,
  getRecentComments,
  getUpcomingShifts,
  getRecentSignups,
  getGiteaActivity,
  getRocketChatStats,
  getVaultwardenAdoption,
  getListmonkCampaigns,
} from './dashboard.service';

const router = Router();
router.use(authenticate);
router.use(requireRole(...ADMIN_ROLES));

// GET /api/dashboard/summary — platform counts
router.get('/summary', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const summary = await getDashboardSummary();
    res.json(summary);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/system — hardware + OS info (SUPER_ADMIN only)
router.get('/system', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const info = getSystemInfo();
    res.json(info);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/containers — Docker container statuses (SUPER_ADMIN only)
router.get('/containers', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const containers = await getContainerStatuses();
    res.json(containers);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/weather — weather from map settings location
router.get('/weather', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const weather = await getWeather();
    if (!weather) {
      res.json({ error: 'No location configured or weather unavailable' });
      return;
    }
    res.json(weather);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/api-metrics — Prometheus API performance metrics (SUPER_ADMIN only)
router.get('/api-metrics', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const metrics = await getApiMetrics();
    if (!metrics) {
      res.json({ error: 'Prometheus unavailable' });
      return;
    }
    res.json(metrics);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/time-series — predefined-key time-series from Prometheus (SUPER_ADMIN only)
const ALLOWED_METRIC_KEYS = new Set([
  'request_rate_2xx', 'request_rate_4xx', 'request_rate_5xx',
  'latency_p50', 'latency_p95', 'latency_p99',
  'email_sent_rate', 'email_failed_rate', 'email_queue_size',
  'cpu_usage', 'memory_usage', 'active_sessions', 'login_rate',
]);
const ALLOWED_RANGES = new Set(['1h', '6h', '24h']);
const ALLOWED_STEPS = new Set(['1m', '5m', '15m']);

router.get('/time-series', requireRole('SUPER_ADMIN'), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const metricsParam = (req.query.metrics as string) || '';
    const range = (req.query.range as string) || '1h';
    const step = (req.query.step as string) || '5m';

    if (!ALLOWED_RANGES.has(range)) {
      res.status(400).json({ error: 'Invalid range. Allowed: 1h, 6h, 24h' });
      return;
    }
    if (!ALLOWED_STEPS.has(step)) {
      res.status(400).json({ error: 'Invalid step. Allowed: 1m, 5m, 15m' });
      return;
    }

    const metricKeys = metricsParam.split(',').filter(k => ALLOWED_METRIC_KEYS.has(k.trim()));
    if (metricKeys.length === 0) {
      res.status(400).json({ error: 'No valid metric keys provided' });
      return;
    }

    const data = await getTimeSeries(metricKeys, range, step);
    res.json(data);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/container-resources — cAdvisor container CPU/memory/network (SUPER_ADMIN only)
router.get('/container-resources', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const containers = await getContainerResources();
    res.json({ containers });
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/activity — recent activity feed (paginated)
router.get('/activity', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const page = Math.max(1, parseInt(req.query.page as string) || 1);
    const limit = Math.min(50, Math.max(1, parseInt(req.query.limit as string) || 20));
    const module = (req.query.module as string) || 'all';
    const result = await getActivityFeed({ page, limit, module });
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/connectivity — service connectivity checks
router.get('/connectivity', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const connectivity = await getConnectivity();
    res.json(connectivity);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/today-events — today's events from Gancio
router.get('/today-events', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const events = await getTodayEvents();
    res.json(events);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/chat-summary — recent messages from Rocket.Chat
router.get('/chat-summary', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const summary = await getChatSummary();
    res.json(summary);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/upcoming-shifts — next 5 shifts
router.get('/upcoming-shifts', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await getUpcomingShifts();
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/recent-signups — latest 8 shift signups
router.get('/recent-signups', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await getRecentSignups();
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/top-videos — top 5 videos by view count (if media enabled)
router.get('/top-videos', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await getTopVideos();
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/recent-comments — latest 8 visible comments (if media enabled)
router.get('/recent-comments', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await getRecentComments();
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/gitea-activity — Gitea repos, users, recent commits (SUPER_ADMIN only)
router.get('/gitea-activity', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const data = await getGiteaActivity();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/rocketchat-stats — RC users, channels, messages (SUPER_ADMIN only)
router.get('/rocketchat-stats', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const data = await getRocketChatStats();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/vaultwarden-adoption — VW user adoption stats (SUPER_ADMIN only)
router.get('/vaultwarden-adoption', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const data = await getVaultwardenAdoption();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

// GET /api/dashboard/listmonk-campaigns — Listmonk campaign performance (SUPER_ADMIN only)
router.get('/listmonk-campaigns', requireRole('SUPER_ADMIN'), async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const data = await getListmonkCampaigns();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

export const dashboardRouter = router;
