import express from 'express';
import _ from 'lodash';

import TemplateValidate from './validate/template';
import TemplateTreatmentModel from '../models/treatment_template';
import TemplateMeasurementModel from '../models/measurement_template';
import res400 from './validate/res400';


const router = express.Router();

router.get('/template/:collection(measurements|treatments)', (req, res, next) => {
  if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'basic')) return;

  (req.params.collection === 'treatments' ? TemplateTreatmentModel : TemplateMeasurementModel)
    .find({}).lean().exec((err, data) => {
     if (err) next (err);
     res.json(_.compact(data.map(e => TemplateValidate.output(e))));  // validate all and filter null values from validation errors
  });
});

router.get('/template/:collection(measurement|treatment)/:name', (req, res, next) => {
  if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'basic')) return;

  (req.params.collection === 'treatment' ? TemplateTreatmentModel : TemplateMeasurementModel)
    .findOne({name: req.params.name}).lean().exec((err, data) => {
    if (err) next (err);
    if (data) {
      res.json(TemplateValidate.output(data));
    }
    else {
      res.status(404).json({status: 'Not found'});
    }
  });
});

router.put('/template/:collection(measurement|treatment)/:name', (req, res, next) => {
  if (!req.auth(res, ['maintain', 'admin'], 'basic')) return;

  const collectionModel = req.params.collection === 'treatment' ? TemplateTreatmentModel : TemplateMeasurementModel;

  collectionModel.findOne({name: req.params.name}).lean().exec((err, data) => {
    if (err) next (err);
    const templateState = data? 'change': 'new';
    const {error, value: template} = TemplateValidate.input(req.body, templateState);
    if (error) return res400(error, res);

    if (template.hasOwnProperty('name') && template.name !== req.params.name) {
      collectionModel.find({name: template.name}).lean().exec((err, data) => {
        if (err) next (err);
        if (data.length > 0) {
          res.status(400).json({status: 'Template name already taken'});
          return;
        }
        else {
          f();
        }
      });
    }
    else {
      f();
    }

    function f() {  // to resolve async
      collectionModel.findOneAndUpdate({name: req.params.name}, template, {new: true, upsert: true}).lean().exec((err, data) => {
        if (err) return next(err);
        res.json(TemplateValidate.output(data));
      });
    }
  });
});

router.delete('/template/:collection(measurement|treatment)/:name', (req, res, next) => {
  if (!req.auth(res, ['maintain', 'admin'], 'basic')) return;

  (req.params.collection === 'treatment' ? TemplateTreatmentModel : TemplateMeasurementModel)
    .findOneAndDelete({name: req.params.name}).lean().exec((err, data) => {
    if (err) return next(err);
    if (data) {
      res.json({status: 'OK'})
    }
    else {
      res.status(404).json({status: 'Not found'});
    }
  });
});


module.exports = router;