import { Router, Request, Response, NextFunction } from 'express';
import { campaignsService } from './campaigns.service';
import { createCampaignSchema, updateCampaignSchema, listCampaignsSchema } from './campaigns.schemas';
import { validate } from '../../../middleware/validate';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { INFLUENCE_ROLES } from '../../../utils/roles';
import { eventBus } from '../../../services/event-bus.service';

const router = Router();

// All campaign admin routes require authentication + admin role
router.use(authenticate);
router.use(requireRole(...INFLUENCE_ROLES));

// GET /api/campaigns — list campaigns with pagination/filters
router.get(
  '/',
  validate(listCampaignsSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await campaignsService.findAll(req.query as any, req.user!);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/campaigns/:id — get single campaign
router.get(
  '/:id',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const campaign = await campaignsService.findById(id, req.user!);
      res.json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

// POST /api/campaigns — create campaign
router.post(
  '/',
  validate(createCampaignSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const campaign = await campaignsService.create(req.body, req.user!);
      eventBus.publish('campaign.created', {
        campaignId: campaign.id,
        title: campaign.title,
        slug: campaign.slug,
        createdByUserId: campaign.createdByUserId!,
      });
      res.status(201).json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

// PUT /api/campaigns/:id — update campaign
router.put(
  '/:id',
  validate(updateCampaignSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const campaign = await campaignsService.update(id, req.body, req.user!);
      eventBus.publish('campaign.updated', {
        campaignId: campaign.id,
        title: campaign.title,
        slug: campaign.slug,
        changes: Object.keys(req.body),
      });
      res.json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

// DELETE /api/campaigns/:id — delete campaign
router.delete(
  '/:id',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const campaign = await campaignsService.findById(id, req.user!);
      await campaignsService.delete(id, req.user!);
      eventBus.publish('campaign.deleted', {
        campaignId: campaign.id,
        title: campaign.title,
        slug: campaign.slug,
      });
      res.status(204).send();
    } catch (err) {
      next(err);
    }
  }
);

export { router as campaignsRouter };
