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

namespace SAAI\Abstracts;

use SAAI\Helpers\Connect;
use SAAI\Helpers\Helper;
use SAAI\Traits\Magic_Get_Trait;
use WP_Error;

/**
 * Abstract_AI_Agent class.
 *
 * @since 1.0.0
 */
abstract class Abstract_AI_Agent {

    use Magic_Get_Trait;

    /**
     * The AI ID.
     *
     * @var string
     */
    protected $ai_id;

    /**
     * The AI endpoint.
     *
     * @var string
     */
    protected $endpoint;

    /**
     * The AI prompt data.
     *
     * @var string
     */
    protected $data;

    /**
     * Whether to use the beta credentials.
     *
     * @var bool
     */
    protected $use_beta = false;

    /**
     * The default settings.
     *
     * @var array
     */
    protected $default_settings = array( 'enabled' => 'no' );

    /**
     * Get the AI base URL.
     *
     * @since 1.0.0
     * @return string The AI base URL.
     */
    protected function get_ai_agents_url() {

        return Helper::get_storeagent_base_url( 'api' ) . '/storeagent/v2/agents/';
    }

    /**
     * Set the prompt data.
     *
     * @param mixed $data The data prompt to be sent.
     *
     * @return void
     */
    public function set_data( $data ) {

        $this->data = $data;
    }

    /**
     * Set the use beta flag.
     *
     * @param bool $use_beta Whether to use the beta credentials.
     *
     * @return void
     */
    public function set_use_beta( $use_beta ) {
        $this->use_beta = $use_beta;
    }
    /**
     * Send the prompt to the AI endpoint.
     *
     * @return array|mixed|WP_Error
     */
    public function send_prompt() {

        if ( empty( $this->data ) ) {
            return new WP_Error( 'no_data', __( 'No data to send to AI.', 'storeagent-ai-for-woocommerce' ) );
        }

        $headers = array(
            'Content-Type'  => 'application/json',
            'X-Origin'      => wp_parse_url( get_home_url(), PHP_URL_HOST ),
            'Authorization' => 'Basic ' . base64_encode( Connect::get_consumer_key() . ':' . Connect::get_consumer_secret() ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
        );

        if ( $this->use_beta ) {
            $headers['X-Beta'] = 'true';
        }

        $response = wp_remote_post(
            $this->get_ai_endpoint(),
            array(
                'body'    => wp_json_encode( $this->data ),
                'headers' => $headers,
                'timeout' => 30,
            )
        );

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

        $response = json_decode( wp_remote_retrieve_body( $response ), true );

        if ( ! empty( $response['data']['status'] ) && intval( $response['data']['status'] ) > 299 &&
            ! empty( $response['code'] ) && ! empty( $response['message'] ) ) {
            return new WP_Error( $response['code'], $response['message'], $response['data'] );
        }

        return $response;
    }

    /**
     * Get the AI ID.
     *
     * @since 1.0.0
     * @return string The AI ID.
     */
    public function get_ai_id() {
        return $this->ai_id;
    }

    /**
     * Get the AI endpoint.
     *
     * @since 1.0.0
     * @return string The AI endpoint.
     */
    protected function get_ai_endpoint() {

        return $this->get_ai_agents_url() . $this->endpoint;
    }

    /**
     * Get the AI settings.
     *
     * @param string|null $key The settings property key.
     *
     * @since 1.0.0
     * @return array|mixed|string
     */
    public function get_settings( $key = null ) {

        $default_settings = wp_parse_args(
            $this->default_settings,
            array(
                'enabled' => 'no',
            )
        );

        return Helper::get_ai_agent_settings( $this->ai_id, $key, $default_settings );
    }

    /**
     * Check if the AI agent is enabled.
     *
     * @since 1.0.0
     * @return bool
     */
    public function is_enabled() {

        return Connect::is_connected() && static::get_settings( 'enabled' ) === 'yes';
    }

    /**
     * Enable the AI agent.
     *
     * @since 1.0.0
     * @return bool True if the agent was enabled successfully, false otherwise.
     */
    public function enable() {
        if ( ! Connect::is_connected() ) {
            return false;
        }

        $option_key          = '_' . str_replace( '-', '_', $this->ai_id );
        $settings            = get_option( $option_key, array() );
        $settings            = wp_parse_args( $settings, $this->default_settings );
        $settings['enabled'] = 'yes';

        return update_option( $option_key, $settings, false );
    }

    /**
     * Maybe enable the AI agent by default.
     *
     * Override this method in the child class to enable the AI agent by default depending on some conditions.
     *
     * @since 1.0.4
     * @return string
     */
    public function maybe_enable_by_default() {

        return 'no';
    }

    /**
     * Run hooks related to the AI agent.
     *
     * @return void
     */
    abstract public function run();

    /**
     * Create a notification for the agent with the appropriate callbacks
     *
     * @param string   $type Notification type (info, warning, success, decision).
     * @param string   $title The notification title.
     * @param string   $message The notification message.
     * @param int|null $product_id Product ID related to the notification (if any).
     * @param array    $extra Extra data to include in the notification.
     * @param array    $actions Action buttons configuration.
     * @return int|WP_Error The notification ID or error
     */
    protected function create_notification( $type, $title, $message, $product_id = null, $extra = array(), $actions = array() ) {
        if ( ! class_exists( 'SAAI\Classes\Notification' ) ) {
            return new WP_Error( 'notification_class_missing', __( 'Notification class not found', 'storeagent-ai-for-woocommerce' ) );
        }

        // Get agent class name for attribution.
        $class_name = wp_basename( get_class( $this ) );

        return \SAAI\Classes\Notification::instance()->create(
            $type,
            $title,
            $message,
            $class_name,
            $product_id,
            $extra,
            $actions
        );
    }

    /**
     * Create a simple info notification for the agent
     *
     * @param string   $title The notification title.
     * @param string   $message The notification message.
     * @param int|null $product_id Product ID related to the notification (if any).
     * @param array    $extra Extra data to include in the notification.
     * @return int|WP_Error The notification ID or error
     */
    protected function create_info_notification( $title, $message, $product_id = null, $extra = array() ) {
        if ( ! class_exists( 'SAAI\Classes\Notification' ) ) {
            return new WP_Error( 'notification_class_missing', __( 'Notification class not found', 'storeagent-ai-for-woocommerce' ) );
        }

        // Get agent class name for attribution.
        $class_name = wp_basename( get_class( $this ) );

        return \SAAI\Classes\Notification::instance()->create_info_notification(
            $title,
            $message,
            $class_name,
            $product_id,
            $extra
        );
    }

    /**
     * Create a decision notification with Accept/Reject buttons
     *
     * @param string   $title The notification title.
     * @param string   $message The notification message.
     * @param int|null $product_id Product ID related to the notification (if any).
     * @param array    $extra Extra data to include in the notification.
     * @param string   $accept_method Method name to call on accept action.
     * @param array    $accept_args Arguments to pass to the accept method.
     * @param string   $reject_method Method name to call on reject action.
     * @param array    $reject_args Arguments to pass to the reject method.
     * @return int|WP_Error The notification ID or error.
     */
    protected function create_decision_notification( $title, $message, $product_id = null, $extra = array(), $accept_method = '', $accept_args = array(), $reject_method = '', $reject_args = array() ) {
        if ( ! class_exists( 'SAAI\Classes\Notification' ) ) {
            return new WP_Error( 'notification_class_missing', __( 'Notification class not found', 'storeagent-ai-for-woocommerce' ) );
        }

        // Get agent class name for attribution.
        $class_name = wp_basename( get_class( $this ) );
        $full_class = get_class( $this );

        // Build actions.
        $actions = array();

        // Only add accept action if method is provided.
        if ( ! empty( $accept_method ) && method_exists( $this, $accept_method ) ) {
            $actions[] = array(
                'label'    => __( 'Accept', 'storeagent-ai-for-woocommerce' ),
                'action'   => 'accept',
                'endpoint' => '/storeagent-ai/v1/notifications/{id}/accept',
                'callback' => array(
                    'class'  => $full_class,
                    'method' => $accept_method,
                    'args'   => $accept_args,
                ),
            );
        }

        // Only add reject action if method is provided.
        if ( ! empty( $reject_method ) && method_exists( $this, $reject_method ) ) {
            $actions[] = array(
                'label'    => __( 'Reject', 'storeagent-ai-for-woocommerce' ),
                'action'   => 'reject',
                'endpoint' => '/storeagent-ai/v1/notifications/{id}/reject',
                'callback' => array(
                    'class'  => $full_class,
                    'method' => $reject_method,
                    'args'   => $reject_args,
                ),
            );
        }

        // Always add archive action.
        $actions[] = array(
            'label'    => __( 'Archive', 'storeagent-ai-for-woocommerce' ),
            'action'   => 'archive',
            'endpoint' => '/storeagent-ai/v1/notifications/{id}/archive',
        );

        // Add product link if product ID is provided.
        if ( $product_id ) {
            $actions[] = array(
                'label'    => __( 'Open Product', 'storeagent-ai-for-woocommerce' ),
                'action'   => 'open_product',
                'endpoint' => '/storeagent-ai/v1/notifications/{id}/open_product',
            );
        }

        return \SAAI\Classes\Notification::instance()->create(
            'decision',
            $title,
            $message,
            $class_name,
            $product_id,
            $extra,
            $actions
        );
    }
}
