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

const router = Router();

// ─── VOLUNTEER HOURS ─────────────────────────────────────────────────────────

// GET /api/volunteer/hours — admin sees all, volunteer sees their own
router.get('/hours', authenticate, requireRole('admin', 'volunteer'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const where = req.user!.role === 'admin' ? {} : { volunteer_id: req.user!.userId };
      const hours = await prisma.volunteerHour.findMany({
        where,
        include: { volunteer: { select: { id: true, name: true } } },
        orderBy: { date: 'desc' },
      });
      res.json(hours);
    } catch (err) { next(err); }
  }
);

// POST /api/volunteer/hours — volunteers log their own hours
router.post('/hours', authenticate, requireRole('admin', 'volunteer'),
  [
    body('date').isISO8601(),
    body('hours').isFloat({ min: 0.5 }),
    body('task_description').trim().notEmpty(),
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) { res.status(422).json({ errors: errors.array() }); return; }
    try {
      const { date, hours, task_description } = req.body;
      const entry = await prisma.volunteerHour.create({
        data: { volunteer_id: req.user!.userId, date: new Date(date), hours, task_description },
      });
      res.status(201).json(entry);
    } catch (err) { next(err); }
  }
);

// PATCH /api/volunteer/hours/:id/verify — admin only
router.patch('/hours/:id/verify', authenticate, requireRole('admin'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const updated = await prisma.volunteerHour.update({
        where: { id: req.params.id },
        data: { verified_by: req.user!.userId },
      });
      res.json(updated);
    } catch (err) { next(err); }
  }
);

// DELETE /api/volunteer/hours/:id — owner or admin
router.delete('/hours/:id', authenticate, requireRole('admin', 'volunteer'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const entry = await prisma.volunteerHour.findUnique({ where: { id: req.params.id } });
      if (!entry) { res.status(404).json({ error: 'Not found' }); return; }
      if (req.user!.role !== 'admin' && entry.volunteer_id !== req.user!.userId) {
        res.status(403).json({ error: 'Forbidden' }); return;
      }
      await prisma.volunteerHour.delete({ where: { id: req.params.id } });
      res.json({ message: 'Hours deleted' });
    } catch (err) { next(err); }
  }
);

// ─── EQUIPMENT ────────────────────────────────────────────────────────────────

// GET /api/volunteer/equipment — admin/volunteer
router.get('/equipment', authenticate, requireRole('admin', 'volunteer'),
  async (_req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const items = await prisma.equipmentItem.findMany({
        include: { checker: { select: { id: true, name: true } } },
        orderBy: { name: 'asc' },
      });
      res.json(items);
    } catch (err) { next(err); }
  }
);

// POST /api/volunteer/equipment — admin creates
router.post('/equipment', authenticate, requireRole('admin'),
  [body('name').trim().notEmpty()],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) { res.status(422).json({ errors: errors.array() }); return; }
    try {
      const { name, description } = req.body;
      const item = await prisma.equipmentItem.create({ data: { name, description } });
      res.status(201).json(item);
    } catch (err) { next(err); }
  }
);

// PATCH /api/volunteer/equipment/:id/checkout — check out or return
router.patch('/equipment/:id/checkout', authenticate, requireRole('admin', 'volunteer'),
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const { action } = req.body; // 'checkout' | 'return'
      const data = action === 'checkout'
        ? { status: 'checked_out' as const, checked_out_by: req.user!.userId, checked_out_at: new Date() }
        : { status: 'available' as const, checked_out_by: null as null, checked_out_at: null as null };
      const updated = await prisma.equipmentItem.update({ where: { id: req.params.id }, data });
      res.json(updated);
    } catch (err) { next(err); }
  }
);

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

export default router;
