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

namespace SAAI\REST;

use SAAI\Traits\Singleton_Trait;
use SAAI\Abstracts\Abstract_AI_Agent_REST;
use SAAI\AI_Agents\Product_Upsells_AI as ProductUpsellsAIAgent;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Product_Upsells_AI REST class.
 *
 * @since 1.2.0
 */
class Product_Upsells_AI extends Abstract_AI_Agent_REST {

    use Singleton_Trait;

    /**
     * Holds the class instance object.
     *
     * @since 1.2.0
     * @var Product_Upsells_AI $instance
     */
    protected static $instance;

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

        register_rest_route(
            $this->namespace,
            "/$this->rest_base/generate",
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'generate_recommendations' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );
    }

    /**
     * Generate upsell/cross-sell recommendations via the REST API.
     *
     * @param WP_REST_Request $request The request object.
     *
     * @since 1.3.0
     * @return WP_REST_Response|WP_Error
     */
    public function generate_recommendations( $request ) {
        $product_id = $request->get_param( 'product_id' );
        $product    = wc_get_product( $product_id );

        if ( ! $product instanceof \WC_Product ) {
            return new WP_Error(
                'invalid_product',
                __( 'Invalid product ID.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $agent  = ProductUpsellsAIAgent::instance();
        $result = $agent->run_agent_query( array( 'product_id' => $product_id ) );

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

        // Extract recommendations from the response.
        $completion     = $result['completion'] ?? array();
        $upsell_ids     = $completion['upsell_ids'] ?? array();
        $cross_sell_ids = $completion['cross_sell_ids'] ?? array();

        if ( empty( $upsell_ids ) && empty( $cross_sell_ids ) ) {
            return new WP_Error(
                'no_recommendations',
                __( 'No suitable recommendations were found for this product.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 404 )
            );
        }

        // Save the recommendations.
        $agent->save_object_data(
            $product,
            array(
                'upsell_ids'     => $upsell_ids,
                'cross_sell_ids' => $cross_sell_ids,
            )
        );

        // Build response with product names for select2.
        $upsell_products     = $this->get_product_id_name_pairs( $upsell_ids );
        $cross_sell_products = $this->get_product_id_name_pairs( $cross_sell_ids );

        return rest_ensure_response(
            array(
                'success'        => true,
                'upsell_ids'     => $upsell_products,
                'cross_sell_ids' => $cross_sell_products,
            )
        );
    }

    /**
     * Get product ID and name pairs from an array of product IDs.
     *
     * @param array $ids The product IDs.
     *
     * @since 1.3.0
     * @return array Array of objects with id and name.
     */
    private function get_product_id_name_pairs( $ids ) {
        $pairs = array();

        foreach ( $ids as $id ) {
            $product = wc_get_product( $id );

            if ( $product ) {
                $pairs[] = array(
                    'id'   => $product->get_id(),
                    'name' => $product->get_name(),
                );
            }
        }

        return $pairs;
    }

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

        if ( isset( $params['enabled'] ) ) {
            $sanitized['enabled'] = sanitize_text_field( $params['enabled'] );
        }

        if ( isset( $params['recommendation_type'] ) ) {
            $allowed = array( 'both', 'upsells', 'cross_sells' );
            $value   = sanitize_text_field( $params['recommendation_type'] );

            $sanitized['recommendation_type'] = in_array( $value, $allowed, true ) ? $value : 'both';
        }

        if ( isset( $params['max_recommendations'] ) ) {
            $sanitized['max_recommendations'] = absint( $params['max_recommendations'] );
        }

        if ( isset( $params['scan_check'] ) ) {
            $sanitized['scan_check'] = sanitize_text_field( $params['scan_check'] );
        }

        if ( isset( $params['scan_frequency'] ) ) {
            $sanitized['scan_frequency'] = absint( $params['scan_frequency'] );
        }

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

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