<?php
namespace SPAATG\Controller;

if ( ! defined( 'ABSPATH' ) ) {
 exit; // Exit if accessed directly.
}

use SPAATG\Controller\Queue\MediaLibraryQueue as MediaLibraryQueue;
use SPAATG\Controller\Queue\Queue as Queue;
use SPAATG\ShortPixelLogger\ShortPixelLogger as Log;

// Class for controlling bulk and reporting.
class BulkController
{
   protected static $instance;
   protected static $logName = 'spaatg-bulk-logs';

   protected $logs;

   public function __construct()
   {

   }

   public static function getInstance()
   {
      if ( is_null(self::$instance))
         self::$instance = new BulkController();

     return self::$instance;
   }

   /** Create a new bulk, enqueue items for bulking
	   * @param $type String media is supported.
	   * @param $customOp String bulk-undoAI is supported.
   */
   public function createNewBulk($type = 'media', $args = [])
   {
      $defaults = [
          'customOp' => null,
          'filters' => [],

      ];

      $args = wp_parse_args($args, $defaults);

      $queueController = new QueueController(['is_bulk' => true]);

			$fs = \wpSPAATG()->filesystem();
			$storageDir = $fs->getDirectory(SPAATG_STORAGE_FOLDER);
			$current_log = $fs->getFile($storageDir->getPath() . 'current_bulk_' . $type . '.log');

			// When starting new bulk remove any open 'current logs';
			if ($current_log->exists() && $current_log->is_writable())
			{
				 $current_log->delete();
			}

      $Q = $queueController->getQueue($type);

      if (! is_null($args['customOp']))
      {
        $customOp = $args['customOp'];

	        if ($customOp == 'bulk-undoAI')
	        {
	          $args['numitems'] = 5;
	          $args['retry_limit'] = 5;
	          $args['process_timeout'] = 3000;

	        }

					$args = apply_filters('spaatg/bulk/custom_options', $args);

      }


      $options = $Q->createNewBulk($args);


      return $Q->getStats();
   }

	 public function isBulkRunning($type = 'media')
	 {
       $queueControl = new QueueController(['is_bulk' => true]);
       $queue = $queueControl->getQueue($type);

			 $stats = $queue->getStats();

			 if ( $stats->is_finished === false && $stats->total > 0)
			 {
			 	return true;
		 	 }
			 else
			 {
			 	return false;
			}
	 }

			 public function isAnyBulkRunning()
		 {
			   return $this->isBulkRunning('media');
		 }

	   // Check if the media bulk queue is on a supported AI custom operation.
	   public function getAnyCustomOperation()
	   {
	    return $this->getCustomOperation('media');

   }

   public function getCustomOperation($qname)
   {
     $queueControl = new QueueController(['is_bulk' => true]);
     $q = $queueControl->getQueue($qname);

     $op = $q->getCustomDataItem('customOperation');
     return $op;
   }

   /*** Start the bulk run. Must deliver all queues at once due to processQueue bundling */
   public function startBulk($types = 'media')
   {
       $queueControl = new QueueController(['is_bulk' => true]);

			 if (! is_array($types))
			 	 $types = array($types);

			 foreach($types as $type)
			 {
         $q = $queueControl->getQueue($type);
	       $q->startBulk();
			 }

       return  $q->getStats();
   }

   public function finishBulk($type = 'media')
   {
     $queueControl = new QueueController(['is_bulk' => true]);

     $q = $queueControl->getQueue($type);

		 $this->addLog($q);

		 $op = $q->getCustomDataItem('customOperation');

	     $q->resetQueue();
   }

   public function getLogs()
   {
        if (is_null($this->logs))
        {
          $logs = get_option(self::$logName, array());
          $this->logs = $logs;
        }
        return $this->logs;
   }

	 public function getLog($logName)
	 {
  		 $fs = \wpSPAATG()->filesystem();
	       $storageDir = $fs->getDirectory(SPAATG_STORAGE_FOLDER);
       $storagePath = realpath($storageDir->getPath());

       // Construct the full path
       $fullPath = $storageDir->getPath() . $logName; // .log not passed  anymore
       $resolvedPath = realpath($fullPath);

       // Ensure the resolved path is within the storage directory
       if ($resolvedPath === false || strpos($resolvedPath, $storagePath) !== 0) {
           return false;  // Path traversal attempt detected
       }


			 $log = $fs->getFile($storageDir->getPath() . $logName);
			 if ($log->exists())
			 	 return $log;
			 else
			 	return false;
	 }



	 public function getLogData($fileName)
	 {
		 		$logs = $this->getLogs();

				foreach($logs as $log)
				{
					 if (isset($log['logfile']) && $log['logfile'] == $fileName)
           {
					 	 return $log;
           }
				}

				return false;
	 }

   protected function addLog($q)
   {
				$stats = $q->getStats(); // for the log
				$type = $q->getType();

        if ($stats->done == 0 && $stats->fatal_errors == 0)
				{
          return; // nothing done, don't log
				}

        $data['processed'] = $stats->done;
        $data['not_processed'] = $stats->in_queue;
        $data['errors'] = $stats->errors;
        $data['fatal_errors'] = $stats->fatal_errors;

				$webpcount = $q->getCustomDataItem('webpcount');
				$avifcount = $q->getCustomDataItem('avifcount');
				$basecount = $q->getCustomDataItem('basecount');

				if (property_exists($stats, 'images'))
					$data['total_images'] = $stats->images->images_done;

        $data['type'] = $type;
				if ($q->getCustomDataItem('customOperation'))
				{
					$data['operation'] = $q->getCustomDataItem('customOperation');
				}
        $data['date'] = time();

        $logs = $this->getLogs();
        $fs = \wpSPAATG()->filesystem();
        $storageDir = $fs->getDirectory(SPAATG_STORAGE_FOLDER);

        if (count($logs) == 10) // remove logs if more than 10.
        {
          $log = array_shift($logs);
					if (isset($data['logfile']))
					{
						$logfile = $data['logfile'];

	          $fileLog = $fs->getFile($storageDir->getPath() . $logfile);
	          if ($fileLog->exists())
	            $fileLog->delete();
					}
        }

        $fileLog = $fs->getFile($storageDir->getPath() . 'current_bulk_' . $type . '.log');
        $moveLog = $fs->getFile($storageDir->getPath() . 'bulk_' . $type. '_' . $data['date'] . '.log');

        if ($fileLog->exists())
          $fileLog->move($moveLog);

				$data['logfile'] = 'bulk_' . $type . '_' . $data['date'] . '.log';
        $logs[] = $data;

        $this->saveLogs($logs);
   }

   protected function saveLogs($logs)
   {
        if (is_array($logs) && count($logs) > 0)
          update_option(self::$logName, $logs, false);
        else
          delete_option(self::$logName);
   }

	 // Removes Bulk Log .
   public static function uninstallPlugin()
   {
      delete_option(self::$logName);
   }

}  // class
