import { Router } from 'express';
import type { Request, Response, NextFunction } from 'express';
import { requireRole } from '../../middleware/rbac.middleware';
import { SOCIAL_ROLES } from '../../utils/roles';
import { spotlightService } from './spotlight.service';
import {
  nominateSchema,
  updateSpotlightSchema,
  featureSchema,
  listSpotlightsSchema,
} from './spotlight.schemas';

const router = Router();

// ── Public / authenticated user routes ──────────────────────────────

/** GET /api/social/spotlight/featured — current month's featured spotlights */
router.get('/featured', async (_req: Request, res: Response, next: NextFunction) => {
  try {
    const spotlights = await spotlightService.getCurrentFeatured();
    res.json({ spotlights });
  } catch (err) {
    next(err);
  }
});

/** GET /api/social/spotlight/leaderboard — public leaderboard (filtered by opt-in) */
router.get('/leaderboard', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const type = (req.query.type as string) || 'canvass';
    if (!['canvass', 'shifts', 'campaigns'].includes(type)) {
      return res.status(400).json({ error: { message: 'Invalid leaderboard type' } });
    }
    const limit = Math.min(parseInt(req.query.limit as string) || 10, 50);
    const leaderboard = await spotlightService.getPublicLeaderboard(
      type as 'canvass' | 'shifts' | 'campaigns',
      limit,
    );
    res.json({ leaderboard, type });
  } catch (err) {
    next(err);
  }
});

/** GET /api/social/spotlight/wall-of-fame — all featured spotlights */
router.get('/wall-of-fame', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const page = Math.max(1, parseInt(req.query.page as string) || 1);
    const limit = Math.min(Math.max(1, parseInt(req.query.limit as string) || 20), 100);
    const result = await spotlightService.getWallOfFame(page, limit);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

/** GET /api/social/spotlight/opt-in-status — current user's leaderboard opt-in */
router.get('/opt-in-status', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await spotlightService.getOptInStatus(req.user!.id);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

/** POST /api/social/spotlight/opt-in — opt in to leaderboard */
router.post('/opt-in', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await spotlightService.optIn(req.user!.id);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

/** POST /api/social/spotlight/opt-out — opt out of leaderboard */
router.post('/opt-out', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await spotlightService.optOut(req.user!.id);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

// ── Admin routes ────────────────────────────────────────────────────

/** GET /api/social/spotlight/admin — list all spotlights */
router.get(
  '/admin',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { page, limit, status } = listSpotlightsSchema.parse(req.query);
      const result = await spotlightService.listAll(page, limit, status as any);
      res.json(result);
    } catch (err) {
      next(err);
    }
  },
);

/** POST /api/social/spotlight/admin/nominate — nominate a volunteer */
router.post(
  '/admin/nominate',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const data = nominateSchema.parse(req.body);
      const spotlight = await spotlightService.nominate(data, req.user!.id);
      res.status(201).json(spotlight);
    } catch (err) {
      next(err);
    }
  },
);

/** PUT /api/social/spotlight/admin/:id — update headline/story */
router.put(
  '/admin/:id',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const data = updateSpotlightSchema.parse(req.body);
      const spotlight = await spotlightService.update(req.params.id as string, data);
      res.json(spotlight);
    } catch (err) {
      next(err);
    }
  },
);

/** POST /api/social/spotlight/admin/:id/approve — approve a nomination */
router.post(
  '/admin/:id/approve',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const spotlight = await spotlightService.approve(req.params.id as string, req.user!.id);
      res.json(spotlight);
    } catch (err) {
      next(err);
    }
  },
);

/** POST /api/social/spotlight/admin/:id/feature — feature for a month */
router.post(
  '/admin/:id/feature',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { month } = featureSchema.parse(req.body);
      const spotlight = await spotlightService.feature(req.params.id as string, month);
      res.json(spotlight);
    } catch (err) {
      next(err);
    }
  },
);

/** POST /api/social/spotlight/admin/:id/archive — archive a spotlight */
router.post(
  '/admin/:id/archive',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const spotlight = await spotlightService.archive(req.params.id as string);
      res.json(spotlight);
    } catch (err) {
      next(err);
    }
  },
);

/** DELETE /api/social/spotlight/admin/:id — delete a spotlight */
router.delete(
  '/admin/:id',
  requireRole(...SOCIAL_ROLES),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await spotlightService.delete(req.params.id as string);
      res.json(result);
    } catch (err) {
      next(err);
    }
  },
);

export const spotlightRouter = router;
