const router = require('express').Router();
const { body, query } = require('express-validator');
const prisma = require('../lib/prisma');
const auditMiddleware = require('../middleware/auditMiddleware');
const { validateRequest } = require('../middleware/errorHandler');
const { validateCsvConfig } = require('../lib/csvConfigValidation');

const animalValidation = [
  body('experiment_id').notEmpty().withMessage('experiment_id is required').matches(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).withMessage('experiment_id must be a valid UUID'),
  body('animal_id_string').trim().notEmpty().withMessage('animal_id_string is required'),
  body('animal_name').trim().notEmpty().withMessage('animal_name is required'),
];

const animalUpdateValidation = [
  body('animal_id_string').optional().trim().notEmpty().withMessage('animal_id_string cannot be empty'),
  body('animal_name').optional().trim().notEmpty().withMessage('animal_name cannot be empty'),
  body('subject_info').optional({ nullable: true }).isObject().withMessage('subject_info must be an object'),
];

// GET /api/animals?experimentId=<uuid> — list for experiment
router.get(
  '/',
  [query('experimentId').optional().matches(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).withMessage('experimentId must be a valid UUID')],
  validateRequest,
  async (req, res, next) => {
    try {
      const where = req.query.experimentId ? { experiment_id: req.query.experimentId } : {};
      const animals = await prisma.animal.findMany({
        where,
        orderBy: { animal_name: 'asc' },
        include: { _count: { select: { daily_statuses: true } } },
      });
      res.json(animals);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/animals/:id — get one with daily statuses
router.get('/:id', async (req, res, next) => {
  try {
    const animal = await prisma.animal.findUnique({
      where: { id: req.params.id },
      include: { daily_statuses: { orderBy: { date: 'desc' } } },
    });
    if (!animal) return res.status(404).json({ error: 'Animal not found' });
    res.json(animal);
  } catch (err) {
    next(err);
  }
});

// POST /api/animals — create
router.post('/', animalValidation, validateRequest, async (req, res, next) => {
  try {
    const { experiment_id, animal_id_string, animal_name } = req.body;
    const animal = await prisma.animal.create({
      data: { experiment_id, animal_id_string, animal_name },
    });

    await prisma.auditLog.create({
      data: {
        table_name: 'animals',
        record_id: animal.id,
        action: 'CREATE',
        changes: { before: null, after: animal },
      },
    });

    res.status(201).json(animal);
  } catch (err) {
    next(err);
  }
});

// PUT /api/animals/:id — update
router.put(
  '/:id',
  auditMiddleware('animals', prisma.animal),
  animalUpdateValidation,
  validateRequest,
  async (req, res, next) => {
    try {
      const { animal_id_string, animal_name, subject_info } = req.body;
      const data = {};
      if (animal_id_string !== undefined) data.animal_id_string = animal_id_string;
      if (animal_name !== undefined) data.animal_name = animal_name;
      if (subject_info !== undefined) data.subject_info = subject_info;

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

// DELETE /api/animals/:id — delete
router.delete(
  '/:id',
  auditMiddleware('animals', prisma.animal),
  async (req, res, next) => {
    try {
      await prisma.animal.delete({ where: { id: req.params.id } });
      res.status(204).send();
    } catch (err) {
      next(err);
    }
  }
);

// PATCH /api/animals/:id/csv-config — replace entire CSV-analysis bucket config
router.patch(
  '/:id/csv-config',
  auditMiddleware('animals', prisma.animal),
  async (req, res, next) => {
    try {
      const err = validateCsvConfig(req.body);
      if (err) return res.status(400).json({ error: err });

      const animal = await prisma.animal.update({
        where: { id: req.params.id },
        data: { csv_analysis_config: req.body },
      });
      res.json(animal);
    } catch (e) {
      next(e);
    }
  }
);

module.exports = router;
