let timer = null; // To store the interval ID
let currentSecond = 0; // Tracks the current second on the timeline
let allSearchedFiles = null;
let currentIndex = 0;
let backendUrl = null;
let cameraDataById = null;
let isExportInProgress = false; // Track if export is currently running
let playbackSpeed = 0.5; // Current playback speed multiplier (starts at 0.5)
let speedLevels = [0.15, 0.5, 1, 1.5]; // Available speed levels: lowest, low, medium, highest
let speedLabels = ['0.5', '1', '1.5','2']; // Display labels for each speed
let currentSpeedIndex = 1; // Index of current speed (0.5 is default - index 1)

$(document).ready(async function () {
  setupTimeline([]);
  $('#changeStreetViewEle').bootstrapSwitch();
  setupTimelineClickHandler();
  window.scrollTo({
    top: 0,
    behavior: "smooth",
  });
  const today = new Date().toISOString().split("T")[0];
  document.getElementById("playback_date").value = today;
  
  if (document.getElementById("export_start_date")) {
    document.getElementById("export_start_date").value = today;
  }
  if (document.getElementById("export_end_date")) {
    document.getElementById("export_end_date").value = today;
  }
  
  const urlParams = new URLSearchParams(window.location.search);
  const id = urlParams.get("id");
  await sendPlaybackRequest({ get_camera_by_id: true, settingId: id,property_id:sessionStorage.getItem('propertyId') });
  await getBackendStreamingUrlForPlayback({ get_streaming_url_request: true });
  getPlaybackRecords();
});

function formatDateTimePlayback(dateString) {
  const date = new Date(dateString + "Z");
  return date.toLocaleString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: true,
  });
}
function sendPlaybackRequest(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/dashboard/settings_requests.php",
      type: "post",
      data,
      success: function (resp) {
        if (data?.get_camera_by_id) {
          cameraDataById = resp?.data;
          if(!cameraDataById){
            document.getElementById("playback_container").innerHTML = `<div class="alert alert-danger">Camera not found against this id</div>`;
          }
          resolve();
        }
      },
      error: function (xhr, status, error) {
        console.log("xhr", xhr);
        if (xhr?.responseJSON?.error)
          show_camera_playback_toastMessage(xhr?.responseJSON?.error);
        else show_camera_playback_toastMessage(error);
      },
    });
  });
}

async function getBackendStreamingUrlForPlayback(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/command_center/command_center_requests.php",
      type: "post",
      data,
      success: function (resp) {
        backendUrl = `${resp?.data}/api`;
        resolve();
      },
      error: function (xhr, status, error) {
        reject(xhr || error);
      },
    });
  });
}

function getPlaybackRecords() {
  const fileType = document.getElementById("file_type").value;
  const playbackDate = document.getElementById("playback_date").value;
  const playbackStart = document.querySelector(
    "input[name='playback_start']"
  ).value;
  const playbackEnd = document.querySelector(
    "input[name='playback_end']"
  ).value;
  const startEndDate = createPlaybackObject(
    playbackDate,
    playbackStart,
    playbackEnd,
    fileType
  );

  const playbackObject = {
    host: cameraDataById?.ftp_host || null,
    user: cameraDataById?.ftp_user || null,
    password: cameraDataById?.ftp_password || null,
    port: cameraDataById?.ftp_port || null,
    ftp_folder: cameraDataById?.camera_ftp_folder || null,
    startTime: startEndDate.startTime,
    endTime: startEndDate.endTime,
    fileType: startEndDate.fileType,
  };

  const encrypted = encryptData(playbackObject);
  isLoadingPlayback(true);
  callPlaybackRecordsApi({ data: encrypted });
}

function setupTimeline(timeSelectorList) {
  const timeMarkers = document.getElementById("timeMarkers");
  const timeline = document.getElementById("timeline");

  // Set up time markers (hours from 00:00 to 23:00 for a full day)
  const hoursInDay = 24;
  for (let hour = 0; hour < hoursInDay; hour++) {
    // Create hour label
    const label = document.createElement("div");
    label.className = "time-label";
    label.textContent = `${hour.toString().padStart(2, "0")}:00`;

    // Position label
    const position = (hour / hoursInDay) * 100;
    label.style.left = `${position}%`;

    // Add to DOM
    timeMarkers.appendChild(label);
  }

  timeSelectorList.forEach((fileTime) => {
    const time = fileTime.time;
    const [hour, minute] = time.split(":").map(Number);
    const percentage = (hour + minute / 60) / 24;

    const timeSelector = document.createElement("div");
    timeSelector.className = "time-selector";
    timeSelector.style.left = `${percentage * 100}%`;

    const currentTime = document.createElement("div");
    currentTime.className = "current-time";
    currentTime.textContent = time;

    timeSelector.appendChild(currentTime);
    timeline.appendChild(timeSelector);
  });
}

function setupTimelineClickHandler() {
  const timelineClickable = document.getElementById("timelineClickable");
  const timeSelector = document.getElementById("timeSelector");
  const currentTimeDisplay = document.getElementById("currentTime");
  const debugInfo = document.getElementById("debugInfo");

  // Add click event to the dedicated clickable area

  timelineClickable.addEventListener("click", function (e) {
    const rect = timelineClickable.getBoundingClientRect();
    const clickPosition = e.clientX - rect.left;
    const percentage = clickPosition / rect.width;

    if (timeSelector) timeSelector.style.display = "block";

    timeSelector.style.left = `${percentage * 100}%`;

    const totalHours = percentage * 24;
    const selectedHour = Math.floor(totalHours);
    const selectedMinute = Math.floor((totalHours - selectedHour) * 60);
    const selectedSecond = Math.floor(
      ((totalHours - selectedHour) * 60 - selectedMinute) * 60
    );

    currentSecond = selectedHour * 3600 + selectedMinute * 60 + selectedSecond;

    const formattedTime = `${String(selectedHour).padStart(2, "0")}:${String(
      selectedMinute
    ).padStart(2, "0")}:${String(selectedSecond).padStart(2, "0")}`;
    currentTimeDisplay.textContent = `${formattedTime}`;

    if (allSearchedFiles && allSearchedFiles.length > 0) {
      let closestFile = null;
      let closestDifference = Number.MAX_SAFE_INTEGER;

      allSearchedFiles.forEach((file, index) => {
        const [fileHours, fileMinutes, fileSeconds] = file.time
          .split(":")
          .map(Number);
        const fileSecondsTotal =
          fileHours * 3600 + fileMinutes * 60 + fileSeconds;

        const difference = Math.abs(currentSecond - fileSecondsTotal);

        if (difference < closestDifference) {
          closestDifference = difference;
          closestFile = file;
          currentIndex = index;
        }
      });
    } else {
      console.error("No files available to search.");
    }
  });

  // Also add mousemove event to show potential selection position
  timelineClickable.addEventListener("mousemove", function (e) {
    const rect = timelineClickable.getBoundingClientRect();
    const mousePosition = e.clientX - rect.left;
    const percentage = mousePosition / rect.width;

    // Calculate time at mouse position
    const totalHours = percentage * 24;
    const hoverHour = Math.floor(totalHours);
    const hoverMinute = Math.floor((totalHours - hoverHour) * 60);

    const hoverTime = `${String(hoverHour).padStart(2, "0")}:${String(
      hoverMinute
    ).padStart(2, "0")}`;
  });
}

function createPlaybackObject(date, startTime, endTime) {
  const toUnixTimestamp = (date, time) => {
    return Math.floor(new Date(`${date}T${time}:00Z`).getTime() / 1000);
  };

  return {
    fileType: 1,
    startTime: toUnixTimestamp(date, startTime),
    endTime: toUnixTimestamp(date, endTime),
  };
}

function callPlaybackRecordsApi(data) {
  $.ajax({
    url: `${backendUrl}/connect_ftp`,
    type: "post",
    data,
    success: function (resp) {
      isLoadingPlayback(false);
      if (resp.files?.length < 1) {
        allSearchedFiles=[];
        show_camera_playback_toastMessage("No data found");
        return;
      }else if (resp.files?.length>0){
        showSuccessGlobalToastMessage(`${resp.files.length} files found`);
        allSearchedFiles = createImageArray(resp.files);
        create_table_view();
      }
    },
    error: function (xhr, status, error) {
      setTimeout(() => {
        isLoadingPlayback(false);
      }, 500);
      show_camera_playback_toastMessage(xhr?.responseJSON?.error || error);
    },
  });
}

function createImageArray(data) {
  let filesArray = [];
  data?.map((ele) => {
    const tsString = extractTimestamp(ele.name);
    const fileTime = extractTime(ele.name);
    if (!tsString) return false;
    const fileDate = new Date(`${tsString}Z`);
    
    const previewPayload = {
      host: cameraDataById?.ftp_host || null,
      user: cameraDataById?.ftp_user || null,
      password: cameraDataById?.ftp_password || null,
      port: cameraDataById?.ftp_port || null,
      filePath: `${cameraDataById?.camera_ftp_folder}/MotionDetection/${ele.name}`,
    };
    const encrypted_data = encryptData(previewPayload);
    const thumbnailUrl = `${backendUrl}/previewFileImage?encrypted_data=${encodeURIComponent(
      encrypted_data
    )}`;
    filesArray.push({
      dateTime: formatDateTimePlayback(fileDate),
      name: ele.name,
      time: fileTime,
      thumbnailUrl,
      dateTimeLocal:new Date(tsString).toISOString()
    });
  });

  setupTimeline(filesArray);
  return filesArray;
}

function extractTime(filename) {
  const regex = /_(\d{14})_/;
  const match = filename.match(regex);
  if (match && match[1]) {
    const ts = match[1];
    const hour = ts.slice(8, 10);
    const minute = ts.slice(10, 12);
    const second = ts.slice(12, 14);
    return `${hour}:${minute}:${second}`;
  } else {
    return null;
  }
}

function extractTimestamp(filename) {
  // Use regex to extract 14 digits between underscores
  const regex = /_(\d{14})_/;
  const match = filename.match(regex);
  if (match && match[1]) {
    const ts = match[1];
    const year = ts.slice(0, 4);
    const month = ts.slice(4, 6);
    const day = ts.slice(6, 8);
    const hour = ts.slice(8, 10);
    const minute = ts.slice(10, 12);
    const second = ts.slice(12, 14);
    return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
  } else {
    return null;
  }
}

function startStreamingImages() {
  if (timer) {
    clearInterval(timer);
  }
  
  const stopButton = document.getElementById("stopButton");
  const startButton = document.getElementById("startButton");
  if (startButton) startButton.style.display = "none";
  if (stopButton) stopButton.style.display = "flex";
  
  // Calculate interval based on playback speed
  const baseInterval = 1000; // 1 second base interval
  const adjustedInterval = baseInterval / playbackSpeed;
  
  timer = setInterval(() => {
    if (currentIndex >= allSearchedFiles.length) {
      currentIndex = 0;
    }
    
    const currentFile = allSearchedFiles[currentIndex];
    showStreamingImageInPreview(currentFile);
    updateCurrentSecondAndSelector(currentFile);
    currentIndex++;
  }, adjustedInterval);
}

function checkCurrentTimeMatch(currentTime, filesArray) {
  return filesArray?.find((file) => file.time === currentTime);
}

function stopStreamingImages() {
  const stopButton = document.getElementById("stopButton");
  const startButton = document.getElementById("startButton");
  if (stopButton) stopButton.style.display = "none";
  if (startButton) startButton.style.display = "flex";
  if (timer) {
    clearInterval(timer);
    timer = null;
    console.log("Playback stopped");
  }
}

function showStreamingImageInPreview(file) {
  const previewImage = document.getElementById("previewImage");
  if (file && file.thumbnailUrl) {
    previewImage.src = file.thumbnailUrl;
    // previewImage.style.display = "block";
    previewImage.style.display = "none";
  } else {
    previewImage.style.display = "none";
    previewImage.src = "";
  }
}

function showNextImage() {
  if (allSearchedFiles && allSearchedFiles.length > 0) {
    currentIndex = (currentIndex + 1) % allSearchedFiles.length;
    const nextFile = allSearchedFiles[currentIndex];
    showLoader();
    showStreamingImageInPreview(nextFile);
    updateCurrentSecondAndSelector(nextFile);
  } else {
    console.log("No files available to display!");
  }
}

function showPreviousImage() {
  if (allSearchedFiles && allSearchedFiles.length > 0) {
    currentIndex =
      (currentIndex - 1 + allSearchedFiles.length) % allSearchedFiles.length;
    const nextFile = allSearchedFiles[currentIndex];
    showLoader();
    showStreamingImageInPreview(nextFile);
    updateCurrentSecondAndSelector(nextFile);
  } else {
    console.log("No files available to display!");
  }
}

function showLoader() {
  const loader = document.getElementById("loader");
  const previewImage = document.getElementById("previewImage");
  if (loader) loader.style.display = "block"; // Hide the loader
  if (previewImage) previewImage.style.display = "none"; // Show the image
}

function hideLoader() {
  const loader = document.getElementById("loader");
  const previewImage = document.getElementById("previewImage");
  if (loader) loader.style.display = "none"; // Hide the loader
  if (previewImage) previewImage.style.display = "block"; // Show the image
}

// Function to handle errors while loading the image
function handleImageError() {
  const loader = document.getElementById("loader");
  const previewImage = document.getElementById("previewImage");
  if (loader) loader.style.display = "none"; // Hide the loader
  if (previewImage) {
    previewImage.style.display = "block";
  }
}

function updateCurrentSecondAndSelector(file) {
  if (file && file.time) {
    const [hours, minutes, seconds] = file.time.split(":").map(Number);
    currentSecond = hours * 3600 + minutes * 60 + seconds;
    const percentage = currentSecond / (24 * 3600);
    const timeSelector = document.getElementById("timeSelector");
    const currentTimeDisplay = document.getElementById("currentTime");
    if (timeSelector) {
      timeSelector.style.display = "block";
      timeSelector.style.left = `${percentage * 100}%`;
    }
    if (currentTimeDisplay) {
      currentTimeDisplay.textContent = file.time;
    }
    
    // Scroll timeline to keep blue line visible
    const timelineContainer = document.querySelector('.timeline-container');
    if (timelineContainer && timeSelector) {
      const selectorRect = timeSelector.getBoundingClientRect();
      const containerRect = timelineContainer.getBoundingClientRect();
      
      // If blue line is outside visible area, scroll to it
      if (selectorRect.left < containerRect.left || selectorRect.right > containerRect.right) {
        const scrollLeft = timelineContainer.scrollLeft + (selectorRect.left - containerRect.left) - (containerRect.width / 2);
        timelineContainer.scrollTo({
          left: scrollLeft,
          behavior: 'smooth'
        });
      }
    }
  }
}

function isLoadingPlayback(loading) {
  const loader = document.getElementById("playbackRecordLoader");
  if (loading) {
    loader.style.display = "block";
  } else {
    loader.style.display = "none";
  }
}

function show_camera_playback_toastMessage(errorMessage) {
  document.getElementById("camera_playback_toastMessage").style.display =
    "block";
  document.getElementById("playback_Message").textContent = errorMessage;
  var toastEl = document.getElementById("camera_playback_Toast");
  var toast = new bootstrap.Toast(toastEl, {
    delay: 3000,
    autohide: false,
  });
  toast.show();

  setTimeout(() => {
    close_camera_playback_toast_message();
  }, 3000);
}

function close_camera_playback_toast_message() {
  const toastEl = document.getElementById("camera_playback_toastMessage");
  toastEl.style.display = "none";
}

function backToCamera() {
  window.location.href = "/command_center.php";
  // window.location.href = "/dashboard.php?tab=property_builder";
}

function create_table_view(){
  const tableContainer = document.getElementById("playback_streaming_table_container");
  tableContainer.innerHTML = "";
  if (!allSearchedFiles || allSearchedFiles.length === 0) {
    tableContainer.innerHTML = '<div class="alert alert-info">No files found</div>';
    return;
  }
  let html = `
    <div class="table-responsive">
      <table id="playback_files_table" class="table table-bordered table-head-fixed text-nowrap table-hover" style="width:100%;">
        <thead>
          <tr>
            <th>Date</th>
            <th>Time</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>`;

  allSearchedFiles.forEach((file, index) => {
    html += `
      <tr>
        <td>${file.dateTime}</td>
        <td>${file.time}</td>
        <td>
          <button class="btn btn-sm btn-primary" onclick="playFromIndex(${index})">Play</button>
          <button class="btn btn-sm btn-info" onclick="showEnlargedPlaybackImage('${file.thumbnailUrl}', '${file.name}')">View</button>
        </td>
      </tr>`;
  });

  html += `</tbody></table></div>`;
  tableContainer.innerHTML = html;

  // Initialize DataTable with pagination
  if (!$.fn.DataTable.isDataTable("#playback_files_table")) {
    $("#playback_files_table").DataTable({
      "responsive": true,
      "order": [[0, "desc"]], // Sort by date descending
      "paging": true,
      "pageLength": 10,
      "searching": true,
      "info": true,
      "lengthChange": true,
      "lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]]
    });
  }
}

// Function to convert 24-hour time to 12-hour format
function convertTo12HourFormat(time24) {
  if (!time24) return '';
  
  const [hours, minutes, seconds] = time24.split(':').map(Number);
  const period = hours >= 12 ? 'PM' : 'AM';
  const hours12 = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
  
  return `${hours12.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')} ${period}`;
}

function toggleView() {
  const showTableView = document.getElementById('changeStreetViewEle').checked;
  const tableContainer = document.getElementById('playback_streaming_table');
  const timelineView = document.querySelector('#play_back_streaming_container_view');
  
  if (showTableView) {
    tableContainer.style.display = 'block';
    timelineView.style.display = 'none';
    stopStreamingImages();
  } else {
    startStreamingImages();
    tableContainer.style.display = 'none';
    timelineView.style.display = 'block';
  }
}

function showEnlargedPlaybackImage(thumbnailUrl, name) {
  document.getElementById('enlargedPlaybackImage').src = thumbnailUrl;
  document.getElementById('playbackImageModalTitle').textContent = `${name} Image`;
  $('#playbackImageModal').modal('show');
}

function playFromIndex(index) {
  if (allSearchedFiles && allSearchedFiles[index]) {
    currentIndex = index;
    const selectedFile = allSearchedFiles[index];
    $('#changeStreetViewEle').bootstrapSwitch('state', false);
    toggleView();
    showStreamingImageInPreview(selectedFile);
    updateCurrentSecondAndSelector(selectedFile);
    startStreamingImages();
    showSuccessGlobalToastMessage(`Started playback from ${selectedFile.time}`);
  } else {
    show_camera_playback_toastMessage('Invalid file index selected');
  }
}

// Function to show export options modal
function showExportModal() {
  if (!allSearchedFiles || allSearchedFiles.length === 0) {
    show_camera_playback_toastMessage('No images available to export. Please search for images first.');
    return;
  }
  
  $('#exportModal').modal('show');
}

// Function to increase playback speed
function increasePlaybackSpeed() {
  if (currentSpeedIndex < speedLevels.length - 1) {
    currentSpeedIndex++;
    playbackSpeed = speedLevels[currentSpeedIndex];
    updateSpeedIndicator();
    
    // If streaming is active, restart with new speed
    if (timer) {
      startStreamingImages();
    }
  }
}

// Function to decrease playback speed
function decreasePlaybackSpeed() {
  if (currentSpeedIndex > 0) {
    currentSpeedIndex--;
    playbackSpeed = speedLevels[currentSpeedIndex];
    updateSpeedIndicator();
    
    // If streaming is active, restart with new speed
    if (timer) {
      startStreamingImages();
    }
  }
}

// Function to update speed indicator display
function updateSpeedIndicator() {
  const speedIndicator = document.getElementById('speedIndicator');
  if (speedIndicator) {
    speedIndicator.textContent = speedLabels[currentSpeedIndex];
    
    // Add visual feedback for different speeds
    speedIndicator.className = 'speed-display';
    if (playbackSpeed < 1) {
      speedIndicator.classList.add('speed-slow');
    } else if (playbackSpeed > 1) {
      speedIndicator.classList.add('speed-fast');
    } else {
      speedIndicator.classList.add('speed-normal');
    }
  }
}

// Function to export images to video
function exportToVideo() {
  // Check if export is already in progress
  if (isExportInProgress) {
    console.log("Export already in progress. Please wait for the current export to complete.");
    return;
  }
  
  const startDate = document.getElementById('export_start_date').value;
  const endDate = document.getElementById('export_end_date').value;
  const startTime = document.getElementById('export_start_time').value;
  const endTime = document.getElementById('export_end_time').value;
  
  const fps = 5;
  const quality = 1080;
  
  if (!startDate || !endDate || !startTime || !endTime) {
    show_camera_playback_toastMessage('Please select both start and end dates and times');
    return;
  }
  
  // Create full datetime strings
  const startDateTime = new Date(`${startDate}T${startTime}`);
  const endDateTime = new Date(`${endDate}T${endTime}`);
  
  if (startDateTime >= endDateTime) {
    show_camera_playback_toastMessage('Start date/time must be before end date/time');
    return;
  }
  
  if (!allSearchedFiles || allSearchedFiles.length === 0) {
    show_camera_playback_toastMessage('No images available to export. Please search for images first.');
    return;
  }
  
  const filesInRange = allSearchedFiles.filter(file => {
    const fileDateTime = new Date(file?.dateTimeLocal);
    return fileDateTime >= startDateTime && fileDateTime <= endDateTime;
  });
  
  if (filesInRange.length === 0) {
    show_camera_playback_toastMessage('No files found in the selected date/time range');
    document.getElementById('export_progress').style.display = 'none';
    return;
  }
  
  isExportInProgress = true;
  const exportButton = document.querySelector('#exportModal .btn-success');
  if (exportButton) {
    exportButton.disabled = true;
    exportButton.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Exporting...';
  }
  
  document.getElementById('export_progress').style.display = 'block';
  document.getElementById('export_status').textContent = '0%';
  document.querySelector('#export_progress .progress-bar').style.width = '0%';
  
  console.log(`Exporting ${filesInRange.length} images from ${startDate} ${startTime} to ${endDate} ${endTime} (${fps} FPS, ${quality}p)`);
  
  createVideoFromImages(filesInRange, fps, quality);
}

function parseLocalDateTime(dateTimeStr) {
  const cleanStr = dateTimeStr.replace(" at ", " ");
  const [monthName, day, year, time, meridian] = cleanStr.split(" ");
  const monthIndex = new Date(`${monthName} 1, 2000`).getMonth(); // Get month number
  let [hour, minute, second] = time.split(":").map(Number);
  if (meridian === "PM" && hour !== 12) hour += 12;
  if (meridian === "AM" && hour === 12) hour = 0;
  return new Date(year, monthIndex, parseInt(day), hour, minute, second);
}

function createVideoFromImages(files, fps, quality) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  
  // Set canvas size based on quality
  const qualityMap = {
    '720': { width: 1280, height: 720 },
    '1080': { width: 1920, height: 1080 },
    '1440': { width: 2560, height: 1440 },
    '2160': { width: 3840, height: 2160 }
  };
  
  const dimensions = qualityMap[quality] || qualityMap['1080'];
  canvas.width = dimensions.width;
  canvas.height = dimensions.height;
  
  const stream = canvas.captureStream(parseInt(fps));
  const mediaRecorder = new MediaRecorder(stream, {
    mimeType: 'video/webm;codecs=vp9',
    videoBitsPerSecond: 8000000 // 8 Mbps
  });
  
  const chunks = [];
  let currentIndex = 0;
  
  mediaRecorder.ondataavailable = (event) => {
    chunks.push(event.data);
  };
  
  mediaRecorder.onstop = () => {
    const blob = new Blob(chunks, { type: 'video/webm' });
    const url = URL.createObjectURL(blob);
    
    // Create download link
    const a = document.createElement('a');
    a.href = url;
    a.download = `playback_export_${new Date().toISOString().split('T')[0]}.webm`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    
    // Reset export state
    isExportInProgress = false;
    
    // Re-enable export button
    const exportButton = document.querySelector('#exportModal .btn-success');
    if (exportButton) {
      exportButton.disabled = false;
      exportButton.innerHTML = '<i class="fas fa-download mr-1"></i>Export';
    }
    
    // Hide progress
    document.getElementById('export_progress').style.display = 'none';
    showSuccessGlobalToastMessage('Video export completed successfully!');
  };
  
  // Start recording
  mediaRecorder.start();
  
  // Process images frame by frame
  function processNextFrame() {
    if (currentIndex >= files.length) {
      mediaRecorder.stop();
      return;
    }
    
    const file = files[currentIndex];
    const img = new Image();
    img.crossOrigin = 'anonymous';
    
    img.onload = () => {
      ctx.fillStyle = '#000000';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      
      const scale = Math.min(canvas.width / img.width, canvas.height / img.height);
      const x = (canvas.width - img.width * scale) / 2;
      const y = (canvas.height - img.height * scale) / 2;
      
      ctx.drawImage(img, x, y, img.width * scale, img.height * scale);
      
      const progress = Math.round((currentIndex / files.length) * 100);
      document.getElementById('export_status').textContent = `${progress}%`;
      document.querySelector('#export_progress .progress-bar').style.width = `${progress}%`;
      
      currentIndex++;
      
      setTimeout(processNextFrame, 1000 / parseInt(fps));
    };
    
    img.onerror = () => {
      console.error('Failed to load image:', file.thumbnailUrl);
      currentIndex++;
      processNextFrame();
    };
    
    img.src = file.thumbnailUrl;
  }
  
  // Add error handling for MediaRecorder
  mediaRecorder.onerror = (event) => {
    console.error('MediaRecorder error:', event);
    isExportInProgress = false;
    const exportButton = document.querySelector('#exportModal .btn-success');
    if (exportButton) {
      exportButton.disabled = false;
      exportButton.innerHTML = '<i class="fas fa-download mr-1"></i>Export';
    }
    
    document.getElementById('export_progress').style.display = 'none';
    show_camera_playback_toastMessage('Export failed. Please try again.');
  };
  
  processNextFrame();
}