const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

const serverError = require('../../utils/serverError');
const db = require('../../db');
const storageManager = require('../data/storageManager');
const measureManager = require('../measure/measureManager');

const PROJECTS_DIR = path.join('.');

async function createVideoProject(projectId, measurementIds, name, resolution, duration) {
   // insérer une nouvelle vidéo dans la base de données
   const status = 0; // status brouillon
   const query = 'INSERT INTO public.videos (project_id, measurement_ids, name, resolution, duration, status) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *';
   const values = [projectId, measurementIds, name, resolution, duration, status];
   const res = await db.query(query, values);
   console.log('New video created:', res.rows[0]);
   return res.rows[0];
}

async function deleteVideoProject(videoId) {
   const query = 'DELETE FROM public.videos WHERE id = $1';
   const values = [videoId];
   const res = await db.query(query, values);
   console.log('Video deleted:', res.rows[0]);
   return res.rows[0];
}

async function createVideoWithList(projectId, pathList) {
   //pathList étant la liste des chemins déjà triés
   const tempFile = path.join('temp.txt');
   try {
      // Trouver tous les fichiers image pour le projet donné
      const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`);
      const dir = path.join(PROJECTS_DIR, 'storage', `${projectId}`, 'images');
      console.log('dir:', dir);
      const images = pathList;
      console.log('images:', images);

      // Trier les images numériquement
      const sortedImages = images.sort((a, b) => {
         const numA = parseInt(path.basename(a).match(/\d+/)[0], 10);
         const numB = parseInt(path.basename(b).match(/\d+/)[0], 10);
         return numA - numB;
      });

      // En déduire l'id de la première et dernière image utilisée
      const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
      const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);

      console.log('firstImageId:', firstImageId);
      console.log('lastImageId:', lastImageId);

      // Créer un fichier temporaire pour la liste des images
      fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));

      const frameRate = 10;

      // le fichier final prend cette forme : {projectId}_{firstImageId}_{lastImageId}-{timestamp}.mp4
      const timestamp = new Date().getTime();
      const outputVideo = path.join(workdir, `${projectId}_${firstImageId}_${lastImageId}-${timestamp}.mp4`);

      // Commande ffmpeg pour créer la vidéo
      const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
      console.log('Running ffmpeg command:', ffmpegCommand);
      execSync(ffmpegCommand);
      console.log('Video created successfully:', outputVideo);
      return outputVideo;
   } catch (error) {
      console.error('Error creating video:', error);
      serverError.sendError(error);
   } finally {
      // Supprimer le fichier temporaire
      if (fs.existsSync(tempFile)) {
         fs.unlinkSync(tempFile);
         console.log('Temporary file deleted:', tempFile);
      }
   }
}

async function createVideo(projectId) {
   const tempFile = path.join('temp.txt');
   try {
      // Trouver tous les fichiers image pour le projet donné
      const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`);
      const dir = path.join(PROJECTS_DIR, 'storage', `${projectId}`, 'images');
      console.log('dir:', dir);
      const images = storageManager.scanAllImages(dir);
      console.log('images:', images);

      // Trier les images numériquement
      const sortedImages = images.sort((a, b) => {
         const numA = parseInt(path.basename(a).match(/\d+/)[0], 10);
         const numB = parseInt(path.basename(b).match(/\d+/)[0], 10);
         return numA - numB;
      });

      // En déduire l'id de la première et dernière image utilisée
      const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
      const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);

      console.log('firstImageId:', firstImageId);
      console.log('lastImageId:', lastImageId);

      // Créer un fichier temporaire pour la liste des images
      fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));

      const frameRate = 10;
      const outputVideo = path.join(workdir, 'video.mp4');

      // Commande ffmpeg pour créer la vidéo
      const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
      console.log('Running ffmpeg command:', ffmpegCommand);
      execSync(ffmpegCommand);
      console.log('Video created successfully:', outputVideo);
   } catch (error) {
      console.error('Error creating video:', error);
      serverError(error);
   } finally {
      // Supprimer le fichier temporaire
      if (fs.existsSync(tempFile)) {
         fs.unlinkSync(tempFile);
         console.log('Temporary file deleted:', tempFile);
      }
   }
}

async function updateVideoFile(videoId, path) {
   const query = 'UPDATE public.videos SET video_file = $2 WHERE id = $1 RETURNING *';
   const values = [videoId, path];
   const res = await db.query(query, values);
   console.log('Video updated:', res.rows[0]);
   return res.rows[0];
}

module.exports = { createVideo, createVideoWithList, createVideoProject, deleteVideoProject, updateVideoFile };
