import { Router, Request, Response, NextFunction } from 'express';
import { campaignEmailsService } from './campaign-emails.service';
import { campaignsService } from '../campaigns/campaigns.service';
import {
  sendCampaignEmailSchema,
  trackMailtoSchema,
  listCampaignEmailsSchema,
} from './campaign-emails.schemas';
import { validate } from '../../../middleware/validate';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { emailRateLimit } from '../../../middleware/rate-limit';
import { INFLUENCE_ROLES } from '../../../utils/roles';

// --- Public Routes (no auth) ---
const publicRouter = Router();

// POST /api/campaigns/:slug/send-email
publicRouter.post(
  '/:slug/send-email',
  emailRateLimit,
  validate(sendCampaignEmailSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const slug = req.params.slug as string;
      const senderIp = req.ip || req.socket.remoteAddress;
      const result = await campaignEmailsService.sendEmail(slug, req.body, senderIp);
      res.status(201).json(result);
    } catch (err) {
      next(err);
    }
  }
);

// POST /api/campaigns/:slug/track-mailto
publicRouter.post(
  '/:slug/track-mailto',
  emailRateLimit,
  validate(trackMailtoSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const slug = req.params.slug as string;
      const senderIp = req.ip || req.socket.remoteAddress;
      const result = await campaignEmailsService.trackMailto(slug, req.body, senderIp);
      res.status(201).json(result);
    } catch (err) {
      next(err);
    }
  }
);

// --- Admin Routes (auth required) ---
const adminRouter = Router();
adminRouter.use(authenticate);
adminRouter.use(requireRole(...INFLUENCE_ROLES));

// GET /api/campaigns/:id/emails — requires ownership (SUPER_ADMIN bypasses)
adminRouter.get(
  '/:id/emails',
  validate(listCampaignEmailsSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      // Access check via campaignsService — throws 404 if not owned.
      await campaignsService.findById(id, req.user!);
      const result = await campaignEmailsService.listByCampaign(id, req.query as any);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/campaigns/:id/email-stats — requires ownership (SUPER_ADMIN bypasses)
adminRouter.get(
  '/:id/email-stats',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      await campaignsService.findById(id, req.user!);
      const stats = await campaignEmailsService.getStats(id);
      res.json(stats);
    } catch (err) {
      next(err);
    }
  }
);

export { publicRouter as campaignEmailsPublicRouter, adminRouter as campaignEmailsAdminRouter };
