import { Router, Response, NextFunction } from 'express';
import { body, validationResult } from 'express-validator';
import prisma from '../lib/prisma';
import { authenticate, requireRole, optionalAuth, AuthRequest } from '../middleware/auth';

const router = Router();

// GET /api/events — public
router.get('/', optionalAuth, async (_req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const events = await prisma.event.findMany({
      include: { _count: { select: { rsvps: true } } },
      orderBy: { date: 'asc' },
    });
    res.json(events);
  } catch (err) { next(err); }
});

// GET /api/events/:id — public
router.get('/:id', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const event = await prisma.event.findUnique({
      where: { id: req.params.id },
      include: { _count: { select: { rsvps: true } } },
    });
    if (!event) { res.status(404).json({ error: 'Event not found' }); return; }
    res.json(event);
  } catch (err) { next(err); }
});

// POST /api/events — admin only
router.post('/', authenticate, requireRole('admin'),
  [
    body('title').trim().notEmpty(),
    body('date').isISO8601(),
    body('location').trim().notEmpty(),
    body('type').isIn(['cleanup', 'educational', 'fundraiser']),
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) { res.status(422).json({ errors: errors.array() }); return; }
    try {
      const { title, description, date, location, max_attendees, type } = req.body;
      const event = await prisma.event.create({
        data: { title, description, date: new Date(date), location, max_attendees, type },
      });
      res.status(201).json(event);
    } catch (err) { next(err); }
  }
);

// PATCH /api/events/:id — admin only
router.patch('/:id', authenticate, requireRole('admin'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { title, description, date, location, max_attendees, type } = req.body;
      const updated = await prisma.event.update({
        where: { id: req.params.id },
        data: { title, description, date: date ? new Date(date) : undefined, location, max_attendees, type },
      });
      res.json(updated);
    } catch (err) { next(err); }
  }
);

// DELETE /api/events/:id — admin only
router.delete('/:id', authenticate, requireRole('admin'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      await prisma.event.delete({ where: { id: req.params.id } });
      res.json({ message: 'Event deleted' });
    } catch (err) { next(err); }
  }
);

// POST /api/events/:id/rsvp — authenticated users
router.post('/:id/rsvp', authenticate, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const event = await prisma.event.findUnique({
      where: { id: req.params.id },
      include: { _count: { select: { rsvps: true } } },
    });
    if (!event) { res.status(404).json({ error: 'Event not found' }); return; }
    if (event.max_attendees && event._count.rsvps >= event.max_attendees) {
      res.status(409).json({ error: 'Event is fully booked' }); return;
    }

    const rsvp = await prisma.eventRSVP.create({
      data: { event_id: req.params.id, user_id: req.user!.userId },
    });
    res.status(201).json(rsvp);
  } catch (err) { next(err); }
});

// DELETE /api/events/:id/rsvp — cancel RSVP
router.delete('/:id/rsvp', authenticate, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    await prisma.eventRSVP.delete({
      where: { event_id_user_id: { event_id: req.params.id, user_id: req.user!.userId } },
    });
    res.json({ message: 'RSVP cancelled' });
  } catch (err) { next(err); }
});

export default router;
