import { Router } from 'express';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { validate } from '../../../middleware/validate';
import { smsCampaignsService } from './sms-campaigns.service';
import { createSmsCampaignSchema, updateSmsCampaignSchema } from './sms-campaigns.schemas';
import { smsQueueService } from '../../../services/sms-queue.service';
import { eventBus } from '../../../services/event-bus.service';
import { BROADCAST_ROLES } from '../../../utils/roles';

const router = Router();

// All routes require authentication + broadcast admin role
router.use(authenticate, requireRole(...BROADCAST_ROLES));

// GET /api/sms/campaigns — list all campaigns
router.get('/', async (req, res, next) => {
  try {
    const page = Math.max(1, Number(req.query.page) || 1);
    const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 50));
    const result = await smsCampaignsService.findAll(page, limit);
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/campaigns/queue-stats — get BullMQ queue stats
router.get('/queue-stats', async (_req, res, next) => {
  try {
    const stats = await smsQueueService.getStats();
    res.json(stats);
  } catch (err) { next(err); }
});

// POST /api/sms/campaigns — create a new campaign
router.post('/', validate(createSmsCampaignSchema), async (req, res, next) => {
  try {
    const campaign = await smsCampaignsService.create(req.body, req.user!.id);
    res.status(201).json(campaign);
  } catch (err) { next(err); }
});

// GET /api/sms/campaigns/:id — get a single campaign
router.get('/:id', async (req, res, next) => {
  try {
    const campaign = await smsCampaignsService.findById(req.params.id as string);
    if (!campaign) { res.status(404).json({ error: 'Campaign not found' }); return; }
    res.json(campaign);
  } catch (err) { next(err); }
});

// PUT /api/sms/campaigns/:id — update a campaign
router.put('/:id', validate(updateSmsCampaignSchema), async (req, res, next) => {
  try {
    const campaign = await smsCampaignsService.update(req.params.id as string, req.body);
    res.json(campaign);
  } catch (err) { next(err); }
});

// DELETE /api/sms/campaigns/:id — delete a campaign
router.delete('/:id', async (req, res, next) => {
  try {
    await smsCampaignsService.delete(req.params.id as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// POST /api/sms/campaigns/:id/start — start sending
router.post('/:id/start', async (req, res, next) => {
  try {
    const campaign = await smsCampaignsService.findById(req.params.id as string);
    const result = await smsCampaignsService.start(req.params.id as string);

    if (campaign) {
      eventBus.publish('sms.campaign.started', {
        campaignId: campaign.id,
        title: campaign.name,
        recipientCount: campaign.totalRecipients,
      });
    }

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

// POST /api/sms/campaigns/:id/pause — pause sending
router.post('/:id/pause', async (req, res, next) => {
  try {
    await smsCampaignsService.pause(req.params.id as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// POST /api/sms/campaigns/:id/resume — resume sending
router.post('/:id/resume', async (req, res, next) => {
  try {
    const result = await smsCampaignsService.resume(req.params.id as string);
    res.json(result);
  } catch (err) { next(err); }
});

// GET /api/sms/campaigns/:id/status — live campaign status
router.get('/:id/status', async (req, res, next) => {
  try {
    const status = await smsCampaignsService.getStatus(req.params.id as string);
    res.json(status);
  } catch (err) { next(err); }
});

// GET /api/sms/campaigns/:id/recipients — campaign recipients
router.get('/:id/recipients', async (req, res, next) => {
  try {
    const page = Math.max(1, Number(req.query.page) || 1);
    const limit = Math.min(500, Math.max(1, Number(req.query.limit) || 100));
    const statusFilter = req.query.status as string | undefined;
    const result = await smsCampaignsService.getRecipients(req.params.id as string, page, limit, statusFilter);
    res.json(result);
  } catch (err) { next(err); }
});

export const smsCampaignsRouter = router;
