<?php
/**
 * Author: Rymera Web Co.
 *
 * @package SAAI\Automations
 */

namespace SAAI\Automations;

use SAAI\Traits\Singleton_Trait;
use SAAI\AI_Agents\Product_Description_AI;
use SAAI\Classes\Notification;
use SAAI\Helpers\Helper;

/**
 * Product_Description_Automations class.
 *
 * This class handles automated tasks related to product descriptions.
 *
 * @since 1.0.0
 */
class Product_Description_Automations {

    use Singleton_Trait;

    /**
     * Holds the class instance object
     *
     * @since 1.0.0
     * @var Product_Description_Automations $instance object
     */
    protected static $instance;

    /**
     * Action hook for the main description length check.
     */
    const MAIN_DESCRIPTION_LENGTH_CHECK_ACTION = 'saai_check_product_main_description_length';

    /**
     * Batch size for processing products.
     */
    const BATCH_SIZE = 50;

    /**
     * Maximum notifications to create per batch run.
     */
    const MAX_NOTIFICATIONS_PER_RUN = 5;

    /**
     * Setup action hooks when class is initialized.
     */
    public function __construct() {
        add_action( self::MAIN_DESCRIPTION_LENGTH_CHECK_ACTION, array( $this, 'handle_main_description_length_check' ) );
    }

    /**
     * Schedule the main description length check.
     *
     * @param array $settings The settings to use for scheduling.
     * @return void
     */
    public function schedule_main_description_length_check( $settings ) {
        // Only schedule if the produt descriptions AI is enabled and the automation is enabled.
        $product_description_ai = Product_Description_AI::instance();
        if ( ! $product_description_ai->is_enabled() ) {
            return;
        }

        if ( ! isset( $settings['main_desc_length_check'] ) || 'yes' !== $settings['main_desc_length_check'] ) {
            // If the setting is disabled, unschedule any existing tasks.
            $this->unschedule_main_description_length_check();
            return;
        }

        // Get frequency setting (hours) - ensure proper type conversion.
        $frequency = 12; // Default frequency.
        if ( isset( $settings['main_desc_check_frequency'] ) ) {
            $frequency_value = $settings['main_desc_check_frequency'];
            // Always convert to integer to ensure proper handling.
            $frequency = intval( $frequency_value );
        }

        if ( $frequency < 1 ) {
            $frequency = 12; // Default to 12 hours.
        }

        // If the action is already scheduled, don't schedule it again.
        if ( as_next_scheduled_action( self::MAIN_DESCRIPTION_LENGTH_CHECK_ACTION ) ) {
            return;
        } else {
            // Schedule the action to run at the specified interval.
            as_schedule_recurring_action(
                time(), // Start now.
                $frequency * HOUR_IN_SECONDS, // Convert hours to seconds.
                self::MAIN_DESCRIPTION_LENGTH_CHECK_ACTION
            );
        }
    }

    /**
     * Unschedule the main description length check.
     *
     * @return void
     */
    public function unschedule_main_description_length_check() {
        as_unschedule_all_actions( self::MAIN_DESCRIPTION_LENGTH_CHECK_ACTION );
    }

    /**
     * Handles the scheduled main description length check.
     *
     * This method is called by the scheduled cron job to check for products
     * with main descriptions that could be improved with AI.
     *
     * @return void
     */
    public function handle_main_description_length_check() {
        // Get the Product Description AI agent instance.
        $product_description_ai = Product_Description_AI::instance();
        $settings               = $product_description_ai->get_settings();

        // Only proceed if main description length check is enabled.
        if ( ! isset( $settings['main_desc_length_check'] ) || 'yes' !== $settings['main_desc_length_check'] ) {
            return;
        }

        $min_words = isset( $settings['main_desc_min_word_count'] ) ?
                absint( $settings['main_desc_min_word_count'] ) : 0;
        $max_words = isset( $settings['main_desc_max_word_count'] ) ?
                absint( $settings['main_desc_max_word_count'] ) : 50;

        // Get products with main descriptions - using random ordering.
        $notification_queue_id = null; // Initialize notification queue ID.
        $batch_sizes           = array(
            'current' => self::BATCH_SIZE,
        );
        $products_count        = $this->get_products_count( $notification_queue_id );
        $offset                = ( $products_count * $batch_sizes['current'] ) - $batch_sizes['current'];

        $args = array(
            'status'  => 'publish',
            'limit'   => self::BATCH_SIZE, // Process in batches to prevent timeouts.
            'orderby' => 'rand', // Random ordering.
        );

        $products = wc_get_products( $args );

        if ( empty( $products ) ) {
            return;
        }

        $notification_count = 0;

        foreach ( $products as $product ) {
            // Stop processing if we've hit the maximum allowed notifications for this run.
            if ( $notification_count >= self::MAX_NOTIFICATIONS_PER_RUN ) {
                break;
            }

            $product_id = $product->get_id();

            // Check the main description (post_content) not the short_description.
            $main_description = $product->get_description();

            // Skip products without any main description if we're not checking for empty (min > 0).
            if ( empty( $main_description ) && $min_words > 0 ) {
                continue;
            }

            // Count words in the main description.
            $word_count = str_word_count( wp_strip_all_tags( $main_description ) );

            // Check if word count falls within our target range for improvement.
            if ( $word_count >= $min_words && $word_count <= $max_words ) {
                // Check if we already have a notification for this product.
                $existing_notification = Notification::instance()->get_all(
                    array(
                        'product_id'        => $product_id,
                        'notification_type' => 'main_description_length',
                        'status'            => array( 'pending' ),
                        'agent'             => 'Product_Description_AI',
                    )
                );
                if ( ! empty( $existing_notification ) ) {
                    continue;
                }

                // Create notification for this product.

                $notification_id = Notification::instance()->create(
                    Notification::TYPE_WARNING,
                    sprintf(
                    /* translators: %s: Product name */
                        __( 'Main description is too short', 'storeagent-ai-for-woocommerce' ),
                        $product->get_name()
                    ),
                    sprintf(
                    /* translators: %1$s: Product name, %2$d: Word count */
                        __( 'The main product description for "%1$s" is only %2$d words. Our AI can help expand it to be more compelling for customers.', 'storeagent-ai-for-woocommerce' ),
                        $product->get_name(),
                        $word_count
                    ),
                    'Product_Description_AI',
                    $product_id,
                    array( 'notification_type' => 'main_description_length' ),
                    array(
                        array(
                            'action' => 'expand_description',
                            'label'  => __( 'Expand with AI', 'storeagent-ai-for-woocommerce' ),
                            'url'    => admin_url( 'post.php?post=' . $product_id . '&action=edit&saai_action=expand_description' ),
                            'target' => '_blank',
                        ),
                    )
                );
                if ( $notification_id ) {
                    ++$notification_count;
                }
            }
        }
    }

    /**
     * Handle settings saved via REST API.
     *
     * @param array           $response     The response data.
     * @param array           $settings     The new settings.
     * @param array           $old_settings The old settings.
     * @param WP_REST_Request $request      The request object.
     *
     * @return array The response data.
     */
    public function handle_rest_settings_save( $response, $settings, $old_settings, $request ) { // phpcs:ignore
        // Ensure we have complete settings by merging with defaults.
        $this->settings = wp_parse_args( $settings, $this->default_settings );

        // Unschedule any existing main description length check.
        $this->unschedule_main_description_length_check();

        // Schedule the main description length check.
        $this->schedule_main_description_length_check( $this->settings );

        return $response;
    }

    /**
     * Run the automation setup.
     *
     * @return void
     */
    public function run() {
        // Get the Product Description AI agent instance and its settings.
        $product_description_ai = Product_Description_AI::instance();

        // Only run automations if the AI agent is enabled.
        if ( ! $product_description_ai->is_enabled() ) {
            return;
        }

        // Hook into REST API settings save response.
        add_filter( 'saai_rest_product-description-ai_settings_save_response', array( $this, 'handle_rest_settings_save' ), 10, 4 );

        // Add JavaScript to auto-trigger the description generator from URL parameters.
        add_action( 'admin_footer', array( $this, 'auto_trigger_description_generator' ) );
    }

    /**
     * Get count of processed products.
     *
     * @param int|null $notification_queue_id The notification queue ID.
     *
     * @return int The count of processed products.
     */
    public function get_products_count( $notification_queue_id = null ) {
        return apply_filters( 'saai_get_product_count', 0, $notification_queue_id );
    }

    /**
     * Add JavaScript to auto-trigger the description generator from URL parameters.
     *
     * @return void
     */
    public function auto_trigger_description_generator() {
        // Only add on product edit screens.
        global $current_screen;
        if ( ! $current_screen || 'product' !== $current_screen->id ) {
            return;
        }

        ?>
        <script type="text/javascript">
        jQuery(document).ready(function($) {
            // Check if the URL contains the auto-trigger parameter.
            const urlParams = new URLSearchParams(window.location.search);
            if (urlParams.has('saai_action') && urlParams.get('saai_action') === 'expand_description') {
                // Wait for the button to be fully initialized
                setTimeout(function() {
                    try {
                        // Target the button directly by ID
                        const button = $('#generate-ai-description-button');
                        
                        if (button.length > 0) {
                            button.click();
                        } else {
                            // Simple fallback
                            $('.saai-product-description-button, [data-action="expand-description"], button:contains("AI Description")').first().click();
                        }
                    } catch (error) {
                        // Do nothing
                    }
                }, 1500);
            }
        });
        </script>
        <?php
    }
}
