import { Router } from 'express';
import { requireRole } from '../../middleware/rbac.middleware';
import { INFLUENCE_ROLES } from '../../utils/roles';
import { impactStoriesService } from './impact-stories.service';
import { createStorySchema, updateStorySchema, listStoriesSchema } from './impact-stories.schemas';
import { eventBus } from '../../services/event-bus.service';

const router = Router();

// --- Admin routes (require admin role) ---

router.post('/', requireRole(...INFLUENCE_ROLES), async (req, res, next) => {
  try {
    const data = createStorySchema.parse(req.body);
    const story = await impactStoriesService.create(data, req.user!.id);
    res.status(201).json(story);
  } catch (err) {
    next(err);
  }
});

router.put('/:id', requireRole(...INFLUENCE_ROLES), async (req, res, next) => {
  try {
    const data = updateStorySchema.parse(req.body);
    const story = await impactStoriesService.update(req.params.id as string, data);
    res.json(story);
  } catch (err) {
    next(err);
  }
});

router.delete('/:id', requireRole(...INFLUENCE_ROLES), async (req, res, next) => {
  try {
    const result = await impactStoriesService.delete(req.params.id as string);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

router.post('/:id/publish', requireRole(...INFLUENCE_ROLES), async (req, res, next) => {
  try {
    const story = await impactStoriesService.publish(req.params.id as string);
    // Fire-and-forget: notify participants
    impactStoriesService.notifyParticipants(story.id).catch(() => {});

    eventBus.publish('social.impact-story.published', {
      storyId: story.id,
      title: story.title,
      authorUserId: story.createdByUserId || req.user!.id,
      campaignId: story.campaignId ?? null,
    });

    res.json(story);
  } catch (err) {
    next(err);
  }
});

router.post('/:id/archive', requireRole(...INFLUENCE_ROLES), async (req, res, next) => {
  try {
    const story = await impactStoriesService.archive(req.params.id as string);
    res.json(story);
  } catch (err) {
    next(err);
  }
});

// --- Authenticated routes (any logged-in user) ---

router.get('/', async (req, res, next) => {
  try {
    const { page, limit, campaignId, status } = listStoriesSchema.parse(req.query);
    // Admin users can filter by status; regular users see published only
    const userRoles = req.user!.roles || [req.user!.role];
    const isAdmin = userRoles.some((r: string) =>
      (INFLUENCE_ROLES as string[]).includes(r),
    );

    if (isAdmin && (campaignId || status)) {
      const result = await impactStoriesService.listAdmin(page, limit, campaignId, status);
      res.json(result);
    } else {
      const result = await impactStoriesService.listPublished(page, limit);
      res.json(result);
    }
  } catch (err) {
    next(err);
  }
});

router.get('/campaign/:campaignId', async (req, res, next) => {
  try {
    const { page, limit } = listStoriesSchema.parse(req.query);
    const campaignId = req.params.campaignId as string;
    const result = await impactStoriesService.listByCampaign(campaignId, page, limit);
    res.json(result);
  } catch (err) {
    next(err);
  }
});

router.get('/:id', async (req, res, next) => {
  try {
    const story = await impactStoriesService.findById(req.params.id as string);
    res.json(story);
  } catch (err) {
    next(err);
  }
});

export const impactStoriesRouter = router;
