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

namespace SAAI\AI_Agents;

use SAAI\Abstracts\Abstract_AI_Agent;
use SAAI\Classes\Plan_Manager;
use SAAI\Factories\Vite_App;
use SAAI\Traits\Singleton_Trait;
use SAAI\Helpers\Helper;
use SAAI\REST\Product_Description_AI as Product_Description_AI_REST;
use SAAI\Classes\Product_Description;
use SAAI\Classes\Notification;
use SAAI\Interfaces\Bulk_Run_Agent_Interface;
use SAAI\AI_Agents\Sub_Agent\Product_Description_Form_Fill_AI;

/**
 * Product_Question_AI_Agent class.
 *
 * @since 1.0.2
 */
class Product_Description_AI extends Abstract_AI_Agent implements Bulk_Run_Agent_Interface {

    use Singleton_Trait;

    /**
     * Holds the class instance object
     *
     * @since 1.0.2
     * @var Product_Description_AI $instance object
     */
    protected static $instance;

    /**
     * Holds the settings data.
     *
     * @since 1.0.2
     * @var array Settings data.
     */
    protected $settings;

    /**
     * Constructor.
     *
     * @param mixed $data The prompt.
     */
    public function __construct( $data = null ) {

        $this->endpoint         = 'product-description';
        $this->ai_id            = "$this->endpoint-ai";
        $this->data             = $data;
        $this->default_settings = array(
            'enabled'                   => $this->maybe_enable_by_default(),
            'tones'                     => array(),
            'interesting_facts'         => array(),
            'age_focus'                 => array(),
            'target_audience'           => array(),
            'refund_guarantee'          => '',
            'description_length'        => '',
            'language'                  => 'default',
            'main_desc_length_check'    => 'yes',  // Enable main description length checks by default.
            'main_desc_check_frequency' => 12,     // Default check every 12 hours.
            'main_desc_min_word_count'  => 5,      // Default minimum word count.
            'main_desc_max_word_count'  => 50,     // Default maximum word count.
        );

        // Initialize settings.
        $this->settings = $this->get_settings();
    }

    /**
     * Set the prompt data.
     *
     * @param mixed $data The data prompt to be sent.
     *
     * @return void
     */
    public function set_data( $data ) {
        foreach ( $data as $key => $value ) {
            if ( is_array( $value ) ) {
                $this->data[ $key ] = implode( ', ', $value );
            } else {
                $this->data[ $key ] = $value;
            }
        }
    }

    /**
     * Run the agent query.
     *
     * @param array $params The parameters.
     *
     * @return array|\WP_Error
     */
    public function run_agent_query( $params = array() ) {
        $product_id = (int) $params['product_id'] ?? 0;
        $product    = wc_get_product( $product_id );

        if ( ! $product->get_meta( Product_Description::META_KEY ) ) {
            $this->run_product_description_form_fill( $product );
            return;
        }

        if ( ! $product->get_meta( Product_Description::META_KEY ) ) {
            return new \WP_Error(
                'saai_bulk_run_product_skipped',
                sprintf(
                    // translators: %s: product name.
                    _x( 'Product "%s" is skipped: please ensure that your product has an existing description so the AI can process it via bulk action.', 'rest_error_message', 'storeagent-ai-for-woocommerce' ),
                    $product->get_name()
                )
            );
        }

        $product_description = new Product_Description( $product );
        $data                = $product_description->get_data();
        $data['language']    = Helper::resolve_default_language( $data['language'] );

        $this->set_data( $data );
        $ai_response = $this->send_prompt();

        if ( is_wp_error( $ai_response ) ) {
            return new \WP_Error(
                'saai_bulk_run_product_error',
                sprintf(
                    // translators: %s: product name.
                    __( 'AI query failed for product "%1$s": %2$s', 'storeagent-ai-for-woocommerce' ),
                    $product->get_name(),
                    $ai_response->get_error_message()
                )
            );
        }

        return $ai_response;
    }

    /**
     * Run the product description form fill.
     *
     * @param \WC_Product $product The product.
     *
     * @return bool|\WP_Error
     */
    public function run_product_description_form_fill( $product ) {
        $product      = $product instanceof \WC_Product ? $product : wc_get_product( $product );
        $product_data = array(
            'product_url'               => get_permalink( $product->get_id() ),
            'product_name'              => $product->get_name(),
            'product_description'       => $product->get_description(),
            'product_short_description' => $product->get_short_description(),
        );

        $ai          = new Product_Description_Form_Fill_AI( array( 'product_data' => $product_data ) );
        $ai_response = $ai->send_prompt();

        if ( is_wp_error( $ai_response ) ) {
            return $ai_response;
        }

        $product_description = new Product_Description( $product->get_id() );

        $product_description->set_data( $ai_response['completion'] );
        $check = $product_description->save();

        if ( is_wp_error( $check ) ) {
            return $check;
        }

        return true;
    }
    /**
     * Save the object data.
     *
     * @param int   $product_id The product ID.
     * @param array $data The data to save.
     *
     * @return bool|\WP_Error
     */
    public function save_object_data( $product_id, $data ) {
        wp_update_post(
            array(
                'ID'           => $product_id,
                'post_content' => wp_kses_post( $data['description'] ),
            )
        );

        return true;
    }

    /**
     * Display the generate AI description button.
     *
     * @param \WP_Post $post The post object.
     * @return void
     */
    public function display_generate_ai_description_button( $post ) {
        if ( 'product' !== $post->post_type ) {
            return;
        }

        Helper::locate_admin_template( 'product-description-button.php', true );
    }

    /**
     * Enqueue the product description admin scripts.
     *
     * @since 1.0.2
     * @return void
     */
    public function enqueue_product_description_admin_scripts() {
        global $current_screen;

        if ( 'product' !== $current_screen->post_type || 'product' !== $current_screen->id ) {
            return;
        }

        $product_description = new Vite_App(
            'saai-product-description',
            'src/vanilla/admin/product-description/index.ts',
            array( 'jquery', 'wp-i18n', 'select2' ),
            array_merge(
                array(
                    'product_description_nonce' => wp_create_nonce( 'saai_get_product_description_form' ),
                    'productDescriptionRestUrl' => Product_Description_AI_REST::instance()->api_url,
                    'autoFillRestUrl'           => Product_Description_AI_REST::instance()->api_url . 'form-fill/',
                    'wpNonce'                   => wp_create_nonce( 'wp_rest' ),
                ),
                Plan_Manager::get_credit_usage_l10n()
            ),
            'saaiObj',
            array()
        );
        $product_description->enqueue();
    }

    /**
     * Get the product description form.
     *
     * @return void
     */
    public function ajax_get_product_description_form() {
        if ( ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ?? '' ), 'saai_get_product_description_form' ) || ! current_user_can( 'manage_woocommerce' ) ) {
            wp_die( 'Invalid nonce' );
        }

        $product_id = intval( $_POST['product_id'] ?? 0 );
        $product    = new Product_Description( $product_id );

        if ( ! $product instanceof Product_Description ) {
            wp_die( 'Invalid product' );
        }

        $data = $product->get_data();
        extract( $data ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract

        $template_path_dir = SAAI_PLUGIN_DIR_PATH . 'templates/admin/';

        include $template_path_dir . 'product-description-form/form-header.php';
        include $template_path_dir . 'product-description-form/step-1-get-started.php';
        include $template_path_dir . 'product-description-form/step-2-tone.php';
        include $template_path_dir . 'product-description-form/step-3-interesting-facts.php';
        include $template_path_dir . 'product-description-form/step-4-age-focus.php';
        include $template_path_dir . 'product-description-form/step-5-target-audience.php';
        include $template_path_dir . 'product-description-form/step-6-refund-guarantee.php';
        include $template_path_dir . 'product-description-form/step-7-keywords.php';
        include $template_path_dir . 'product-description-form/step-8-size-options.php';
        include $template_path_dir . 'product-description-form/step-9-ingredients.php';
        include $template_path_dir . 'product-description-form/step-10-description-length.php';
        include $template_path_dir . 'product-description-form/step-11-language.php';
        include $template_path_dir . 'product-description-form/form-footer.php';
        include $template_path_dir . 'product-description-form/description-preview.php';

        wp_die();
    }

    /**
     * Initialize settings for the AI agent.
     *
     * @return void
     */
    public function init_settings() {
        // Add a settings section for main description length checks.
        add_filter( 'saai_agent_settings_' . $this->ai_id, array( $this, 'add_main_description_length_check_settings' ), 10, 1 );
    }

    /**
     * Add settings for main description length checks.
     *
     * @param array $settings The existing settings.
     * @return array Modified settings.
     */
    public function add_main_description_length_check_settings( $settings ) {
        // Add to the settings array.
        $settings['main_desc_length_check'] = array(
            'type'        => 'toggle',
            'id'          => 'main_desc_length_check',
            'name'        => __( 'Main Description Length Checks', 'storeagent-ai-for-woocommerce' ),
            'description' => __( 'Automatically check for products with brief main descriptions and notify store owner.', 'storeagent-ai-for-woocommerce' ),
            'default'     => $this->default_settings['main_desc_length_check'],
        );

        $settings['main_desc_check_frequency'] = array(
            'type'        => 'select',
            'id'          => 'main_desc_check_frequency',
            'name'        => __( 'Check Frequency', 'storeagent-ai-for-woocommerce' ),
            'description' => __( 'How often to check for main product descriptions that are too short.', 'storeagent-ai-for-woocommerce' ),
            'default'     => $this->default_settings['main_desc_check_frequency'],
            'options'     => array(
                '6'  => __( 'Every 6 hours', 'storeagent-ai-for-woocommerce' ),
                '12' => __( 'Every 12 hours', 'storeagent-ai-for-woocommerce' ),
                '24' => __( 'Every 24 hours', 'storeagent-ai-for-woocommerce' ),
                '48' => __( 'Every 2 days', 'storeagent-ai-for-woocommerce' ),
                '72' => __( 'Every 3 days', 'storeagent-ai-for-woocommerce' ),
            ),
            'conditions'  => array(
                array(
                    'id'    => 'main_desc_length_check',
                    'value' => 'yes',
                ),
            ),
        );

        // Add settings for word count thresholds.
        $settings['main_desc_min_word_count'] = array(
            'type'        => 'number',
            'id'          => 'main_desc_min_word_count',
            'name'        => __( 'Minimum Word Count', 'storeagent-ai-for-woocommerce' ),
            'description' => __( 'Products with main descriptions above this many words will be considered for improvement. Set to 0 to catch empty descriptions.', 'storeagent-ai-for-woocommerce' ),
            'default'     => $this->default_settings['main_desc_min_word_count'],
            'min'         => 0, // Allow 0 to catch empty descriptions.
            'conditions'  => array(
                array(
                    'id'    => 'main_desc_length_check',
                    'value' => 'yes',
                ),
            ),
        );

        $settings['main_desc_max_word_count'] = array(
            'type'        => 'number',
            'id'          => 'main_desc_max_word_count',
            'name'        => __( 'Maximum Word Count', 'storeagent-ai-for-woocommerce' ),
            'description' => __( 'Products with main descriptions below this many words will be considered as needing improvement.', 'storeagent-ai-for-woocommerce' ),
            'default'     => $this->default_settings['main_desc_max_word_count'],
            'min'         => 1,
            'conditions'  => array(
                array(
                    'id'    => 'main_desc_length_check',
                    'value' => 'yes',
                ),
            ),
        );

        return $settings;
    }

    /**
     * Run hooks related to the AI agent.
     *
     * @return void
     */
    public function run() {
        if ( ! $this->is_enabled() ) {
            return;
        }

        // Register init_settings on init hook to ensure textdomain is loaded.
        add_action( 'init', array( $this, 'init_settings' ) );

        add_action( 'edit_form_after_title', array( $this, 'display_generate_ai_description_button' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_product_description_admin_scripts' ) );
        add_action( 'wp_ajax_saai_get_product_description_form', array( $this, 'ajax_get_product_description_form' ) );
    }

    /**
     * Maybe enable the AI agent by default.
     *
     * @since 1.0.4
     * @return string
     */
    public function maybe_enable_by_default() {
        return 'yes';
    }

    /**
     * Enable the AI agent and schedule tasks.
     *
     * @since 1.0.0
     * @return bool True if the agent was enabled successfully, false otherwise.
     */
    public function enable() {
        $result = parent::enable();
        return $result;
    }
}
