<?php
/**
 * Coupon Description AI Agent.
 *
 * @since   1.1.4
 * @package SAAI\AI_Agents
 */

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\Coupon_Description_AI as Coupon_Description_AI_REST;

defined( 'ABSPATH' ) || exit;

/**
 * Coupon_Description_AI class.
 *
 * AI-powered coupon description generation from coupon data and metadata.
 *
 * @since 1.1.4
 */
class Coupon_Description_AI extends Abstract_AI_Agent {

    use Singleton_Trait;

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

    /**
     * Constructor.
     *
     * @since 1.1.4
     *
     * @param mixed $data The prompt data.
     */
    public function __construct( $data = null ) {
        $this->endpoint         = 'coupon-description';
        $this->ai_id            = "$this->endpoint-ai";
        $this->data             = $data;
        $this->default_settings = array(
            'enabled'  => 'no',
            'language' => 'default',
        );
    }

    /**
     * Run the agent query for a coupon.
     *
     * @since 1.1.4
     *
     * @param int $coupon_id The coupon post ID.
     * @return array|\WP_Error The AI response or error.
     */
    public function run_agent_query( $coupon_id ) {
        $coupon = new \WC_Coupon( $coupon_id );

        if ( ! $coupon->get_id() ) {
            return new \WP_Error(
                'saai_invalid_coupon',
                __( 'Invalid coupon ID.', 'storeagent-ai-for-woocommerce' )
            );
        }

        $data = $this->build_coupon_data( $coupon );

        // Add language setting.
        $language         = $this->get_settings( 'language' ) ?? 'default';
        $data['language'] = Helper::resolve_default_language( $language );

        $this->set_data( array( 'coupon_data' => wp_json_encode( $data ) ) );

        $ai_response = $this->send_prompt();

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

        return $ai_response['completion'] ?? $ai_response;
    }

    /**
     * Build coupon data array from WC_Coupon object.
     *
     * @since 1.1.4
     *
     * @param \WC_Coupon $coupon The coupon object.
     * @return array The coupon data.
     */
    protected function build_coupon_data( $coupon ) {
        $data = array(
            'code'                        => $coupon->get_code(),
            'discount_type'               => $coupon->get_discount_type(),
            'amount'                      => $coupon->get_amount(),
            'free_shipping'               => $coupon->get_free_shipping(),
            'expiry_date'                 => $coupon->get_date_expires() ? $coupon->get_date_expires()->date( get_option( 'date_format', 'F j, Y' ) ) : '',
            'minimum_amount'              => $coupon->get_minimum_amount(),
            'maximum_amount'              => $coupon->get_maximum_amount(),
            'product_ids'                 => $this->get_product_names( $coupon->get_product_ids() ),
            'excluded_product_ids'        => $this->get_product_names( $coupon->get_excluded_product_ids() ),
            'product_categories'          => $this->get_category_names( $coupon->get_product_categories() ),
            'excluded_product_categories' => $this->get_category_names( $coupon->get_excluded_product_categories() ),
            'exclude_sale_items'          => $coupon->get_exclude_sale_items(),
            'limit_usage_to_x_items'      => $coupon->get_limit_usage_to_x_items(),
            'usage_limit'                 => $coupon->get_usage_limit(),
            'usage_limit_per_user'        => $coupon->get_usage_limit_per_user(),
            'individual_use'              => $coupon->get_individual_use(),
            'email_restrictions'          => $coupon->get_email_restrictions(),
        );

        /**
         * Filter the coupon description data before it is sent to the AI agent.
         *
         * Allows third-party plugins (e.g. Advanced Coupons) to enrich
         * the coupon data payload with additional fields.
         *
         * @since 1.1.4
         *
         * @param array      $data   The coupon data array.
         * @param \WC_Coupon $coupon The WooCommerce coupon object.
         */
        $data = apply_filters( 'saai_coupon_description_data', $data, $coupon );

        return $this->filter_empty_values( $data );
    }

    /**
     * Get product names from product IDs.
     *
     * @since 1.1.4
     *
     * @param array $product_ids Array of product IDs.
     * @return array Array of product names.
     */
    protected function get_product_names( $product_ids ) {
        if ( empty( $product_ids ) ) {
            return array();
        }

        $names = array();
        foreach ( $product_ids as $id ) {
            $product = wc_get_product( $id );
            if ( $product ) {
                $names[] = $product->get_name();
            }
        }

        return $names;
    }

    /**
     * Get category names from category IDs.
     *
     * @since 1.1.4
     *
     * @param array $category_ids Array of category IDs.
     * @return array Array of category names.
     */
    protected function get_category_names( $category_ids ) {
        if ( empty( $category_ids ) ) {
            return array();
        }

        $names = array();
        foreach ( $category_ids as $id ) {
            $term = get_term( $id, 'product_cat' );
            if ( $term && ! is_wp_error( $term ) ) {
                $names[] = $term->name;
            }
        }

        return $names;
    }

    /**
     * Filter out fields with empty or meaningless values.
     *
     * Removes fields with empty strings, '0', 0, false, null, or empty arrays.
     * Always preserves 'code' and 'discount_type'.
     *
     * @since 1.1.4
     *
     * @param array $data The coupon data array.
     * @return array The filtered data.
     */
    protected function filter_empty_values( $data ) {
        $always_include = array( 'code', 'discount_type' );

        return array_filter(
            $data,
            function ( $value, $key ) use ( $always_include ) {
                if ( in_array( $key, $always_include, true ) ) {
                    return true;
                }

                if ( is_array( $value ) ) {
                    return ! empty( $value );
                }

                // Filter out meaningless values.
                return ! in_array( $value, array( '', '0', 0, false, null ), true );
            },
            ARRAY_FILTER_USE_BOTH
        );
    }

    /**
     * Enqueue admin scripts on the coupon edit screen.
     *
     * @since 1.1.4
     *
     * @return void
     */
    public function enqueue_admin_scripts() {
        global $current_screen;

        if ( ! $current_screen || 'shop_coupon' !== $current_screen->id || 'post' !== $current_screen->base ) {
            return;
        }

        $coupon_description = new Vite_App(
            'saai-coupon-description',
            'src/vanilla/admin/coupon-description/index.ts',
            array( 'jquery', 'wp-i18n' ),
            array_merge(
                array(
                    'couponDescriptionRestUrl' => Coupon_Description_AI_REST::instance()->api_url,
                    'wpNonce'                  => wp_create_nonce( 'wp_rest' ),
                ),
                Plan_Manager::get_credit_usage_l10n()
            ),
            'saaiObj',
            array()
        );
        $coupon_description->enqueue();
    }

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

        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
    }
}
