<?php
namespace FuseCommerce\Jobs;

use FuseCommerce\Services\ProductIndexerService;
use FuseCommerce\Services\ProductSerializerService;
use FuseCommerce\Services\CategoryIndexerService;
use FuseCommerce\Services\AttributeIndexerService;
use FuseCommerce\Services\TagIndexerService;
use FuseCommerce\Services\FileStorageService;
use FuseCommerce\Repositories\ProductRepository;

if ( ! defined( 'ABSPATH' ) ) exit;



class IndexProducts {
    private $lockFile = null;
    private $lockHandle = null;

    public function run(): void {
        // Acquire lock before running
        if (!$this->acquireLock()) {
            // IndexProducts: Could not acquire lock, another process is running
            return;
        }

        // Register shutdown function to clean up on timeout/fatal errors
        register_shutdown_function([$this, 'releaseLock']);

        try {
            // Initialize services
            $product_repository  = new ProductRepository();
            $serializer          = new ProductSerializerService();
            $category_indexer    = new CategoryIndexerService( $product_repository );
            $attribute_indexer   = new AttributeIndexerService( $product_repository );
            $tag_indexer         = new TagIndexerService( $product_repository );
            $file_storage        = new FileStorageService();

            $indexer_service = new ProductIndexerService(
                $product_repository,
                $serializer,
                $category_indexer,
                $attribute_indexer,
                $tag_indexer,
                $file_storage
            );

            // Run indexing
            $result = $indexer_service->startOrResumeIndexing();

            if ( ! $result['success'] ) {
                error_log( 'FtlCommerce IndexProducts Job: ' . $result['message'] );
            }
        } finally {
            // Always release the lock when done
            $this->releaseLock();
        }
    }

    public function canRun(): bool {
        // Check if WooCommerce is active
        return class_exists( 'WooCommerce' );
    }

    private function acquireLock(): bool {
        $this->lockFile = get_temp_dir() . 'fusecommerce_index_products.lock';
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- flock requires direct file handle
        $this->lockHandle = fopen($this->lockFile, 'c');

        if ($this->lockHandle === false) {
            return false;
        }

        // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- flock may emit warnings
        if (!flock($this->lockHandle, LOCK_EX | LOCK_NB)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- flock requires direct file handle
            fclose($this->lockHandle);
            $this->lockHandle = null;
            return false;
        }

        return true;
    }

    private function releaseLock(): void {
        if ($this->lockHandle !== null) {
            flock($this->lockHandle, LOCK_UN);
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- flock requires direct file handle
            fclose($this->lockHandle);
            $this->lockHandle = null;
        }

        if ($this->lockFile !== null && file_exists($this->lockFile)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink -- wp_delete_file doesn't work for lock files
            @unlink($this->lockFile);
        }
    }
}