<?php
/**
 * Coupon Generator AI REST API.
 *
 * Provides REST API endpoints for the Coupon Generator AI agent including:
 * - Agent settings management
 * - AI-powered coupon generation
 * - Template storage and retrieval
 *
 * @since   1.1.4
 * @package SAAI
 */

namespace SAAI\REST;

use SAAI\Abstracts\Abstract_AI_Agent_REST;
use SAAI\Helpers\Connect;
use SAAI\Traits\AI_Tool_Token_Trait;
use SAAI\Traits\Singleton_Trait;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use SAAI\AI_Agents\Advanced_Coupons\Coupon_Generator_AI as Coupon_Generator_AI_Agent;

defined( 'ABSPATH' ) || exit;

/**
 * Coupon Generator AI REST API class.
 *
 * Handles REST API endpoints for the Coupon Generator AI agent including
 * settings management and AI-powered coupon generation.
 *
 * @since 1.1.4
 */
class Coupon_Generator_AI extends Abstract_AI_Agent_REST {

    use Singleton_Trait;
    use AI_Tool_Token_Trait;

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

    /**
     * Transient prefix for AI-generated templates.
     *
     * @var string
     */
    const TRANSIENT_PREFIX = 'acfw_ai_coupon_template_';

    /**
     * Transient expiration time (1 hour).
     *
     * @var int
     */
    const TRANSIENT_EXPIRATION = 3600;

    /**
     * Minimum prompt length for coupon generation.
     *
     * @var int
     */
    const MIN_PROMPT_LENGTH = 10;

    /**
     * Maximum prompt length for coupon generation.
     *
     * @var int
     */
    const MAX_PROMPT_LENGTH = 2000;

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

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

        // GET /storeagent-ai/v1/coupon-generator-ai/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' ),
            )
        );

        // POST /storeagent-ai/v1/coupon-generator-ai/generate.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/generate",
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'generate_coupon' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
                'args'                => array(
                    'prompt' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'description'       => __( 'Natural language prompt describing the desired coupon.', 'storeagent-ai-for-woocommerce' ),
                        'sanitize_callback' => 'sanitize_textarea_field',
                    ),
                    'amount' => array(
                        'required'          => false,
                        'type'              => 'integer',
                        'default'           => 1,
                        'minimum'           => 1,
                        'maximum'           => 5,
                        'description'       => __( 'Number of coupon variations to generate (1-5).', 'storeagent-ai-for-woocommerce' ),
                        'sanitize_callback' => 'absint',
                    ),
                ),
            )
        );

        // GET /storeagent-ai/v1/coupon-generator-ai/template.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/template",
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_template' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );

        // DELETE /storeagent-ai/v1/coupon-generator-ai/template.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/template",
            array(
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => array( $this, 'clear_template' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );

        // GET /storeagent-ai/v1/coupon-generator-ai/template/exists.
        register_rest_route(
            $this->namespace,
            "/$this->rest_base/template/exists",
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'template_exists' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
            )
        );
    }

    /**
     * Get the Coupon Generator AI settings.
     *
     * @param WP_REST_Request $request Request object.
     *
     * @since 1.1.4
     * @return WP_REST_Response Response object.
     */
    public function get_settings( $request ) {
        // Get the agent instance to access default settings.
        $agent = Coupon_Generator_AI_Agent::instance();

        $ai_agent_key = $this->get_option_key();
        $settings     = get_option( $ai_agent_key, array() );

        // Merge with default settings from the agent.
        $settings = wp_parse_args( $settings, $agent->default_settings );

        return rest_ensure_response( $settings );
    }

    /**
     * Generate coupon template(s) via AI.
     *
     * Uses the standard pipes/agent pattern to send the prompt to the AI service
     * via the storeagent-worker API_Agents endpoint.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error The response object or WP_Error on failure.
     */
    public function generate_coupon( $request ) {
        // Check if StoreAgent is connected.
        if ( ! Connect::is_connected() ) {
            return new WP_Error(
                'storeagent_not_connected',
                __( 'StoreAgent is not connected. Please connect your store first.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $prompt = $request->get_param( 'prompt' );
        $amount = $request->get_param( 'amount' ) ?? 1;

        // Validate prompt length.
        if ( strlen( $prompt ) < self::MIN_PROMPT_LENGTH ) {
            return new WP_Error(
                'invalid_prompt',
                __( 'Please provide a more detailed description of the coupon you want to create.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        // Reject oversized prompts before sending to the server.
        if ( strlen( $prompt ) > self::MAX_PROMPT_LENGTH ) {
            return new WP_Error(
                'prompt_too_long',
                __( 'Your coupon description is too long. Please keep it under 2000 characters.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        // Passthrough data: token-related data for n8n to access store data.
        $passthrough = array(
            'restUrl'     => get_rest_url(),
            'aiToolToken' => $this->generate_ai_tool_token(),
            'siteDomain'  => wp_parse_url( get_home_url(), PHP_URL_HOST ),
        );

        $data = array(
            'prompt'      => $prompt,
            'amount'      => $amount,
            'passthrough' => $passthrough,
        );

        // Use the standard AI agent send_prompt() flow.
        $agent = Coupon_Generator_AI_Agent::instance();
        $agent->set_data( $data );
        $response = $agent->send_prompt();

        // Handle errors.
        if ( is_wp_error( $response ) ) {
            return new WP_Error(
                'generation_failed',
                __( 'Failed to generate coupon. Please try again.', 'storeagent-ai-for-woocommerce' ),
                array(
                    'status' => 500,
                    'error'  => $response->get_error_message(),
                )
            );
        }

        // Check for validation errors returned by n8n.
        if ( ! empty( $response['errors'] ) ) {
            return new WP_Error(
                'generation_failed',
                __( 'Failed to generate a valid coupon template. Please try again with a different description.', 'storeagent-ai-for-woocommerce' ),
                array(
                    'status' => 422,
                    'errors' => $response['errors'],
                )
            );
        }

        // Validate that the completion is a non-empty array.
        $completion = $response['completion'] ?? null;
        if ( ! is_array( $completion ) || empty( $completion ) ) {
            return new WP_Error(
                'generation_failed',
                __( 'Failed to generate coupon template. Please try again.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 500 )
            );
        }

        // Save to transient if completion data is available.
        if ( $completion ) {
            $user_id       = get_current_user_id();
            $transient_key = self::TRANSIENT_PREFIX . $user_id;

            // Mark template as AI-generated for enrichment processing.
            $template_data                    = $completion;
            $template_data['generated_by_ai'] = true;
            $template_data['prompt']          = $prompt;

            set_transient( $transient_key, $template_data, self::TRANSIENT_EXPIRATION );
        }

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

    /**
     * Get AI-generated template from transient.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error The response object or WP_Error on failure.
     */
    public function get_template( $request ) {
        $user_id       = get_current_user_id();
        $transient_key = self::TRANSIENT_PREFIX . $user_id;
        $raw_template  = get_transient( $transient_key );

        if ( false === $raw_template ) {
            return new WP_Error(
                'no_template',
                __( 'No AI-generated template found or template has expired.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 404 )
            );
        }

        // Parse AI response if needed (completion might be a JSON string).
        if ( isset( $raw_template['completion'] ) && is_string( $raw_template['completion'] ) ) {
            $raw_template = json_decode( $raw_template['completion'], true );
            if ( json_last_error() !== JSON_ERROR_NONE ) {
                return new WP_Error(
                    'invalid_template',
                    __( 'Failed to parse AI-generated template.', 'storeagent-ai-for-woocommerce' ),
                    array( 'status' => 500 )
                );
            }
        }

        // Ensure template is marked as AI-generated for enrichment.
        if ( ! isset( $raw_template['generated_by_ai'] ) ) {
            $raw_template['generated_by_ai'] = true;
        }

        // Use shared processor (DRY) - same as regular templates.
        if ( ! class_exists( '\ACFWF\Models\REST_API\Template_Processor' ) ) {
            return new WP_Error(
                'dependency_unavailable',
                __( 'Advanced Coupons plugin is required to process templates.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 503 )
            );
        }

        $processor = new \ACFWF\Models\REST_API\Template_Processor(
            \ACFWF()->Plugin_Constants,
            \ACFWF()->Helper_Functions
        );
        $processed = $processor->process_template( $raw_template );

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

    /**
     * Clear AI-generated template transient.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response The response object.
     */
    public function clear_template( $request ) {
        $user_id       = get_current_user_id();
        $transient_key = self::TRANSIENT_PREFIX . $user_id;
        delete_transient( $transient_key );

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

    /**
     * Check if AI-generated template transient exists.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response The response object.
     */
    public function template_exists( $request ) {
        $user_id       = get_current_user_id();
        $transient_key = self::TRANSIENT_PREFIX . $user_id;
        $exists        = false !== get_transient( $transient_key );

        return rest_ensure_response(
            array( 'exists' => $exists )
        );
    }

    /**
     * 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'] = sanitize_text_field( $params['enabled'] );
        }

        return $sanitized;
    }
}
