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/sightings — public
router.get('/', optionalAuth, async (_req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const sightings = await prisma.wildlifeSighting.findMany({
      include: { reporter: { select: { id: true, name: true } } },
      orderBy: { created_at: 'desc' },
    });
    res.json(sightings);
  } catch (err) { next(err); }
});

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

// POST /api/sightings — any authenticated user
router.post('/', authenticate,
  [
    body('species').trim().notEmpty(),
    body('gps_lat').isFloat({ min: -90, max: 90 }),
    body('gps_lng').isFloat({ min: -180, max: 180 }),
  ],
  async (req: AuthRequest, res: Response, next: NextFunction) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) { res.status(422).json({ errors: errors.array() }); return; }
    try {
      const { species, gps_lat, gps_lng, photo_url, description } = req.body;
      const sighting = await prisma.wildlifeSighting.create({
        data: { species, gps_lat, gps_lng, photo_url, description, reporter_id: req.user!.userId },
      });
      res.status(201).json(sighting);
    } catch (err) { next(err); }
  }
);

// PATCH /api/sightings/:id — admin can verify; reporter can edit their own
router.patch('/:id', authenticate, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const existing = await prisma.wildlifeSighting.findUnique({ where: { id: req.params.id } });
    if (!existing) { res.status(404).json({ error: 'Not found' }); return; }
    const isOwner = existing.reporter_id === req.user!.userId;
    const isAdmin = req.user!.role === 'admin';
    if (!isOwner && !isAdmin) { res.status(403).json({ error: 'Forbidden' }); return; }

    const { species, gps_lat, gps_lng, photo_url, description, verified } = req.body;
    const data: Record<string, unknown> = { species, gps_lat, gps_lng, photo_url, description };
    if (isAdmin && typeof verified === 'boolean') data.verified = verified;

    const updated = await prisma.wildlifeSighting.update({ where: { id: req.params.id }, data });
    res.json(updated);
  } catch (err) { next(err); }
});

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

export default router;
