<?php

namespace AC_SYNC\Includes\Classes\Cron {
  if (!defined('ABSPATH')) exit; // Exit if accessed directly
  use AC_SYNC\Includes\Classes\Product\Action_Wear_Product as Product;
  use AC_SYNC\Includes\Classes\Sync\Action_Wear_Sync as Sync;
  use AC_SYNC\Includes\Classes\Logger\Action_Wear_Log as Log;
  use AC_SYNC\Includes\Classes\Utils\Action_Wear_Utils as Utils;
  use AC_SYNC\Includes\Classes\Differential\Action_Wear_Differential as Differential;
  use AC_SYNC\Includes\Classes\Setting\Action_Wear_Setting_Debug_Mode as DebugMode;


  class Action_Wear_Cron
  {

    const DEBUG_MODE = true;
    const DISABLED = false;

    /**
     * Cronjob manager exec function
     *
     * All scheduled operations are grouped into this function
     *
     **/
    public static function exec($direct = false)
    {

      if (self::DISABLED) return;
      if (!Utils::cronjobCanRun() && !$direct) return;
      @ignore_user_abort(true);
      @set_time_limit(300);
      @ini_set('memory_limit', '512M');

      // Cleanup orphaned temp files from crashed sync processes
      self::cleanupOrphanedTempFiles();

      if (Sync::isLocked()) {
        $msg = "Cronjob locked, processo già in esecuzione";
        if (self::DEBUG_MODE) Log::write($msg, Log::INFO, Log::CONTEXT_CRONJOB);
        return $msg;
      }

      if (self::DEBUG_MODE) Log::write("Inizio esecuzione del cronjob", Log::INFO, Log::CONTEXT_CRONJOB);

      Sync::lock();

      try {
        $operations = Differential::getRegisteredOperations();
        foreach ($operations as $operation) {
          $differential = new Differential(new $operation);
          if (!$differential->isOperationToExecute()) continue;
          $differential->execute();
        }
      } catch (\Throwable $e) {
        Log::write("Cronjob error: " . $e->getMessage(), Log::ERROR, Log::CONTEXT_CRONJOB);
      } finally {
        // Always release the lock, even if an error occurred
        Sync::unlock();
      }

      if (self::DEBUG_MODE) Log::write("Termino esecuzione del cronjob", Log::INFO, Log::CONTEXT_CRONJOB);
      Sync::updateLastSync(time());
    }

    /**
     * Clean up orphaned temporary files from crashed sync processes.
     * Removes files and directories older than 4 hours.
     */
    public static function cleanupOrphanedTempFiles()
    {
      $uploadDir = wp_upload_dir();
      $baseDir = $uploadDir['basedir'];
      $maxAge = 4 * HOUR_IN_SECONDS;
      $now = time();

      // Clean orphaned JSON temp files
      $patterns = [
        $baseDir . '/actionwear-bulk-*-sync-*.json',
        $baseDir . '/actionwear-bulk-sync-*.json',
      ];

      foreach ($patterns as $pattern) {
        $files = glob($pattern);
        if (!is_array($files)) continue;
        foreach ($files as $file) {
          if (($now - filemtime($file)) > $maxAge) {
            @unlink($file);
          }
        }
      }

      // Clean orphaned chunk directories
      $chunkDirs = glob($baseDir . '/actionwear-chunks-*', GLOB_ONLYDIR);
      if (is_array($chunkDirs)) {
        foreach ($chunkDirs as $dir) {
          if (($now - filemtime($dir)) > $maxAge) {
            $files = glob($dir . '/*.json');
            if (is_array($files)) {
              foreach ($files as $file) {
                @unlink($file);
              }
            }
            @rmdir($dir);
          }
        }
      }
    }
  }
}
