import { Router, Request, Response, NextFunction } from 'express';
import trainingController from '../controllers/training.controller';
import { authenticate, optionalAuth } from '../middleware/auth.middleware';
import { requirePermission } from '../middleware/rbac.middleware';
import { permissionService } from '../services/permission.service';

const router = Router();

// ---------------------------------------------------------------------------
// injectTeilnahmenFlag
//
// Sets req.canSeeTeilnahmen = true for users with kalender:create.
// Regular Mitglieder see only attendance counts; officers see the full list.
// ---------------------------------------------------------------------------

async function injectTeilnahmenFlag(
  req: Request,
  _res: Response,
  next: NextFunction
): Promise<void> {
  try {
    if (req.user) {
      const groups: string[] = req.user?.groups ?? [];
      (req as any).canSeeTeilnahmen =
        groups.includes('dashboard_admin') ||
        permissionService.hasPermission(groups, 'kalender:create');
    }
  } catch (_err) {
    // Non-fatal — default to restricted view
  }
  next();
}

// ---------------------------------------------------------------------------
// Routes
// ---------------------------------------------------------------------------

/**
 * GET /api/training
 * Public list of upcoming events (limit param).
 * Optional auth to include own RSVP status.
 */
router.get('/', optionalAuth, trainingController.getUpcoming);

/**
 * GET /api/training/calendar?from=<ISO>&to=<ISO>
 * Events in a date range for the calendar view.
 * Optional auth to include own RSVP status.
 */
router.get('/calendar', optionalAuth, trainingController.getCalendarRange);

/**
 * GET /api/training/calendar.ics?token=<calendarToken>
 * iCal export — authenticated via per-user calendar token OR Bearer JWT.
 * No `authenticate` enforced here; controller resolves auth itself.
 * See training.controller.ts for full auth tradeoff discussion.
 */
router.get('/calendar.ics', optionalAuth, trainingController.getIcalExport);

/**
 * GET /api/training/calendar-token
 * Returns (or creates) the user's personal iCal subscribe token + URL.
 * Requires authentication.
 */
router.get('/calendar-token', authenticate, trainingController.getCalendarToken);

/**
 * GET /api/training/stats?year=<YYYY>
 * Annual participation stats.
 * Requires Kommandant or above (requirePermission('kalender:create')).
 */
router.get(
  '/stats',
  authenticate,
  requirePermission('kalender:create'),
  trainingController.getStats
);

/**
 * GET /api/training/:id
 * Single event with attendance counts.
 * Gruppenführer+ also gets the full attendee list.
 */
router.get(
  '/:id',
  authenticate,
  injectTeilnahmenFlag,
  trainingController.getById
);

/**
 * POST /api/training
 * Create a new training event.
 * Requires Gruppenführer or above (requirePermission('kalender:create')).
 */
router.post(
  '/',
  authenticate,
  requirePermission('kalender:create'),
  trainingController.createEvent
);

/**
 * PATCH /api/training/:id
 * Update an existing event.
 * Requires Gruppenführer or above.
 */
router.patch(
  '/:id',
  authenticate,
  requirePermission('kalender:create'),
  trainingController.updateEvent
);

/**
 * DELETE /api/training/:id
 * Soft-cancel an event (sets abgesagt=true, records reason).
 * Requires Kommandant or above.
 */
router.delete(
  '/:id',
  authenticate,
  requirePermission('kalender:create'),
  trainingController.cancelEvent
);

/**
 * PATCH /api/training/:id/attendance
 * Any authenticated member updates their own RSVP.
 */
router.patch(
  '/:id/attendance',
  authenticate,
  trainingController.updateRsvp
);

/**
 * POST /api/training/:id/attendance/mark
 * Gruppenführer bulk-marks who actually appeared.
 */
router.post(
  '/:id/attendance/mark',
  authenticate,
  requirePermission('kalender:create'),
  trainingController.markAttendance
);

export default router;
