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

namespace SAAI\AI_Agents;

use SAAI\Abstracts\Abstract_AI_Agent;
use SAAI\Classes\Product_Question;
use SAAI\Factories\Vite_App;
use SAAI\REST\Product_Questions_AI as Product_Questions_AI_REST;
use SAAI\Traits\Singleton_Trait;
use SAAI\Traits\Template_Loader;

/**
 * Product_Question_AI_Agent class.
 *
 * @since 1.0.0
 */
class Product_Questions_AI extends Abstract_AI_Agent {

    use Singleton_Trait;
    use Template_Loader;

    const PRODUCT_QUESTIONS_DATA_SOURCE_META_KEY = '_product_questions_data_sources';

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

    /**
     * Constructor.
     *
     * @param mixed $data The prompt.
     */
    public function __construct( $data = null ) {
        $this->endpoint = 'product-questions';
        $this->ai_id    = "$this->endpoint-ai";
        $this->data     = $data;
    }

    /**
     * Enqueue scripts and styles for the front end.
     *
     * @since 1.0.0
     * @return void
     */
    public function wp_enqueue_scripts() {
        if ( is_singular( 'product' ) ) {
            $product  = wc_get_product();
            $settings = $this->get_settings();

            $l10n = array(
                'restUrl'        => Product_Questions_AI_REST::instance()->api_url . "{$product->get_id()}/ask",
                'wpNonce'        => wp_create_nonce( 'wp_rest' ),
                'widgetEnabled'  => $settings['enableWidget'] ?? 'no',
                'widgetPosition' => $settings['widgetPosition'] ?? 'bottom-right',
                'debug'          => true, // Add a debug flag.
            );
            $app  = new Vite_App(
                'product-questions-script',
                'src/vanilla/single/product/product-question.ts',
                array( 'jquery', 'wp-i18n' ),
                $l10n,
                'saaiPqObj',
                array( 'storeagent-fonts' )
            );
            $app->enqueue();
        }
    }

    /**
     * Display the questions tab on the front end product page.
     *
     * @since 1.0.0
     */
    public function display_questions_tab() {
        global $product;

        $page        = isset( $_GET['questions-page'] ) ? absint( $_GET['questions-page'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $per_page    = 10;
        $total_pages = ceil( Product_Question::get_questions_count( $product->get_id() ) / $per_page );

        $this->load_template(
            'frontend/product-questions.php',
            array(
                'questions'   => Product_Question::get_questions( $product->get_id(), $page, $per_page ),
                'total_pages' => $total_pages,
                'product'     => $product,
                'page'        => $page,
            )
        );
    }

    /**
     * Add the questions tab to the product page.
     *
     * @param array $tabs The tabs.
     *
     * @since 1.0.0
     * @return array
     */
    public function product_tabs( $tabs ) {

        $title = $this->get_settings( 'tabName' );

        $tabs['product_questions'] = array(
            'title'    => $title ? $title : __( 'Q&A', 'storeagent-ai-for-woocommerce' ),
            'priority' => 50,
            'callback' => array( $this, 'display_questions_tab' ),
        );

        return $tabs;
    }

    /**
     * Maybe add the product questions mod count.
     *
     * @since 1.0.0
     * @return void
     */
    public function maybe_add_product_questions_mod_count() {

        global $submenu;

        if ( $this->get_settings( 'moderateQnA' ) !== 'yes' ) {
            return;
        }

        $count     = wp_count_posts( Product_Question::POST_TYPE )->pending;
        $main_menu = 'edit.php?post_type=product';
        if ( isset( $submenu[ $main_menu ] ) ) {
            $submenu_slug = 'edit.php?post_type=' . Product_Question::POST_TYPE;
            foreach ( $submenu[ $main_menu ] as &$menu ) {
                if ( ! empty( $menu[2] ) && $submenu_slug === $menu[2] ) {
                    $menu[0] .= sprintf( ' <span class="awaiting-mod count-%s"><span class="plugin-count">%s</span></span>', $count, $count );
                    break;
                }
            }
        }
    }

    /**
     * Add the meta box.
     *
     * @since 1.0.0
     * @return void
     */
    public function register_product_questions_meta_box() {
        // Only show if the feature is enabled in settings.
        if ( $this->get_settings( 'enableDataSources' ) !== 'yes' ) {
            return;
        }

        add_meta_box(
            'product_data_sources',
            __( 'Product Questions', 'storeagent-ai-for-woocommerce' ),
            array( $this, 'render_product_questions_meta_box' ),
            'product',
            'normal',
            'low'
        );
    }

    /**
     * Render the product questions meta box.
     *
     * @param \WP_Post $post The post object.
     *
     * @since 1.0.0
     * @return void
     */
    public function render_product_questions_meta_box( $post ) {

        $data_sources = get_post_meta( $post->ID, self::PRODUCT_QUESTIONS_DATA_SOURCE_META_KEY, true );
        $this->load_template(
            'admin/product-questions-meta-box.php',
            array( 'data_sources' => $data_sources )
        );
    }

    /**
     * Save the product questions meta box.
     *
     * @param int      $post_id The post ID.
     * @param \WP_Post $post    The post object.
     *
     * @since 1.0.0
     * @return void
     */
    public function save_product_questions_meta_box( $post_id, $post ) {
        if ( 'product' !== $post->post_type ) {
            return;
        }

        if ( ! isset( $_POST['saai_product_questions_nonce'] ) || ! wp_verify_nonce( $_POST['saai_product_questions_nonce'], 'saai_product_questions_meta_box' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
            return;
        }

        $data_sources = isset( $_POST['saai_product_questions_data_sources'] ) ? $_POST['saai_product_questions_data_sources'] : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
        $data_sources = array_filter( array_unique( array_map( 'esc_url_raw', $data_sources ) ) );
        update_post_meta( $post_id, self::PRODUCT_QUESTIONS_DATA_SOURCE_META_KEY, $data_sources );
    }

    /**
     * Publish a product question - callback for notification.
     *
     * @param array $args The arguments. Must contain question_id.
     * @return bool|WP_Error True on success, WP_Error on failure.
     */
    public function publish_qa( $args ) {
        if ( empty( $args['question_id'] ) ) {
            return new \WP_Error( 'missing_question_id', __( 'Question ID is required.', 'storeagent-ai-for-woocommerce' ) );
        }

        $question_id = absint( $args['question_id'] );
        $post        = get_post( $question_id );

        if ( ! $post || Product_Question::POST_TYPE !== $post->post_type ) {
            return new \WP_Error( 'invalid_question', __( 'Invalid question.', 'storeagent-ai-for-woocommerce' ) );
        }

        // Set the post status to publish.
        $result = wp_update_post(
            array(
                'ID'          => $question_id,
                'post_status' => 'publish',
            )
        );

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

        return true;
    }

    /**
     * Discard a product question (trash it) - callback for notification.
     *
     * @param array $args The arguments. Must contain question_id.
     * @return bool|WP_Error True on success, WP_Error on failure.
     */
    public function discard_qa( $args ) {
        if ( empty( $args['question_id'] ) ) {
            return new \WP_Error( 'missing_question_id', __( 'Question ID is required.', 'storeagent-ai-for-woocommerce' ) );
        }

        $question_id = absint( $args['question_id'] );
        $post        = get_post( $question_id );

        if ( ! $post || Product_Question::POST_TYPE !== $post->post_type ) {
            return new \WP_Error( 'invalid_question', __( 'Invalid question.', 'storeagent-ai-for-woocommerce' ) );
        }

        // Trash the post.
        $result = wp_trash_post( $question_id );

        if ( ! $result ) {
            return new \WP_Error( 'trash_failed', __( 'Failed to trash the question.', 'storeagent-ai-for-woocommerce' ) );
        }

        return true;
    }

    /**
     * Get admin URL for editing a question.
     *
     * @param int $question_id The question post ID.
     * @return string The admin URL.
     */
    public function get_question_edit_url( $question_id ) {
        return admin_url( 'post.php?post=' . absint( $question_id ) . '&action=edit' );
    }

    /**
     * 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( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
        add_filter( 'woocommerce_product_tabs', array( $this, 'product_tabs' ) );
        add_action( 'admin_menu', array( $this, 'maybe_add_product_questions_mod_count' ), 100 );
        add_action( 'add_meta_boxes', array( $this, 'register_product_questions_meta_box' ) );
        add_action( 'save_post', array( $this, 'save_product_questions_meta_box' ), 10, 2 );

        // Register the action handler for the notification.
        add_filter( 'saai_notification_custom_action_url', array( $this, 'handle_notification_action_url' ), 10, 3 );
    }

    /**
     * Handle the notification action URL.
     *
     * @param string $url    The URL.
     * @param string $action The action.
     * @param array  $data   The notification data.
     * @return string The URL.
     */
    public function handle_notification_action_url( $url, $action, $data ) {
        // Only handle our own notifications.
        if ( empty( $data['agent'] ) || 'Product_Questions_AI' !== $data['agent'] ) {
            return $url;
        }

        // Check if we have a question ID.
        if ( empty( $data['extra']['question_id'] ) ) {
            return $url;
        }

        $question_id = $data['extra']['question_id'];

        // Handle the review_question action.
        if ( 'review_question' === $action ) {
            return $this->get_question_edit_url( $question_id );
        }

        return $url;
    }

    /**
     * Initialize settings for the Product Questions AI.
     *
     * @return void
     */
    public function init_settings() {
        // Initialize settings that need to be translated or registered with WordPress.
        $this->default_settings = array(
            'enabled'           => $this->maybe_enable_by_default(),
            'tabName'           => __( 'Q&A', 'storeagent-ai-for-woocommerce' ),
            'moderateQnA'       => 'no',
            'showDisclaimer'    => 'no',
            'disclaimerText'    => __( 'This AI-generated content may contain errors or fabrications. We recommend verifying important details independently before purchase.', 'storeagent-ai-for-woocommerce' ),
            'enableWidget'      => 'no',
            'widgetPosition'    => 'bottom-right',
            'language'          => 'default',
            'productInfo'       => array(
                'productId'   => 'no',
                'description' => 'yes',
                'productName' => 'yes',
                'price'       => 'no',
                'sku'         => 'no',
                'attributes'  => 'no',
                'metadata'    => array(),
            ),
            'enableDataSources' => 'no',
            'dataSources'       => array(),
            'questionsAnswers'  => 'no',
        );
    }

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