const express = require('express');
const router = express.Router();
const serverError = require('../utils/serverError');
const database_manager = require('../src/database/database_manager');

const defaultSettings = {
   id: 1,
   interval: null,
   nb_images: null,
   maintenance: false,
   stop_flag: false,
   idle: true
};

async function camera_initialization() {
   // si capture.get_camera est vide ou undefined, on l'initialise
   let current_camera = await database_manager.capture.get_camera();
   if (!current_camera || current_camera === undefined) {
      console.log("Initializing camera...");
      current_camera = await database_manager.capture.init_camera(
         defaultSettings.id,
         defaultSettings.interval,
         defaultSettings.nb_images,
         defaultSettings.maintenance,
         defaultSettings.stop_flag,
         defaultSettings.idle
      );
      console.log("Camera initialized:", current_camera);
   }
   else {
      console.log("Camera already initialized:", current_camera);
   }
}

camera_initialization()

async function get_camera_settings() {
   const settings = await database_manager.capture.get_camera();
   if (!settings) {
      // balancer une erreur si la caméra n'est pas initialisée
      throw new Error("Camera settings not found in the database.");
   }
   return settings;
}

router.get('/camera/status', async (req, res) => {
   try {
      const settings = await get_camera_settings();
      res.json(settings);
   } catch (error) {
      serverError.sendError('Error getting camera status:', res, error, 500);
   }
});

async function stop_procedure() { // côté serveur
   let new_settings = {
      stop_flag: true,
   }
   await database_manager.capture.edit_camera(1, new_settings);
   console.log("Stopping camera... en attente de confirmation de la caméra...");
}

async function confirm_stop_procedure() { // côté caméra
   let new_settings = {
      interval: null,
      nb_images: null,
      stop_flag: false,
      idle: true,
   }
   await database_manager.capture.edit_camera(1, new_settings);
   let project_settings = {
      status: 0,
   }
   let current_project = await database_manager.project.find_current_rendering_project();
   if (current_project) {
      await database_manager.project.edit_project_by_id(current_project.id, project_settings);
      console.log("Project : " + current_project.id + " stopped.");
   } else {
      console.log("No project to stop.");
   }
   console.log("Camera stopped.");
}

async function start_procedure(project_id, interval, nb_images) {
   let new_settings = {
      interval: interval,
      nb_images: nb_images,
      stop_flag: false,
      idle: false,
   }
   console.log("Starting Procedure with settings:", new_settings);
   await database_manager.capture.edit_camera(1, new_settings);
   let project_settings = {
      status: 1,
   }
   let existing_project = await database_manager.project.find_current_rendering_project();
   if (existing_project) {
      throw new Error("A project is already being rendered. Please stop it before starting a new one.");
   } else {
      await database_manager.project.edit_project_by_id(project_id, project_settings);
      console.log("Project : " + project_id + " started.");
   }
   console.log("Camera started.");
}

async function activate_maintenance() {
   let new_settings = {
      maintenance: true,
   }
   await database_manager.capture.edit_camera(1, new_settings);
   console.log("Camera in maintenance mode.");
}

async function deactivate_maintenance() {
   let new_settings = {
      maintenance: false,
   }
   await database_manager.capture.edit_camera(1, new_settings);
   console.log("Camera out of maintenance mode.");
}

router.post('/procedure/start', async (req, res) => {
   const { project_id, interval, nb_images } = req.body;
   if (!interval || !nb_images) {
      return res.status(400).json({ error: 'Interval and number of images are required' });
   }
   try {
      await start_procedure(project_id, interval, nb_images);
      res.json({ message: 'Camera started successfully', settings: { interval, nb_images } });
   } catch (error) {
      serverError.sendError('Error starting camera procedure:', res, error, 500);
   }
});

router.post('/procedure/stop', async (req, res) => {
   try {
      await stop_procedure();
      res.json({ message: 'Camera stop procedure initiated successfully' });
   } catch (error) {
      serverError.sendError('Error stopping camera procedure:', res, error, 500);
   }
});

router.post('/camera/stop', async (req, res) => {
   try {
      await confirm_stop_procedure();
      res.json({ message: 'Camera stopped successfully' });
   } catch (error) {
      serverError.sendError('Error stopping camera:', res, error, 500);
   }
});

/**
 * @swagger
 * /camera/status:
 *   get:
 *     summary: Get the current camera settings
 *     responses:
 *       200:
 *         description: Successfully retrieved camera settings
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 id:
 *                   type: integer
 *                 interval:
 *                   type: integer
 *                 nb_images:
 *                   type: integer
 *                 maintenance:
 *                   type: boolean
 *                 stop_flag:
 *                   type: boolean
 *                 idle:
 *                   type: boolean
 *       500:
 *         description: Error retrieving camera settings
 *
 * /procedure/start:
 *   post:
 *     summary: Start the camera procedure
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               project_id:
 *                 type: integer
 *               interval:
 *                 type: integer
 *               nb_images:
 *                 type: integer
 *     responses:
 *       200:
 *         description: Camera started successfully
 *       400:
 *         description: Interval and number of images are required
 *       500:
 *         description: Error starting camera procedure
 *
 * /procedure/stop:
 *   post:
 *     summary: Initiate the camera stop procedure
 *     responses:
 *       200:
 *         description: Camera stop procedure initiated successfully
 *       500:
 *         description: Error stopping camera procedure
 *
 * /camera/stop:
 *   post:
 *     summary: Confirm the camera stop procedure
 *     responses:
 *       200:
 *         description: Camera stopped successfully
 *       500:
 *         description: Error stopping camera
 *
 * /camera/maintenance:
 *   post:
 *     summary: Activate maintenance mode for the camera
 *     responses:
 *       200:
 *         description: Camera in maintenance mode
 *       500:
 *         description: Error activating maintenance mode
 *
 * /camera/maintenance/deactivate:
 *   post:
 *     summary: Deactivate maintenance mode for the camera
 *     responses:
 *       200:
 *         description: Camera out of maintenance mode
 *       500:
 *         description: Error deactivating maintenance mode
 */
router.post('/camera/maintenance', async (req, res) => {
   try {
      await activate_maintenance();
      res.json({ message: 'Camera in maintenance mode' });
   } catch (error) {
      serverError.sendError('Error activating maintenance mode:', res, error, 500);
   }
}
);

router.post('/camera/maintenance/deactivate', async (req, res) => {
   try {
      await deactivate_maintenance();
      res.json({ message: 'Camera out of maintenance mode' });
   } catch (error) {
      serverError.sendError('Error deactivating maintenance mode:', res, error, 500);
   }
});

module.exports = router;