import { Router, Request, Response, NextFunction } from 'express';
import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
import { redis } from '../../../config/redis';
import { campaignsService } from './campaigns.service';
import { createUserCampaignSchema, updateUserCampaignSchema } from './campaigns.schemas';
import { validate } from '../../../middleware/validate';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireNonTemp } from '../../../middleware/rbac.middleware';

const campaignSubmitRateLimit = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 5,
  standardHeaders: true,
  legacyHeaders: false,
  store: new RedisStore({
    sendCommand: (command: string, ...args: string[]) => redis.call(command, ...args) as Promise<any>,
    prefix: 'rl:campaign-submit:',
  }),
  message: {
    error: {
      message: 'Too many campaign submissions, please try again later',
      code: 'CAMPAIGN_SUBMIT_RATE_LIMIT_EXCEEDED',
    },
  },
});

const router = Router();

// All user campaign routes require auth + non-temp
router.use(authenticate);
router.use(requireNonTemp);

// POST /api/campaigns/user/submit — create a user-generated campaign
router.post(
  '/user/submit',
  campaignSubmitRateLimit,
  validate(createUserCampaignSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const campaign = await campaignsService.createUserCampaign(req.body, req.user!);
      res.status(201).json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/campaigns/user/my-campaigns — list own campaigns
router.get(
  '/user/my-campaigns',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const campaigns = await campaignsService.findUserCampaigns(req.user!.id);
      res.json(campaigns);
    } catch (err) {
      next(err);
    }
  }
);

// PUT /api/campaigns/user/:id — edit own campaign
router.put(
  '/user/:id',
  validate(updateUserCampaignSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const campaign = await campaignsService.updateUserCampaign(id, req.body, req.user!);
      res.json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

export { router as campaignUserRouter };
