import { Router, Request, Response, NextFunction } from 'express';
import { petitionsService } from './petitions.service';
import {
  createPetitionSchema, updatePetitionSchema, listPetitionsSchema,
  listSignaturesSchema, updateSignatureStatusSchema,
  moderatePetitionSchema, listModerationQueueSchema,
} from './petitions.schemas';
import { validate } from '../../../middleware/validate';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { INFLUENCE_ROLES } from '../../../utils/roles';

const router = Router();

router.use(authenticate);
router.use(requireRole(...INFLUENCE_ROLES));

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

// GET /api/petitions/moderation/queue — moderation queue
router.get(
  '/moderation/queue',
  validate(listModerationQueueSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await petitionsService.findModerationQueue(req.query as any);
      res.json(result);
    } catch (err) { next(err); }
  }
);

// GET /api/petitions/moderation/stats — moderation stats
router.get(
  '/moderation/stats',
  async (_req: Request, res: Response, next: NextFunction) => {
    try {
      const stats = await petitionsService.getModerationStats();
      res.json(stats);
    } catch (err) { next(err); }
  }
);

// PATCH /api/petitions/moderation/:id — moderate petition
router.patch(
  '/moderation/:id',
  validate(moderatePetitionSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const petition = await petitionsService.moderatePetition(id, req.body, req.user!.id);
      res.json(petition);
    } catch (err) { next(err); }
  }
);

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

// POST /api/petitions — create petition
router.post(
  '/',
  validate(createPetitionSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const petition = await petitionsService.create(req.body, req.user!);
      res.status(201).json(petition);
    } catch (err) { next(err); }
  }
);

// PUT /api/petitions/:id — update petition
router.put(
  '/:id',
  validate(updatePetitionSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const petition = await petitionsService.update(id, req.body);
      res.json(petition);
    } catch (err) { next(err); }
  }
);

// DELETE /api/petitions/:id — delete petition
router.delete(
  '/:id',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      await petitionsService.delete(id);
      res.status(204).send();
    } catch (err) { next(err); }
  }
);

// GET /api/petitions/:id/signatures — list all signatures (admin)
router.get(
  '/:id/signatures',
  validate(listSignaturesSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const result = await petitionsService.listSignaturesAdmin(id, req.query as any);
      res.json(result);
    } catch (err) { next(err); }
  }
);

// GET /api/petitions/:id/stats — signature stats (admin)
router.get(
  '/:id/stats',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const stats = await petitionsService.getStats(id);
      res.json(stats);
    } catch (err) { next(err); }
  }
);

// PATCH /api/petitions/:id/signatures/:sigId/status — approve/reject signature
router.patch(
  '/:id/signatures/:sigId/status',
  validate(updateSignatureStatusSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const sigId = req.params.sigId as string;
      const signature = await petitionsService.updateSignatureStatus(sigId, req.body);
      res.json(signature);
    } catch (err) { next(err); }
  }
);

// POST /api/petitions/:id/signatures/bulk-status — bulk approve/reject
router.post(
  '/:id/signatures/bulk-status',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { ids, status } = req.body;
      if (!Array.isArray(ids) || !status) {
        res.status(400).json({ error: { message: 'ids (array) and status required', code: 'VALIDATION_ERROR' } });
        return;
      }
      const result = await petitionsService.bulkUpdateSignatureStatus(ids, status);
      res.json({ updated: result.count });
    } catch (err) { next(err); }
  }
);

// DELETE /api/petitions/:id/signatures/:sigId — delete signature
router.delete(
  '/:id/signatures/:sigId',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const sigId = req.params.sigId as string;
      await petitionsService.deleteSignature(sigId);
      res.status(204).send();
    } catch (err) { next(err); }
  }
);

// GET /api/petitions/:id/export — export signatures (CSV/JSON)
router.get(
  '/:id/export',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const format = (req.query.format as string) === 'json' ? 'json' : 'csv';
      const result = await petitionsService.exportSignatures(id, format);

      if (format === 'json') {
        res.setHeader('Content-Disposition', `attachment; filename="${result.filename}"`);
        res.json(result.data);
      } else {
        res.setHeader('Content-Type', 'text/csv');
        res.setHeader('Content-Disposition', `attachment; filename="${result.filename}"`);
        res.setHeader('Cache-Control', 'no-store');
        res.send(result.data);
      }
    } catch (err) { next(err); }
  }
);

export { router as petitionsAdminRouter };
