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

namespace SAAI\REST;

use SAAI\Abstracts\Abstract_AI_Agent_REST;
use SAAI\AI_Agents\Review_Moderation_AI as ReviewModerationAIAgent;
use SAAI\Traits\Singleton_Trait;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Review_Moderation_AI REST class.
 *
 * @since 1.1.4
 */
class Review_Moderation_AI extends Abstract_AI_Agent_REST {

    use Singleton_Trait;

    /**
     * Holds the class instance object.
     *
     * @since 1.1.4
     * @var Review_Moderation_AI $instance object.
     */
    protected static $instance;

    /**
     * Works as constructor for this class.
     *
     * @since 1.1.4
     * @return void
     */
    public function register_plugin_routes() {
        $this->rest_base = 'review-moderation-ai';
        parent::register_plugin_routes();
    }

    /**
     * Register the routes.
     *
     * @since 1.1.4
     * @return void
     */
    public function register_routes() {
        parent::register_routes();

        // Endpoint to get current settings.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/settings",
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_settings' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );

        // Endpoint to get the moderation queue (flagged reviews).
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/queue",
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_queue' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
                'args'                => array(
                    'page'     => array(
                        'type'              => 'integer',
                        'default'           => 1,
                        'sanitize_callback' => 'absint',
                    ),
                    'per_page' => array(
                        'type'              => 'integer',
                        'default'           => 10,
                        'sanitize_callback' => 'absint',
                    ),
                ),
            )
        );

        // Endpoint to get moderation statistics.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/stats",
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_stats' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );

        // Endpoint to manually trigger moderation on a specific review.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/moderate",
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'moderate_review' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
                'args'                => array(
                    'comment_id' => array(
                        'required'          => true,
                        'type'              => 'integer',
                        'sanitize_callback' => 'absint',
                        'validate_callback' => 'rest_validate_request_arg',
                    ),
                ),
            )
        );
    }

    /**
     * Get the Review Moderation AI settings.
     *
     * @param WP_REST_Request $request Request object.
     *
     * @since 1.1.4
     * @return WP_REST_Response Response object.
     */
    public function get_settings( $request ) {
        $agent    = ReviewModerationAIAgent::instance();
        $defaults = $agent->default_settings;

        $ai_agent_key = 'saai_' . str_replace( '-', '_', $this->rest_base );
        $settings     = get_option( $ai_agent_key, array() );
        $settings     = wp_parse_args( $settings, $defaults );

        return rest_ensure_response( $settings );
    }

    /**
     * Sanitize settings data before saving.
     *
     * @since 1.1.4
     * @param array $params The parameters to sanitize.
     * @return array The sanitized parameters.
     */
    protected function sanitize_settings_data( $params ) {
        $sanitized = array();

        // Sanitize enabled setting.
        if ( isset( $params['enabled'] ) ) {
            $sanitized['enabled'] = in_array( $params['enabled'], array( 'yes', 'no' ), true ) ? $params['enabled'] : 'no';
        }

        // Sanitize auto_approve_enabled setting.
        if ( isset( $params['auto_approve_enabled'] ) ) {
            $sanitized['auto_approve_enabled'] = in_array( $params['auto_approve_enabled'], array( 'yes', 'no' ), true ) ? $params['auto_approve_enabled'] : 'no';
        }

        // Sanitize auto_approve_threshold (0-100).
        if ( isset( $params['auto_approve_threshold'] ) ) {
            $sanitized['auto_approve_threshold'] = max( 0, min( 100, (int) $params['auto_approve_threshold'] ) );
        }

        // Sanitize auto_reject_enabled.
        if ( isset( $params['auto_reject_enabled'] ) ) {
            $sanitized['auto_reject_enabled'] = in_array( $params['auto_reject_enabled'], array( 'yes', 'no' ), true ) ? $params['auto_reject_enabled'] : 'no';
        }

        // Sanitize auto_reject_threshold (0-100).
        if ( isset( $params['auto_reject_threshold'] ) ) {
            $sanitized['auto_reject_threshold'] = max( 0, min( 100, (int) $params['auto_reject_threshold'] ) );
        }

        // Sanitize email_notifications.
        if ( isset( $params['email_notifications'] ) ) {
            $sanitized['email_notifications'] = in_array( $params['email_notifications'], array( 'yes', 'no' ), true ) ? $params['email_notifications'] : 'yes';
        }

        // Sanitize textarea fields.
        if ( isset( $params['custom_blacklist'] ) ) {
            $sanitized['custom_blacklist'] = sanitize_textarea_field( $params['custom_blacklist'] );
        }

        if ( isset( $params['custom_whitelist'] ) ) {
            $sanitized['custom_whitelist'] = sanitize_textarea_field( $params['custom_whitelist'] );
        }

        // Sanitize language.
        if ( isset( $params['language'] ) ) {
            $sanitized['language'] = sanitize_text_field( $params['language'] );
        }

        return apply_filters( 'saai_sanitize_review_moderation_settings', $sanitized, $params );
    }

    /**
     * Get the moderation queue (flagged reviews).
     *
     * @param WP_REST_Request $request The request object.
     *
     * @since 1.1.4
     * @return WP_REST_Response Response object.
     */
    public function get_queue( $request ) {
        $page     = $request->get_param( 'page' );
        $per_page = $request->get_param( 'per_page' );
        $offset   = ( $page - 1 ) * $per_page;

        $args = array(
            'type'       => 'review',
            'status'     => 'hold',
            'number'     => $per_page,
            'offset'     => $offset,
            'orderby'    => 'comment_date',
            'order'      => 'DESC',
            'post_type'  => 'product',
            'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
                array(
                    'key'   => ReviewModerationAIAgent::MODERATION_STATUS_META_KEY,
                    'value' => 'flagged',
                ),
            ),
        );

        $comments    = get_comments( $args );
        $total_query = new \WP_Comment_Query(
            array_merge(
                $args,
                array(
                    'count'  => true,
                    'number' => 0,
                    'offset' => 0,
                )
            )
        );

        $total = $total_query->get_comments();
        $queue = array();

        foreach ( $comments as $comment ) {
            $result = get_comment_meta( $comment->comment_ID, ReviewModerationAIAgent::MODERATION_RESULT_META_KEY, true );
            $date   = get_comment_meta( $comment->comment_ID, ReviewModerationAIAgent::MODERATION_DATE_META_KEY, true );

            $queue[] = array(
                'comment_id'        => $comment->comment_ID,
                'review_content'    => $comment->comment_content,
                'reviewer_name'     => $comment->comment_author,
                'reviewer_email'    => $comment->comment_author_email,
                'rating'            => (int) get_comment_meta( $comment->comment_ID, 'rating', true ),
                'product_id'        => $comment->comment_post_ID,
                'product_name'      => get_the_title( $comment->comment_post_ID ),
                'date'              => $comment->comment_date,
                'moderation_result' => $result,
                'moderation_date'   => $date,
            );
        }

        return rest_ensure_response(
            array(
                'items' => $queue,
                'total' => (int) $total,
                'page'  => $page,
                'pages' => ceil( (int) $total / $per_page ),
            )
        );
    }

    /**
     * Get moderation statistics.
     *
     * @param WP_REST_Request $request The request object.
     *
     * @since 1.1.4
     * @return WP_REST_Response Response object.
     */
    public function get_stats( $request ) {
        global $wpdb;

        $stats = array(
            'total_moderated' => 0,
            'auto_approved'   => 0,
            'flagged'         => 0,
            'rejected'        => 0,
            'pending'         => 0,
        );

        $statuses = array( 'approved', 'flagged', 'rejected', 'pending' );

        foreach ( $statuses as $status ) {
            $count = $wpdb->get_var(
                $wpdb->prepare(
                    "SELECT COUNT(*) FROM {$wpdb->commentmeta} WHERE meta_key = %s AND meta_value = %s",
                    ReviewModerationAIAgent::MODERATION_STATUS_META_KEY,
                    $status
                )
            );

            $stats[ $status ] = (int) $count;
        }

        // Total includes all statuses except pending.
        $stats['total_moderated'] = $stats['approved'] + $stats['flagged'] + $stats['rejected'];
        $stats['auto_approved']   = $stats['approved'];

        return rest_ensure_response( $stats );
    }

    /**
     * Manually trigger moderation on a specific review.
     *
     * @param WP_REST_Request $request The request object.
     *
     * @since 1.1.4
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function moderate_review( $request ) {
        $comment_id = $request->get_param( 'comment_id' );
        $comment    = get_comment( $comment_id );

        if ( ! $comment ) {
            return new WP_Error(
                'comment_not_found',
                __( 'Comment not found.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 404 )
            );
        }

        // Verify this is a product review.
        if ( ! ReviewModerationAIAgent::is_product_review_comment( $comment ) ) {
            return new WP_Error(
                'not_a_product_review',
                __( 'The specified comment is not a product review.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $agent  = ReviewModerationAIAgent::instance();
        $result = $agent->run_agent_query(
            array(
                'comment_id' => $comment_id,
            )
        );

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

        return rest_ensure_response(
            array(
                'success' => true,
                'result'  => $result,
            )
        );
    }
}
