import { Router, Request, Response, NextFunction } from 'express';
import { strawPollsService } from './polls.service';
import {
  createStrawPollSchema,
  updateStrawPollSchema,
  listStrawPollsSchema,
  generateLinksSchema,
} from './polls.schemas';
import { validate } from '../../middleware/validate';
import { authenticate } from '../../middleware/auth.middleware';
import { requireRole } from '../../middleware/rbac.middleware';
import { POLLS_ROLES } from '../../utils/roles';

const adminRouter = Router();
adminRouter.use(authenticate);
adminRouter.use(requireRole(...POLLS_ROLES));

// List polls
adminRouter.get('/', validate(listStrawPollsSchema, 'query'), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await strawPollsService.findAll(req.query as any);
    res.json(result);
  } catch (err) { next(err); }
});

// Get poll detail
adminRouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const poll = await strawPollsService.findById(id);
    if (!poll) return res.status(404).json({ error: 'Poll not found' });
    res.json(poll);
  } catch (err) { next(err); }
});

// Create poll
adminRouter.post('/', validate(createStrawPollSchema), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const poll = await strawPollsService.create(req.body, req.user!.id);
    res.status(201).json(poll);
  } catch (err) { next(err); }
});

// Update poll
adminRouter.put('/:id', validate(updateStrawPollSchema), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const poll = await strawPollsService.update(id, req.body);
    if (!poll) return res.status(404).json({ error: 'Poll not found' });
    res.json(poll);
  } catch (err) { next(err); }
});

// Delete poll
adminRouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const poll = await strawPollsService.delete(id);
    if (!poll) return res.status(404).json({ error: 'Poll not found' });
    res.json({ success: true });
  } catch (err) { next(err); }
});

// Activate (DRAFT -> ACTIVE)
adminRouter.post('/:id/activate', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const poll = await strawPollsService.activate(req.params.id as string);
    res.json(poll);
  } catch (err) { next(err); }
});

// Close (ACTIVE -> CLOSED)
adminRouter.post('/:id/close', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const poll = await strawPollsService.closePoll(req.params.id as string);
    if (!poll) return res.status(400).json({ error: 'Poll cannot be closed (not active)' });
    res.json(poll);
  } catch (err) { next(err); }
});

// Reopen (CLOSED -> ACTIVE)
adminRouter.post('/:id/reopen', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const poll = await strawPollsService.reopenPoll(req.params.id as string);
    res.json(poll);
  } catch (err) { next(err); }
});

// Archive (CLOSED -> ARCHIVED)
adminRouter.post('/:id/archive', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const poll = await strawPollsService.archivePoll(req.params.id as string);
    res.json(poll);
  } catch (err) { next(err); }
});

// Delete a vote (moderation)
adminRouter.delete('/:id/votes/:voteId', async (req: Request, res: Response, next: NextFunction) => {
  try {
    await strawPollsService.deleteVote(req.params.id as string, req.params.voteId as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// Delete a comment (moderation)
adminRouter.delete('/:id/comments/:commentId', async (req: Request, res: Response, next: NextFunction) => {
  try {
    await strawPollsService.deleteComment(req.params.id as string, req.params.commentId as string);
    res.json({ success: true });
  } catch (err) { next(err); }
});

// Generate voting links (TOKEN_GATED)
adminRouter.post('/:id/generate-links', validate(generateLinksSchema), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await strawPollsService.generateVotingTokens(req.params.id as string, req.body.count);
    res.json(result);
  } catch (err) { next(err); }
});

export { adminRouter as strawPollAdminRouter };
