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

namespace SAAI\Classes;

use SAAI\AI_Agents\Review_Summaries_AI;
use SAAI\Traits\AI_Tool_Token_Trait;
use WP_Comment;
use WP_Error;

/**
 * Review_Summaries class.
 *
 * @since 1.0.0
 */
class Review_Summary {

    use AI_Tool_Token_Trait;

    public const LAST_UPDATED_META_KEY = '_saai_review_summary_last_updated';

    public const THREAD_ID_META_KEY = '_saai_review_summary_thread_id';

    public const SUMMARY_META_KEY = '_saai_review_summary';

    /**
     * Product ID.
     *
     * @var int
     */
    private $product_id;

    /**
     * Constructor.
     *
     * @param int $product_id Product ID.
     */
    public function __construct( $product_id ) {

        $this->product_id = $product_id;
    }

    /**
     * Query review objects.
     *
     * @param array $args Query arguments. See WP_Comment_Query::__construct() for information on accepted arguments.
     *
     * @return WP_Comment[]
     */
    public function query_review_objects( $args = array() ) {

        $defaults = array(
            'post_id' => $this->product_id,
            'status'  => 'approve',
            'type'    => 'review',
            'orderby' => 'comment_date_gmt',
            'order'   => 'DESC',
            'number'  => 50,
            'paged'   => 1,
        );

        $args = wp_parse_args( $args, $defaults );
        $args = apply_filters( 'saai_review_summary_query_args', $args, $this->product_id );

        return get_comments( $args );
    }

    /**
     * Get the total reviews count.
     *
     * @return int
     */
    public function get_total_reviews_count() {
        $args = array(
            'post_id' => $this->product_id,
            'status'  => 'approve',
            'type'    => 'review',
            'count'   => true,
        );

        return get_comments( $args );
    }

    /**
     * Get the saved review summary.
     *
     * @return array
     */
    public function get_saved_review_summary() {
        $product        = wc_get_product( $this->product_id );
        $review_summary = (array) $product->get_meta( self::SUMMARY_META_KEY );
        $review_summary = wp_parse_args(
            $review_summary,
            array(
                'summary'       => '',
                'key_takeaways' => array(),
            )
        );

        $review_summary['key_takeaways'] = $this->parse_key_takeaways( $review_summary['key_takeaways'] );

        return $review_summary;
    }

    /**
     * Parse the key takeaways.
     *
     * @param array $key_takeaways Key takeaways.
     *
     * @return array
     */
    private function parse_key_takeaways( $key_takeaways ) {
        $parsed_key_takeaways = array();
        foreach ( $key_takeaways as $key_takeaway ) {
            if ( is_array( $key_takeaway ) ) {
                $parsed_key_takeaways[] = $key_takeaway;
            } else {
                $parsed_key_takeaways[] = array(
                    'content'   => $key_takeaway,
                    'sentiment' => 'positive',
                );
            }
        }
        return $parsed_key_takeaways;
    }

    /**
     * Generate review summary for a product.
     *
     * @param bool $should_save Whether to save the review summary to the product meta.
     * @return array|WP_Error
     */
    public function generate_product_review_summary( $should_save = true ) {

        $product = wc_get_product( $this->product_id );
        if ( ! $product ) {
            return new WP_Error( 'not_found', __( 'Product not found.', 'storeagent-ai-for-woocommerce' ) );
        }

        $passthrough  = array(
            'version'     => 'v2', // Version of agent required by the server to be used (for backward compatibility).
            'productId'   => $this->product_id,
            'aiToolToken' => $this->generate_ai_tool_token(),
            'restUrl'     => get_rest_url(),
        );
        $product_name = $product->get_name();
        $product_url  = $product->get_permalink();

        // Reviews are fetched via HAL through the product-reviews endpoint.
        // An empty array is passed here for backwards compatibility with the worker Pipe.
        $reviews = array();

        $data = apply_filters(
            'saai_product_summary_data',
            compact(
                'product_name',
                'product_url',
                'reviews',
                'passthrough'
            ),
            $this->product_id
        );

        // Instantiate the AI agent.
        $ai_agent = new Review_Summaries_AI( $data );

        // Set language from settings.
        $ai_agent->set_language_from_settings();

        // Send the prompt to the AI agent.
        $response = $ai_agent->send_prompt();
        if ( is_wp_error( $response ) ) {
            return $response;
        }

        // Check if the response is empty.
        if ( empty( $response['completion'] ) ) {
            return new WP_Error( 'no_completion', __( 'No completion found.', 'storeagent-ai-for-woocommerce' ) );
        }

        /***************************************************************************
         * Available Properties:
         ***************************************************************************
            *
            * Please check Langbase pipeline for the available properties.
            * 'summary' - string
            * 'key_takeaways' - string[]
            * 'total_reviews' - number
            * 'average_rating' - number
            */
        $review_summary                  = $response['completion'];
        $review_summary['key_takeaways'] = self::sanitize_key_takeaways( $review_summary['key_takeaways'] );

        // Save the review summary to the product meta.
        if ( $should_save ) {
            $product->update_meta_data( self::SUMMARY_META_KEY, $review_summary );
            $product->save_meta_data();
        }

        return $review_summary;
    }

    /**
     * Sanitize the key takeaways.
     *
     * @param array $raw_key_takeaways Raw key takeaways.
     *
     * @return array
     */
    public static function sanitize_key_takeaways( $raw_key_takeaways ) {
        $sanitized_key_takeaways = array();
        $allowed_sentiments      = array( 'positive', 'neutral', 'negative' );
        foreach ( $raw_key_takeaways as $key_takeaway ) {
            // Check if the key_takeaway is an array and has the required keys.
            if ( ! is_array( $key_takeaway ) ) {
                continue;
            }

            $sentiment = isset( $key_takeaway['sentiment'] ) ? $key_takeaway['sentiment'] : 'positive';
            $content   = isset( $key_takeaway['content'] ) ? $key_takeaway['content'] : '';

            $sanitized_key_takeaways[] = array(
                'sentiment' => in_array( $sentiment, $allowed_sentiments, true ) ? $sentiment : 'positive',
                'content'   => sanitize_text_field( $content ),
            );
        }

        return $sanitized_key_takeaways;
    }
}
