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

namespace SAAI\REST;

use SAAI\Abstracts\Abstract_AI_Agent_REST;
use SAAI\AI_Agents\Image_Alt_Tags_AI;
use SAAI\Helpers\Helper;
use SAAI\Traits\Singleton_Trait;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * Image_Alt_Tags_AI_REST REST class.
 *
 * @since 1.1.2
 */
class Image_Alt_Tags_AI_REST extends Abstract_AI_Agent_REST {

    use Singleton_Trait;

    /**
     * Holds the class instance object
     *
     * @since 1.1.2
     * @var Image_Alt_Tags_AI_REST $instance object
     */
    protected static $instance;

    /**
     * The namespace.
     *
     * @var string
     */
    protected $namespace = 'storeagent-ai/v1';

    /**
     * The base.
     *
     * @var string
     */
    protected $rest_base = 'image-alt-tags-ai';

    /**
     * Register the routes.
     *
     * @return void
     */
    public function register_routes() {
        // Register settings endpoint from parent class.
        parent::register_routes();

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            array(
                array(
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => array( $this, 'generate_image_alt_tags' ),
                    'permission_callback' => array( $this, 'check_permission' ),
                    'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
                ),
                'schema' => array( $this, 'get_public_item_schema' ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/form',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_image_alt_tags_form' ),
                    'permission_callback' => array( $this, 'check_permission' ),
                    'args'                => array(
                        'attachment_id' => array(
                            'required'          => true,
                            'type'              => 'integer',
                            'sanitize_callback' => 'absint',
                            'validate_callback' => 'rest_validate_request_arg',
                        ),
                    ),
                ),
            )
        );
    }

    /**
     * Check if the user has permission to use this endpoint.
     *
     * @param WP_REST_Request $request The request object.
     * @return bool|WP_Error
     */
    public function check_permission( $request ) {
        $attachment_id = $request->get_param( 'attachment_id' );

        // If no attachment ID, check for upload files capability.
        if ( ! $attachment_id ) {
            if ( ! current_user_can( 'upload_files' ) ) {
                return new WP_Error(
                    'rest_forbidden',
                    __( 'You do not have permission to access this resource.', 'storeagent-ai-for-woocommerce' ),
                    array( 'status' => 403 )
                );
            }
            return true;
        }

        // Check if user can edit this specific attachment.
        if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
            return new WP_Error(
                'rest_forbidden',
                __( 'You do not have permission to edit this attachment.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 403 )
            );
        }

        return true;
    }

    /**
     * Generate image alt tags.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error
     */
    public function generate_image_alt_tags( $request ) {
        $attachment_id = intval( $request->get_param( 'attachment_id' ) );

        if ( ! $attachment_id && ! $request->get_param( 'image_url' ) ) {
            return new WP_Error(
                'missing_image_data',
                __( 'Missing image data. Please provide either attachment_id or image_url.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        // Validate that at least one generation option is selected.
        if ( ! $request->get_param( 'generate_alt' ) && ! $request->get_param( 'generate_caption' ) && ! $request->get_param( 'generate_title' ) && ! $request->get_param( 'generate_description' ) ) {
            return new WP_Error(
                'no_generation_options',
                __( 'Please select at least one option to generate (alt text, caption, title, or description).', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $params            = $this->prepare_image_alt_tags_params( $request );
        $image_alt_tags_ai = Image_Alt_Tags_AI::instance();

        $ai_response = $image_alt_tags_ai->run_agent_query( $params );

        if ( is_wp_error( $ai_response ) ) {
            return new WP_Error(
                'ai_generation_failed',
                $ai_response->get_error_message(),
                array( 'status' => 500 )
            );
        }

        // Save the generated data back to the attachment.
        if ( $attachment_id ) {
            $save_data = $this->prepare_image_alt_tags_save_data( $ai_response['completion'], $request );
            $image_alt_tags_ai->save_object_data( $attachment_id, $save_data );
        }

        $response_data = $this->with_usage_data(
            array(
                'success'       => true,
                'attachment_id' => $attachment_id,
                'data'          => $ai_response['completion'],
            )
        );

        return rest_ensure_response( $response_data );
    }

    /**
     * Get the image alt tags fields.
     *
     * @return array The image alt tags fields.
     */
    private static function get_image_alt_tags_fields() {
        return array(
            'alt',
            'caption',
            'title',
            'description',
        );
    }

    /**
     * Prepare the image alt tags parameters.
     *
     * @param WP_REST_Request $request The request object.
     * @return array The prepared parameters.
     */
    private function prepare_image_alt_tags_params( $request ) {
        $params = array(
            'attachment_id' => $request->get_param( 'attachment_id' ),
            'image_url'     => $request->get_param( 'image_url' ),
        );

        // Add post context if provided.
        $post_context = $request->get_param( 'post_context' );
        if ( $post_context ) {
            // Validate JSON format.
            $decoded_context = json_decode( $post_context, true );
            if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded_context ) ) {
                $params['post_context'] = $decoded_context;
            }
        }

        foreach ( self::get_image_alt_tags_fields() as $field ) {
            if ( $request->get_param( "generate_{$field}" ) ) {
                $params[ "current_{$field}" ] = $request->get_param( "current_{$field}" );
            }
        }

        return $params;
    }

    /**
     * Prepare the image alt tags save data.
     *
     * @param array           $completion The completion data.
     * @param WP_REST_Request $request The request object.
     * @return array The prepared save data.
     */
    private function prepare_image_alt_tags_save_data( $completion, $request ) {
        $save_data = array();

        foreach ( self::get_image_alt_tags_fields() as $field ) {
            if ( $request->get_param( "generate_{$field}" ) && isset( $completion[ $field ] ) ) {
                // Map 'alt' to 'alt_text' for the save method.
                $save_field               = ( 'alt' === $field ) ? 'alt_text' : $field;
                $save_data[ $save_field ] = $completion[ $field ];
            }
        }

        return $save_data;
    }

    /**
     * Get the image alt tags form.
     *
     * @param WP_REST_Request $request The request object.
     * @return WP_REST_Response|WP_Error
     */
    public function get_image_alt_tags_form( $request ) {
        $attachment_id = intval( $request->get_param( 'attachment_id' ) );

        if ( ! $attachment_id ) {
            return new WP_Error(
                'missing_attachment_id',
                __( 'Missing attachment ID.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $attachment = get_post( $attachment_id );

        if ( ! $attachment || 'attachment' !== $attachment->post_type || ! wp_attachment_is_image( $attachment ) ) {
            return new WP_Error(
                'invalid_attachment',
                __( 'Invalid attachment.', 'storeagent-ai-for-woocommerce' ),
                array( 'status' => 400 )
            );
        }

        $image_url   = Image_Alt_Tags_AI::instance()->get_optimized_image_url( $attachment_id );
        $current_alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
        $caption     = $attachment->post_excerpt;
        $title       = $attachment->post_title;
        $description = $attachment->post_content;

        $form_data = array(
            'attachment_id' => $attachment_id,
            'image_url'     => $image_url,
            'current_alt'   => $current_alt,
            'caption'       => $caption,
            'title'         => $title,
            'description'   => $description,
        );

        return rest_ensure_response( $form_data );
    }

    /**
     * Get the endpoint arguments for the CREATE method.
     *
     * @param string $method The HTTP method.
     * @return array
     */
    public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {
        return array(
            WP_REST_Server::CREATABLE => array(
                'attachment_id'        => array(
                    'required'          => false,
                    'type'              => 'integer',
                    'sanitize_callback' => 'intval',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'post_context'         => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                    'validate_callback' => 'rest_validate_request_arg',
                    'description'       => __( 'JSON string containing the parent post/product context (title and description).', 'storeagent-ai-for-woocommerce' ),
                ),
                'image_url'            => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_url',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'current_alt'          => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'current_caption'      => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'current_title'        => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'current_description'  => array(
                    'required'          => false,
                    'type'              => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                    'validate_callback' => 'rest_validate_request_arg',
                ),
                'generate_alt'         => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => true,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
                'generate_caption'     => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => false,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
                'generate_title'       => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => false,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
                'generate_description' => array(
                    'required'          => false,
                    'type'              => 'boolean',
                    'default'           => false,
                    'sanitize_callback' => 'rest_sanitize_boolean',
                ),
            ),
        );
    }

    /**
     * Sanitize settings data before saving.
     *
     * @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'] );
        }

        // Sanitize default_fields setting.
        if ( isset( $params['default_fields'] ) && is_array( $params['default_fields'] ) ) {
            $allowed_fields              = array( 'alt', 'caption', 'title', 'description' );
            $sanitized['default_fields'] = array_values(
                array_intersect(
                    array_map( 'sanitize_text_field', $params['default_fields'] ),
                    $allowed_fields
                )
            );
        }

        return $sanitized;
    }

    /**
     * Get the public item schema.
     *
     * @return array
     */
    public function get_public_item_schema() {
        return array(
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'image_alt_tags',
            'type'       => 'object',
            'properties' => array(
                'attachment_id'    => array(
                    'description' => __( 'The attachment ID.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'integer',
                    'context'     => array( 'view', 'edit' ),
                    'readonly'    => true,
                ),
                'image_url'        => array(
                    'description' => __( 'The image URL.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'string',
                    'context'     => array( 'view', 'edit' ),
                    'readonly'    => true,
                ),
                'current_alt'      => array(
                    'description' => __( 'The current alt text.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'string',
                    'context'     => array( 'view', 'edit' ),
                    'readonly'    => true,
                ),
                'generate_alt'     => array(
                    'description' => __( 'Whether to generate alt text.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'boolean',
                    'context'     => array( 'view', 'edit' ),
                ),
                'generate_caption' => array(
                    'description' => __( 'Whether to generate caption.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'boolean',
                    'context'     => array( 'view', 'edit' ),
                ),
                'generate_title'   => array(
                    'description' => __( 'Whether to generate title.', 'storeagent-ai-for-woocommerce' ),
                    'type'        => 'boolean',
                    'context'     => array( 'view', 'edit' ),
                ),
            ),
        );
    }
}
