<?php

namespace EssentialBlocks\Integrations\AI;

/**
 * OpenAI API Integration for Essential Blocks
 *
 * This class handles the integration with OpenAI API for content generation
 */
class OpenAI
{
    /**
     * API Key for OpenAI
     *
     * @var string
     */
    private $api_key;

    /**
     * Maximum number of tokens to generate
     *
     * @var int
     */
    private $max_tokens = 1500;

    /**
     * API Endpoint for OpenAI Chat Completions
     *
     * @var string
     */
    private $api_endpoint = 'https://api.openai.com/v1/chat/completions';

    /**
     * API Endpoint for OpenAI Image Generation (DALL-E)
     *
     * @var string
     */
    private $image_api_endpoint = 'https://api.openai.com/v1/images/generations';

    /**
     * Model to use for OpenAI text generation
     * This will be set dynamically from settings
     *
     * @var string
     */
    private $model = 'gpt-4.1-nano';

    /**
     * Model to use for OpenAI image generation
     *
     * @var string
     */
    private $image_model = 'dall-e-3';

    /**
     * Default image size for DALL-E
     *
     * @var string
     */
    private $image_size = '1024x1024';

    /**
     * Default image quality for DALL-E
     *
     * @var string
     */
    private $image_quality = 'standard';

    /**
     * Constructor
     */
    public function __construct()
    {
        // Get API key from options
        $eb_write_with_ai = (array) get_option( 'eb_write_with_ai', [  ] );
        if ( ! empty( $eb_write_with_ai[ 'apiKey' ] ) ) {
            $this->set_api_key( $eb_write_with_ai[ 'apiKey' ] );
        }

        if ( isset( $eb_write_with_ai[ 'maxTokens' ] ) && intval( $eb_write_with_ai[ 'maxTokens' ] ) > 0 ) {
            $this->max_tokens = intval( $eb_write_with_ai[ 'maxTokens' ] );
        }

        // Set content generation model from settings
        if ( isset( $eb_write_with_ai[ 'contentModel' ] ) && ! empty( $eb_write_with_ai[ 'contentModel' ] ) ) {
            $this->set_content_model( $eb_write_with_ai[ 'contentModel' ] );
        }
    }

    /**
     * Set API Key
     *
     * @param string $api_key
     * @return void
     */
    public function set_api_key( $api_key )
    {
        $this->api_key = $api_key;
    }

    /**
     * Set Max Tokens
     *
     * @param int $max_tokens
     * @return void
     */
    public function set_max_tokens( $max_tokens )
    {
        $this->max_tokens = intval( $max_tokens );
    }

    /**
     * Set Content Generation Model
     *
     * @param string $model
     * @return void
     */
    public function set_content_model( $model )
    {
        // Validate the model against supported models
        $valid_models = [ 'gpt-4.1-nano', 'gpt-4o', 'gpt-4-turbo', 'gpt-4o-mini', 'gpt-3.5-turbo' ];
        if ( in_array( $model, $valid_models ) ) {
            $this->model = $model;
        } else {
            // Fallback to default if invalid model is provided
            $this->model = 'gpt-4.1-nano';
        }
    }

    /**
     * Validate API Key
     *
     * Makes a simple request to the OpenAI API to validate the API key
     *
     * @param string $api_key The API key to validate
     * @return array Response with status and message
     */
    public function validate_api_key( $api_key )
    {
        if ( empty( $api_key ) ) {
            return [
                'success' => false,
                'message' => __( 'API key is required.', 'essential-blocks' )
             ];
        }

        // Make a simple request to the OpenAI API to validate the key
        $response = wp_remote_post(
            'https://api.openai.com/v1/chat/completions',
            [
                'headers' => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $api_key
                 ],
                'body'    => wp_json_encode( [
                    'model'      => $this->model,
                    'messages'   => [
                        [
                            'role'    => 'user',
                            'content' => 'Hello'
                         ]
                     ],
                    'max_tokens' => 5
                 ] ),
                'timeout' => 15
             ]
        );

        // Check for errors
        if ( is_wp_error( $response ) ) {
            return [
                'success' => false,
                'message' => $response->get_error_message()
             ];
        }

        // Parse the response
        $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
        $response_code = wp_remote_retrieve_response_code( $response );

        // Check if the response is valid
        if ( $response_code !== 200 ) {
            $error_message = isset( $response_body[ 'error' ][ 'message' ] )
            ? $response_body[ 'error' ][ 'message' ]
            : __( 'Invalid API key or API error.', 'essential-blocks' );

            return [
                'success' => false,
                'message' => $error_message
             ];
        }

        return [
            'success' => true,
            'message' => __( 'API key is valid.', 'essential-blocks' )
         ];
    }

    /**
     * Generate content using OpenAI API
     *
     * @param string $prompt The complete prompt for content generation
     * @return array Response with status and content
     */
    public function generate_content( $prompt, $writePageContent = 'writePageContent' )
    {
        // Get AI settings
        $eb_write_with_ai = (array) get_option( 'eb_write_with_ai', [  ] );

        // Check if AI is enabled
        $is_ai_enabled_for_page_content = isset( $eb_write_with_ai[ 'writePageContent' ] ) ? $eb_write_with_ai[ 'writePageContent' ] : true;
        $is_ai_enabled_for_richtext     = isset( $eb_write_with_ai[ 'writeRichtext' ] ) ? $eb_write_with_ai[ 'writeRichtext' ] : true;
        $is_ai_enabled_for_input_fields = isset( $eb_write_with_ai[ 'writeInputFields' ] ) ? $eb_write_with_ai[ 'writeInputFields' ] : true;
        if ( $writePageContent === 'writePageContent' && ! $is_ai_enabled_for_page_content ) {
            return [
                'success' => false,
                'message' => __( 'AI page content generation is disabled. Please enable it in the settings.', 'essential-blocks' )
             ];
        } elseif ( $writePageContent === 'writeRichtext' && ! $is_ai_enabled_for_richtext ) {
            return [
                'success' => false,
                'message' => __( 'AI richtext content generation is disabled. Please enable it in the settings.', 'essential-blocks' )
             ];
        } elseif ( $writePageContent === 'writeInputFields' && ! $is_ai_enabled_for_input_fields ) {
            return [
                'success' => false,
                'message' => __( 'AI input fieldcontent generation is disabled. Please enable it in the settings.', 'essential-blocks' )
             ];
        }

        // Check if API key is set
        if ( empty( $this->api_key ) ) {
            return [
                'success' => false,
                'message' => __( 'OpenAI API key is not set. Please set it in the settings.', 'essential-blocks' )
             ];
        }

        // Prepare the request body
        $body = [
            'model'       => $this->model,
            'messages'    => [
                [
                    'role'    => 'user',
                    'content' => $prompt
                 ]
             ],
            'temperature' => 0.7,
            'max_tokens'  => $this->max_tokens
         ];

        // Make the API request
        $response = wp_remote_post(
            $this->api_endpoint,
            [
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $this->api_key
                 ],
                'body'        => wp_json_encode( $body ),
                'timeout'     => 60,
                'data_format' => 'body'
             ]
        );

        // Check for errors
        if ( is_wp_error( $response ) ) {
            return [
                'success' => false,
                'message' => $response->get_error_message()
             ];
        }

        // Parse the response
        $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
        $response_code = wp_remote_retrieve_response_code( $response );

        // Check if the response is valid
        if ( $response_code !== 200 || ! isset( $response_body[ 'choices' ][ 0 ][ 'message' ][ 'content' ] ) ) {
            $error_message = isset( $response_body[ 'error' ][ 'message' ] )
            ? $response_body[ 'error' ][ 'message' ]
            : __( 'Unknown error occurred while generating content.', 'essential-blocks' );

            return [
                'success'  => false,
                'message'  => $error_message,
                'response' => $response_body
             ];
        }

        // Return the generated content
        return [
            'success' => true,
            'content' => $response_body[ 'choices' ][ 0 ][ 'message' ][ 'content' ],
            'usage'   => isset( $response_body[ 'usage' ] ) ? $response_body[ 'usage' ] : null
         ];
    }

    /**
     * Convert string compression values to numeric values
     *
     * @param string $compression The compression level (high, medium, low, or numeric value)
     * @return int The numeric compression value
     */
    private function convert_compression_to_numeric( $compression )
    {
        // If it's already numeric, return as integer
        if ( is_numeric( $compression ) ) {
            return intval( $compression );
        }

        // Convert string values to numeric
        switch ( strtolower( trim( $compression ) ) ) {
            case 'high':
                return 100;
            case 'medium':
                return 75;
            case 'low':
                return 50;
            case 'standard':
            default:
                return 100; // Default to high quality
        }
    }

    /**
     * Generate image using OpenAI DALL-E API
     *
     * @param string $prompt The prompt for image generation
     * @param string $model The model to use (dall-e-2, dall-e-3, gpt-image-1)
     * @param string $size Image size (varies by model)
     * @param string $quality Image quality (standard, hd)
     * @param string $style Image style (vivid, natural) - DALL-E 3 only
     * @param string $writePageContent Context for AI settings check
     * @param string $background Background handling option
     * @param string $output_format Image output format (png, jpeg, webp)
     * @param string $output_compression Compression level for the output
     * @param int $image_count Number of images to generate
     * @param string $reference_image_url Reference image URL for editing mode
     * @param string $editing_mode Whether editing mode is enabled ('true' or 'false')
     * @param string $edit_type Type of edit operation ('edit' or 'variation')
     * @return array Response with status and image URL/base64
     */
    public function generate_image( $prompt, $model = 'gpt-image-1', $size = '1024x1024', $quality = 'standard', $style = 'vivid', $writePageContent = 'writePageContent', $background = '', $output_format = 'png', $output_compression = 'standard', $image_count = 2, $reference_image_url = '', $editing_mode = 'false', $edit_type = 'edit' )
    {
        // Get AI settings
        $eb_write_with_ai = (array) get_option( 'eb_write_with_ai', [  ] );

        // Check if AI is enabled for image generation
        $is_ai_enabled_for_image = isset( $eb_write_with_ai[ 'generateImage' ] ) ? $eb_write_with_ai[ 'generateImage' ] : true;

        if ( ! $is_ai_enabled_for_image ) {
            return [
                'success' => false,
                'message' => __( 'AI Image generation is disabled. Please enable it in the settings.', 'essential-blocks' )
             ];
        }

        // Check if API key is set
        if ( empty( $this->api_key ) ) {
            return [
                'success' => false,
                'message' => __( 'OpenAI API key is not set. Please set it in the settings.', 'essential-blocks' )
             ];
        }

        // Validate prompt
        if ( empty( $prompt ) || ! is_string( $prompt ) ) {
            return [
                'success' => false,
                'message' => __( 'Image prompt is required and must be a valid string.', 'essential-blocks' )
             ];
        }

        // Validate and sanitize prompt length (DALL-E has a 1000 character limit)
        if ( strlen( $prompt ) > 1000 ) {
            return [
                'success' => false,
                'message' => __( 'Image prompt must be 1000 characters or less.', 'essential-blocks' )
             ];
        }

        // Implement intelligent model selection based on parameters
        // $model = $this->determine_optimal_model( $model, $size, $quality, $style, $background, $output_format, $output_compression );

        // Validate model
        $valid_models = [ 'dall-e-2', 'dall-e-3', 'gpt-image-1' ];
        if ( ! in_array( $model, $valid_models ) ) {
            $model = $this->image_model; // fallback to default
        }

        // Validate image size based on model
        if ( $model === 'dall-e-2' ) {
            $valid_sizes = [ '256x256', '512x512', '1024x1024' ];
        } else { // dall-e-3
            $valid_sizes = [ '1024x1024', '1792x1024', '1024x1792' ];
        }

        if ( ! in_array( $size, $valid_sizes ) ) {
            $size = $model === 'dall-e-2' ? '1024x1024' : '1024x1024'; // fallback to default
        }

        // Filter and validate parameters based on selected model
        $filtered_params = $this->filter_parameters_by_model( $model, $size, $quality, $style, $background, $output_format, $output_compression );

        // Extract filtered parameters
        $size               = $filtered_params[ 'size' ];
        $quality            = $filtered_params[ 'quality' ];
        $style              = $filtered_params[ 'style' ];
        $background         = $filtered_params[ 'background' ];
        $output_format      = $filtered_params[ 'output_format' ];
        $output_compression = $filtered_params[ 'output_compression' ];

        // Convert output_compression from string to numeric if needed
        $output_compression = $this->convert_compression_to_numeric( $output_compression );

        // Validate and set image count based on model capabilities
        $validated_image_count = $image_count;
        if ( $model === 'dall-e-3' && $image_count > 1 ) {
            $validated_image_count = 1; // DALL-E 3 only supports 1 image per request
        } elseif ( $image_count < 1 || $image_count > 10 ) {
            $validated_image_count = 2; // Default fallback
        }

        // Prepare the request body with filtered parameters
        $body = [
            'model'           => $model,
            'prompt'          => $prompt,
            'n'               => $validated_image_count, // number of images to generate
            'size'            => $size,
            'response_format' => 'b64_json' // url or b64_json
         ];

        // Add model-specific parameters based on capabilities
        switch ( $model ) {
            case 'dall-e-2':
                // DALL-E 2 only supports basic parameters
                break;

            case 'dall-e-3':
                // DALL-E 3 supports quality and style
                if ( ! empty( $quality ) && $quality !== 'standard' ) {
                    $body[ 'quality' ] = $quality;
                }
                if ( ! empty( $style ) && $style !== 'none' ) {
                    $body[ 'style' ] = $style;
                }
                // Note: 'n' is already set above with validated count (always 1 for dall-e-3)
                break;

            case 'gpt-image-1':
                // GPT-Image-1 supports additional parameters
                if ( ! empty( $background ) && $background !== 'auto' ) {
                    $body[ 'background' ] = $background;
                }
                if ( ! empty( $output_format ) && $output_format !== 'png' ) {
                    $body[ 'output_format' ] = $output_format;
                }
                if ( ! empty( $output_compression ) ) {
                    $body[ 'output_compression' ] = $output_compression;
                }
                if ( ! empty( $quality ) && $quality !== 'medium' ) {
                    $body[ 'quality' ] = $quality;
                }
                unset( $body[ 'response_format' ] );
                break;
        }
        // error_log( 'GPT Model: ' . $model );
        // error_log( 'GPT Body: ' . print_r( $body, true ) );

        // Handle editing mode with specialized OpenAI endpoints
        if ( ! empty( $reference_image_url ) && $editing_mode === 'true' ) {
            return $this->handle_image_editing( $reference_image_url, $prompt, $edit_type, $validated_image_count, $size );
        }

        // Make the API request
        $response = wp_remote_post(
            $this->image_api_endpoint,
            [
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $this->api_key
                 ],
                'body'        => wp_json_encode( $body ),
                'timeout'     => 180,
                'data_format' => 'body'
             ]
        );

        // error_log( 'Response-----' . print_r( $response, true ) );

        // Check for errors
        if ( is_wp_error( $response ) ) {
            return [
                'success' => false,
                'message' => $response->get_error_message()
             ];
        }

        // Parse the response
        $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
        $response_code = wp_remote_retrieve_response_code( $response );

        // Check if the response is valid - handle both 'url' and 'b64_json' formats
        if ( $response_code !== 200 || ! isset( $response_body[ 'data' ][ 0 ] ) ) {
            $error_message = isset( $response_body[ 'error' ][ 'message' ] )
            ? $response_body[ 'error' ][ 'message' ]
            : __( 'Unknown error occurred while generating image.', 'essential-blocks' );

            return [
                'success'  => false,
                'message'  => $error_message,
                'response' => $response_body
             ];
        }

        // Check if first image has either url or b64_json
        $first_image = $response_body[ 'data' ][ 0 ];
        if ( ! isset( $first_image[ 'url' ] ) && ! isset( $first_image[ 'b64_json' ] ) ) {
            return [
                'success'  => false,
                'message'  => __( 'Invalid image data received from OpenAI API.', 'essential-blocks' ),
                'response' => $response_body
             ];
        }

        // Process all generated images
        $images = [  ];
        foreach ( $response_body[ 'data' ] as $index => $image_data ) {
            // Handle both URL and base64 formats
            $image_url = null;
            $image_b64 = null;

            if ( isset( $image_data[ 'url' ] ) ) {
                $image_url = $image_data[ 'url' ];
            } elseif ( isset( $image_data[ 'b64_json' ] ) ) {
                $image_b64 = $image_data[ 'b64_json' ];
            }

            $revised_prompt = isset( $image_data[ 'revised_prompt' ] ) ? $image_data[ 'revised_prompt' ] : $prompt;

            // Generate metadata for each image
            $metadata = $this->generate_image_metadata( $revised_prompt, $prompt );

            $images[  ] = [
                'image_url'      => $image_url,
                'image_b64'      => $image_b64,
                'revised_prompt' => $revised_prompt,
                'title'          => $metadata[ 'title' ],
                'alt_tag'        => $metadata[ 'alt_tag' ],
                'caption'        => $metadata[ 'caption' ],
                'description'    => $metadata[ 'description' ]
             ];
        }

        // Images processed successfully

        // Extract usage information from the API response
        $usage_info = $this->extract_image_usage_info( $response_body, $model, $validated_image_count );
        // error_log( 'Usage Info: ' . print_r( $usage_info, true ) );

        // Return all generated images with usage information
        return [
            'success' => true,
            'images'  => $images,
            'usage'   => $usage_info
         ];
    }

    /**
     * Extract usage information from OpenAI image generation API response
     *
     * @param array $response_body The API response body
     * @param string $model The model used for generation
     * @param int $image_count The number of images generated
     * @return array Usage information with formatted message
     */
    private function extract_image_usage_info( $response_body, $model, $image_count )
    {
        // Check if usage information is available in the response
        if ( isset( $response_body[ 'usage' ] ) ) {
            $usage = $response_body[ 'usage' ];

            // Extract token information
            $input_tokens  = isset( $usage[ 'input_tokens' ] ) ? intval( $usage[ 'input_tokens' ] ) : 0;
            $output_tokens = isset( $usage[ 'output_tokens' ] ) ? intval( $usage[ 'output_tokens' ] ) : 0;
            $total_tokens  = isset( $usage[ 'total_tokens' ] ) ? intval( $usage[ 'total_tokens' ] ) : ( $input_tokens + $output_tokens );

            // Create user-friendly usage message
            $usage_message = sprintf(
                __( 'Using %s model, you consumed %d input tokens and %d output tokens for generating %d image(s).', 'essential-blocks' ),
                strtoupper( $model ),
                $input_tokens,
                $output_tokens,
                $image_count
            );

            return [
                'input_tokens'  => $input_tokens,
                'output_tokens' => $output_tokens,
                'total_tokens'  => $total_tokens,
                'message'       => $usage_message,
                'raw_usage'     => $usage
             ];
        }

        // Fallback when usage information is not available
        $fallback_message = sprintf(
            __( 'Successfully generated %d image(s) using %s model. Token usage information not available.', 'essential-blocks' ),
            $image_count,
            strtoupper( $model )
        );

        return [
            'input_tokens'  => null,
            'output_tokens' => null,
            'total_tokens'  => null,
            'message'       => $fallback_message,
            'raw_usage'     => null
         ];
    }

    /**
     * Determine optimal model based on parameters
     *
     * @param string $requested_model The originally requested model
     * @param string $size Image size
     * @param string $quality Image quality
     * @param string $style Image style
     * @param string $background Background setting
     * @param string $output_format Output format
     * @param string $output_compression Output compression
     * @return string The optimal model to use
     */
    private function determine_optimal_model( $requested_model, $size, $quality, $style, $background, $output_format, $output_compression )
    {
        // Priority 1: If background is not 'auto', must use gpt-image-1
        if ( ! empty( $background ) && $background !== 'auto' ) {
            return 'gpt-image-1';
        }

        // Priority 2: If output_format or output_compression is not default, must use gpt-image-1
        if ( ( ! empty( $output_format ) && $output_format !== 'png' ) ||
            ( ! empty( $output_compression ) && $output_compression !== 'standard' ) ) {
            return 'gpt-image-1';
        }

        // Priority 3: If style is 'vivid' or 'natural', must use dall-e-3
        if ( ! empty( $style ) && ( $style === 'vivid' || $style === 'natural' ) ) {
            return 'dall-e-3';
        }

        // Priority 4: Size-based selection
        $dalle_e2_sizes   = [ '256x256', '512x512' ];
        $dalle_e3_sizes   = [ '1792x1024', '1024x1792' ];
        $gpt_image1_sizes = [ '1536x1024', '1024x1536', 'auto' ];

        if ( in_array( $size, $dalle_e2_sizes ) ) {
            return 'dall-e-2';
        }

        if ( in_array( $size, $dalle_e3_sizes ) ) {
            return 'dall-e-3';
        }

        if ( in_array( $size, $gpt_image1_sizes ) ) {
            return 'gpt-image-1';
        }

        // For 1024x1024 or other sizes, default to gpt-image-1 unless style forces dall-e-3
        return 'gpt-image-1';
    }

    /**
     * Filter parameters based on model capabilities
     *
     * @param string $model The selected model
     * @param string $size Image size
     * @param string $quality Image quality
     * @param string $style Image style
     * @param string $background Background setting
     * @param string $output_format Output format
     * @param string $output_compression Output compression
     * @return array Filtered parameters
     */
    private function filter_parameters_by_model( $model, $size, $quality, $style, $background, $output_format, $output_compression )
    {
        $filtered = [
            'size'               => $size,
            'quality'            => $quality,
            'style'              => $style,
            'background'         => $background,
            'output_format'      => $output_format,
            'output_compression' => $output_compression
         ];

        switch ( $model ) {
            case 'dall-e-2':
                // DALL-E 2: Only supports size and prompt
                $filtered[ 'quality' ]            = 'standard'; // Reset to default
                $filtered[ 'style' ]              = 'none'; // Reset to none
                $filtered[ 'background' ]         = 'auto'; // Reset to auto
                $filtered[ 'output_format' ]      = 'png'; // Reset to default
                $filtered[ 'output_compression' ] = 'standard'; // Reset to default

                // Validate size for DALL-E 2
                $valid_sizes = [ '256x256', '512x512', '1024x1024' ];
                if ( ! in_array( $size, $valid_sizes ) ) {
                    $filtered[ 'size' ] = '1024x1024'; // Default fallback
                }
                break;

            case 'dall-e-3':
                // DALL-E 3: Supports quality, style, size, prompt
                $filtered[ 'background' ]         = 'auto'; // Reset to auto
                $filtered[ 'output_format' ]      = 'png'; // Reset to default
                $filtered[ 'output_compression' ] = 'standard'; // Reset to default

                // Validate quality for DALL-E 3
                $valid_qualities = [ 'standard', 'hd' ];
                if ( ! in_array( $quality, $valid_qualities ) ) {
                    $filtered[ 'quality' ] = 'standard';
                }

                // Validate style for DALL-E 3
                $valid_styles = [ 'vivid', 'natural' ];
                if ( ! in_array( $style, $valid_styles ) ) {
                    $filtered[ 'style' ] = 'vivid'; // Default for DALL-E 3
                }

                // Validate size for DALL-E 3
                $valid_sizes = [ '1024x1024', '1792x1024', '1024x1792' ];
                if ( ! in_array( $size, $valid_sizes ) ) {
                    $filtered[ 'size' ] = '1024x1024'; // Default fallback
                }
                break;

            case 'gpt-image-1':
                // GPT-Image-1: Supports all parameters

                // Validate quality for GPT-Image-1
                $valid_qualities = [ 'high', 'medium', 'low' ];
                if ( ! in_array( $quality, $valid_qualities ) ) {
                    $filtered[ 'quality' ] = 'medium'; // Default for GPT-Image-1
                }

                // Validate background
                $valid_backgrounds = [ 'auto', 'transparent', 'opaque' ];
                if ( ! in_array( $background, $valid_backgrounds ) ) {
                    $filtered[ 'background' ] = 'auto';
                }

                // Validate output format
                $valid_formats = [ 'png', 'jpeg', 'webp' ];
                if ( ! in_array( $output_format, $valid_formats ) ) {
                    $filtered[ 'output_format' ] = 'png';
                }

                // Validate output compression
                $valid_compressions = [ 'standard', 'high', 'low', 'medium' ];
                if ( ! in_array( $output_compression, $valid_compressions ) ) {
                    $filtered[ 'output_compression' ] = 'standard';
                }
                // Validate output compression for PNG
                else if ( $filtered[ 'output_format' ] === 'png' ) {
                    $filtered[ 'output_compression' ] = 'standard';
                }

                // Validate size for GPT-Image-1
                $valid_sizes = [ '1024x1024', '1536x1024', '1024x1536', 'auto' ];
                if ( ! in_array( $size, $valid_sizes ) ) {
                    $filtered[ 'size' ] = 'auto'; // Default fallback
                }

                // Reset style to none for GPT-Image-1
                $filtered[ 'style' ] = 'none';
                break;
        }

        return $filtered;
    }

    /**
     * Generate metadata for an image based on its prompt
     *
     * @param string $revised_prompt The revised prompt from DALL-E
     * @param string $original_prompt The original user prompt
     * @return array Array containing title, alt_tag, caption, and description
     */
    private function generate_image_metadata( $revised_prompt, $original_prompt )
    {
        // If API key is not available, return default metadata
        if ( empty( $this->api_key ) ) {
            return $this->get_default_image_metadata( $original_prompt );
        }

        // Create a prompt for generating metadata
        $metadata_prompt = "Based on this image description: \"{$revised_prompt}\"\n\n" .
            "Generate appropriate metadata for this image in the following JSON format:\n" .
            "{\n" .
            "  \"title\": \"A concise, descriptive title (max 60 characters)\",\n" .
            "  \"alt_tag\": \"Descriptive alt text for accessibility (max 125 characters)\",\n" .
            "  \"caption\": \"A brief caption describing the image (max 200 characters)\",\n" .
            "  \"description\": \"A detailed description of the image (max 300 characters)\"\n" .
            "}\n\n" .
            "Make sure the JSON is valid and all fields are filled. Focus on being descriptive but concise.";

        // Prepare the request body for metadata generation
        $body = [
            'model'       => $this->model,
            'messages'    => [
                [
                    'role'    => 'system',
                    'content' => 'You are an expert at creating image metadata. Always respond with valid JSON only, no additional text.'
                 ],
                [
                    'role'    => 'user',
                    'content' => $metadata_prompt
                 ]
             ],
            'temperature' => 0.3, // Lower temperature for more consistent output
            'max_tokens'  => 300
         ];

        // Make the API request for metadata
        $response = wp_remote_post(
            $this->api_endpoint,
            [
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $this->api_key
                 ],
                'body'        => wp_json_encode( $body ),
                'timeout'     => 30,
                'data_format' => 'body'
             ]
        );

        // Check for errors or invalid response
        if ( is_wp_error( $response ) ) {
            return $this->get_default_image_metadata( $original_prompt );
        }

        $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
        $response_code = wp_remote_retrieve_response_code( $response );

        if ( $response_code !== 200 || ! isset( $response_body[ 'choices' ][ 0 ][ 'message' ][ 'content' ] ) ) {
            return $this->get_default_image_metadata( $original_prompt );
        }

        // Parse the JSON response
        $metadata_json = $response_body[ 'choices' ][ 0 ][ 'message' ][ 'content' ];
        $metadata      = json_decode( $metadata_json, true );

        // Validate the metadata structure
        if ( ! is_array( $metadata ) ||
            ! isset( $metadata[ 'title' ] ) ||
            ! isset( $metadata[ 'alt_tag' ] ) ||
            ! isset( $metadata[ 'caption' ] ) ||
            ! isset( $metadata[ 'description' ] ) ) {
            return $this->get_default_image_metadata( $original_prompt );
        }

        // Sanitize and truncate the metadata fields
        return [
            'title'       => sanitize_text_field( substr( $metadata[ 'title' ], 0, 60 ) ),
            'alt_tag'     => sanitize_text_field( substr( $metadata[ 'alt_tag' ], 0, 125 ) ),
            'caption'     => sanitize_text_field( substr( $metadata[ 'caption' ], 0, 200 ) ),
            'description' => sanitize_text_field( substr( $metadata[ 'description' ], 0, 300 ) )
         ];
    }

    /**
     * Get default image metadata when AI generation fails
     *
     * @param string $prompt The original prompt
     * @return array Default metadata array
     */
    private function get_default_image_metadata( $prompt )
    {
        // Create basic metadata from the prompt
        $clean_prompt = sanitize_text_field( $prompt );
        $title        = substr( $clean_prompt, 0, 60 );

        return [
            'title'       => $title ?: __( 'AI Generated Image', 'essential-blocks' ),
            'alt_tag'     => substr( $clean_prompt, 0, 125 ) ?: __( 'AI generated image', 'essential-blocks' ),
            'caption'     => substr( $clean_prompt, 0, 200 ) ?: __( 'Image generated using AI', 'essential-blocks' ),
            'description' => substr( $clean_prompt, 0, 300 ) ?: __( 'This image was generated using artificial intelligence based on a text prompt.', 'essential-blocks' )
         ];
    }

    /**
     * Convert image URL to base64 data URL with RGBA format for OpenAI compatibility
     *
     * @param string $image_url The image URL to convert
     * @return string|false Base64 data URL or false on failure
     */
    private function convert_image_to_base64( $image_url )
    {
        if ( empty( $image_url ) ) {
            return false;
        }

        // Step 1: Try direct file access for local images
        $image_data  = $this->get_local_image_data( $image_url );
        $method_used = 'direct_file_access';

        // Step 2: Fallback to HTTP request if direct access failed
        if ( $image_data === false ) {
            $image_data  = $this->get_remote_image_data( $image_url );
            $method_used = 'http_request';
        }

        if ( $image_data === false ) {
            return false;
        }

        // Convert image to RGBA format for OpenAI compatibility
        $rgba_image_data = $this->convert_image_to_rgba( $image_data );
        if ( $rgba_image_data === false ) {
            return false;
        }

        // Encode to base64
        $base64_data = base64_encode( $rgba_image_data );
        if ( $base64_data === false ) {
            return false;
        }

        // Return as PNG data URL (PNG supports alpha channel)
        return 'data:image/png;base64,' . $base64_data;
    }

    /**
     * Convert image data to RGBA format for OpenAI compatibility
     *
     * @param string $image_data Binary image data
     * @return string|false RGBA image data as PNG or false on failure
     */
    private function convert_image_to_rgba( $image_data )
    {
        // Check if GD extension is available
        if ( ! extension_loaded( 'gd' ) ) {
            return false;
        }

        // Create image resource from string
        $image = imagecreatefromstring( $image_data );
        if ( $image === false ) {
            return false;
        }

        // Get image dimensions
        $width  = imagesx( $image );
        $height = imagesy( $image );

        if ( $width === false || $height === false ) {
            imagedestroy( $image );
            return false;
        }

        // Create a new true color image with alpha channel
        $rgba_image = imagecreatetruecolor( $width, $height );
        if ( $rgba_image === false ) {
            imagedestroy( $image );
            return false;
        }

        // Enable alpha blending and save alpha channel
        imagealphablending( $rgba_image, false );
        imagesavealpha( $rgba_image, true );

        // Fill with transparent background
        $transparent = imagecolorallocatealpha( $rgba_image, 0, 0, 0, 127 );
        if ( $transparent === false ) {
            imagedestroy( $image );
            imagedestroy( $rgba_image );
            return false;
        }

        imagefill( $rgba_image, 0, 0, $transparent );

        // Enable alpha blending for copying
        imagealphablending( $rgba_image, true );

        // Copy the original image to the RGBA image
        if ( ! imagecopy( $rgba_image, $image, 0, 0, 0, 0, $width, $height ) ) {
            imagedestroy( $image );
            imagedestroy( $rgba_image );
            return false;
        }

        // Clean up original image
        imagedestroy( $image );

        // Capture PNG output
        ob_start();
        $png_success = imagepng( $rgba_image );
        $png_data    = ob_get_contents();
        ob_end_clean();

        // Clean up RGBA image
        imagedestroy( $rgba_image );

        if ( ! $png_success || empty( $png_data ) ) {
            return false;
        }

        return $png_data;
    }

    /**
     * Attempt to get image data via direct file access for local images
     *
     * @param string $image_url The image URL to process
     * @return string|false Image data or false on failure
     */
    private function get_local_image_data( $image_url )
    {
        // Parse the URL
        $parsed_url = wp_parse_url( $image_url );
        if ( ! $parsed_url || ! isset( $parsed_url[ 'path' ] ) ) {
            return false;
        }

        // Check if this is likely a local URL
        if ( isset( $parsed_url[ 'host' ] ) ) {
            $host     = $parsed_url[ 'host' ];
            $is_local = in_array( $host, [ 'localhost', '127.0.0.1', '::1' ] ) ||
            filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) === false;

            if ( ! $is_local ) {
                return false; // Not a local URL, skip direct file access
            }
        }

        // Convert URL path to file system path
        $file_path = $this->url_to_file_path( $image_url );
        if ( $file_path === false ) {
            return false;
        }

        // Check if file exists and is readable
        if ( ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
            return false;
        }

        // Verify it's an image file by checking MIME type
        $finfo = finfo_open( FILEINFO_MIME_TYPE );
        if ( $finfo ) {
            $mime_type = finfo_file( $finfo, $file_path );
            finfo_close( $finfo );

            if ( ! $mime_type || strpos( $mime_type, 'image/' ) !== 0 ) {
                return false; // Not an image file
            }
        }

        // Read the file contents
        $image_data = file_get_contents( $file_path );
        if ( $image_data === false ) {
            return false;
        }

        return $image_data;
    }

    /**
     * Convert URL to file system path
     *
     * @param string $image_url The image URL
     * @return string|false File system path or false on failure
     */
    private function url_to_file_path( $image_url )
    {
        // Get WordPress paths
        $wp_upload_dir = wp_upload_dir();
        $upload_url    = $wp_upload_dir[ 'baseurl' ];
        $upload_path   = $wp_upload_dir[ 'basedir' ];

        $content_url  = content_url();
        $content_path = WP_CONTENT_DIR;

        $site_url = site_url();
        $abspath  = ABSPATH;

        // Try to match against common WordPress URL patterns
        if ( strpos( $image_url, $upload_url ) === 0 ) {
            // Image is in uploads directory
            $relative_path = str_replace( $upload_url, '', $image_url );
            return $upload_path . $relative_path;
        } elseif ( strpos( $image_url, $content_url ) === 0 ) {
            // Image is in wp-content directory
            $relative_path = str_replace( $content_url, '', $image_url );
            return $content_path . $relative_path;
        } elseif ( strpos( $image_url, $site_url ) === 0 ) {
            // Image is somewhere in the WordPress installation
            $relative_path = str_replace( $site_url, '', $image_url );
            return $abspath . ltrim( $relative_path, '/' );
        }

        // Try to handle relative URLs or URLs without domain
        $parsed_url = wp_parse_url( $image_url );
        if ( isset( $parsed_url[ 'path' ] ) ) {
            $path = $parsed_url[ 'path' ];

            // Check if it's a path starting with /wp-content/
            if ( strpos( $path, '/wp-content/' ) === 0 ) {
                return $abspath . ltrim( $path, '/' );
            }

            // Check if it's a path that might be relative to uploads
            if ( strpos( $path, '/uploads/' ) !== false ) {
                $uploads_pos   = strpos( $path, '/uploads/' );
                $relative_path = substr( $path, $uploads_pos );
                return $upload_path . $relative_path;
            }
        }

        return false;
    }

    /**
     * Get image data via HTTP request (fallback method)
     *
     * @param string $image_url The image URL to download
     * @return string|false Image data or false on failure
     */
    private function get_remote_image_data( $image_url )
    {
        // wp_safe_remote_get sets reject_unsafe_urls, blocking loopback/private/link-local
        // ranges so an attacker-supplied reference_image_url cannot probe internal hosts.
        $response = wp_safe_remote_get( $image_url, [
            'timeout'    => 30,
            'user-agent' => 'Essential Blocks Image Converter'
         ] );

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

        $image_data = wp_remote_retrieve_body( $response );
        if ( empty( $image_data ) ) {
            return false;
        }

        return $image_data;
    }

    /**
     * Handle image editing using OpenAI's specialized endpoints
     *
     * @param string $reference_image_url The reference image URL
     * @param string $prompt The editing prompt (required for edits, ignored for variations)
     * @param string $edit_type Type of edit ('edit' or 'variation')
     * @param int $image_count Number of images to generate
     * @param string $size Image size
     * @return array Response with status and image data
     */
    private function handle_image_editing( $reference_image_url, $prompt, $edit_type, $image_count, $size )
    {
        // Process the reference image and get its dimensions
        $processed_image_data = $this->process_reference_image_with_dimensions( $reference_image_url );
        if ( $processed_image_data === false ) {
            return [
                'success' => false,
                'message' => __( 'Failed to process reference image for editing.', 'essential-blocks' )
             ];
        }

        $processed_image = $processed_image_data[ 'image_data' ];
        $image_width     = $processed_image_data[ 'width' ];
        $image_height    = $processed_image_data[ 'height' ];

        // Determine the optimal size based on reference image aspect ratio
        $optimal_size = $this->select_optimal_size_for_editing( $image_width, $image_height );

        // Log the size selection for debugging
        // error_log( sprintf(
        //     'Image editing size selection: Original dimensions %dx%d (ratio: %.2f), Selected size: %s',
        //     $image_width,
        //     $image_height,
        //     $image_width / $image_height,
        //     $optimal_size
        // ) );
        // wp_die();

        // Determine the appropriate endpoint
        // $endpoint = $edit_type === 'variation'
        // ? 'https://api.openai.com/v1/images/variations'
        // : 'https://api.openai.com/v1/images/edits';

        $endpoint = 'https://api.openai.com/v1/images/edits';

        // Prepare the multipart form data
        $boundary = wp_generate_uuid4();
        $model    = 'gpt-image-1';
        $body     = $this->build_multipart_body( $processed_image, $prompt, $edit_type, $image_count, $optimal_size, $boundary, $model );

        // $logged_body = preg_replace( '/[\x00-\x1F\x80-\xFF]/', '.', $body ); // replace binary with dots
        // error_log( 'Body-----' . print_r( $body, true ) );

        // Make the API request with multipart/form-data
        $dev = false;
        if ( $dev ) {
            $dummy_response_path = ESSENTIAL_BLOCKS_DIR_PATH . 'includes/Integrations/AI/image-edit-response.json';
            $json_data           = file_get_contents( $dummy_response_path );
            $response            = json_decode( $json_data, true ); // set true t
        } else {
            $response = wp_remote_post(
                $endpoint,
                [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $this->api_key,
                        'Content-Type'  => 'multipart/form-data; boundary=' . $boundary
                     ],
                    'body'    => $body,
                    'timeout' => 180
                 ]
            );
        }
        // error_log( 'Response-----' . print_r( $response, true ) );

        if ( is_wp_error( $response ) ) {
            return [
                'success' => false,
                'message' => $response->get_error_message()
             ];
        }

        // Parse the response
        $response_body_raw = wp_remote_retrieve_body( $response );
        $response_code     = wp_remote_retrieve_response_code( $response );

        // Handle both string and array response body
        if ( is_string( $response_body_raw ) ) {
            $response_body = json_decode( $response_body_raw, true );
            if ( json_last_error() !== JSON_ERROR_NONE ) {
                return [
                    'success' => false,
                    'message' => __( 'Invalid JSON response from OpenAI API.', 'essential-blocks' )
                 ];
            }
        } else {
            $response_body = $response_body_raw;
        }

        // Check if the response is valid
        if ( $response_code !== 200 || ! is_array( $response_body ) || ! isset( $response_body[ 'data' ] ) || ! is_array( $response_body[ 'data' ] ) || empty( $response_body[ 'data' ] ) ) {
            $error_message = ( is_array( $response_body ) && isset( $response_body[ 'error' ][ 'message' ] ) )
            ? $response_body[ 'error' ][ 'message' ]
            : __( 'Unknown error occurred during image editing.', 'essential-blocks' );

            return [
                'success'  => false,
                'message'  => $error_message,
                'response' => $response_body
             ];
        }
        $response_data = $response_body[ 'data' ];

        // Process the edited images
        $images = [  ];
        foreach ( $response_data as $image_data ) {
            $image_url = isset( $image_data[ 'url' ] ) ? $image_data[ 'url' ] : null;
            $image_b64 = isset( $image_data[ 'b64_json' ] ) ? $image_data[ 'b64_json' ] : null;

            // Generate metadata for the edited image
            $metadata = $this->generate_image_metadata( $prompt, $prompt );

            $images[  ] = [
                'image_url'      => $image_url,
                'image_b64'      => $image_b64,
                'revised_prompt' => $prompt,
                'title'          => $metadata[ 'title' ],
                'alt_tag'        => $metadata[ 'alt_tag' ],
                'caption'        => $metadata[ 'caption' ],
                'description'    => $metadata[ 'description' ]
             ];
        }

        // Extract usage information from the API response
        $usage_info = $this->extract_image_usage_info( $response_body, $model, count( $images ) );

        return [
            'success' => true,
            'images'  => $images,
            'usage'   => $usage_info
         ];
    }

    /**
     * Build multipart form data for image editing requests
     *
     * @param string $image_data Base64 image data
     * @param string $prompt The editing prompt
     * @param string $edit_type Type of edit ('edit' or 'variation')
     * @param int $image_count Number of images to generate
     * @param string $size Image size
     * @param string $boundary Multipart boundary
     * @param string $model The model to use for image generation
     * @return string Multipart form data
     */
    private function build_multipart_body( $image_data, $prompt, $edit_type, $image_count, $size, $boundary, $model )
    {
        $body = '';

        // Add image data
        if ( strpos( $image_data, 'data:' ) === 0 ) {
            // Extract base64 data from data URL
            $image_parts  = explode( ',', $image_data );
            $image_binary = base64_decode( $image_parts[ 1 ] );
            $mime_type    = explode( ';', explode( ':', $image_parts[ 0 ] )[ 1 ] )[ 0 ];
            $extension    = $this->get_extension_from_mime_type( $mime_type );
        } else {
            // Assume it's already binary data
            $image_binary = $image_data;
            $mime_type    = 'image/png'; // Default MIME type
            $extension    = 'png'; // Default extension
        }

        $body .= "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"image\"; filename=\"image.{$extension}\"\r\n";
        $body .= "Content-Type: {$mime_type}\r\n\r\n";
        $body .= $image_binary . "\r\n";

        // Add prompt (only for edits, not variations)
        if ( ! empty( $prompt ) ) {
            // error_log( message: 'Inside prompt condition' . print_r( $prompt, return : true ) );
            $body .= "--{$boundary}\r\n";
            $body .= "Content-Disposition: form-data; name=\"prompt\"\r\n\r\n";
            $body .= $prompt . "\r\n";
        }

        // Add number of images
        $body .= "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"n\"\r\n\r\n";
        $body .= $image_count . "\r\n";

        // Add size
        $body .= "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"size\"\r\n\r\n";
        $body .= $size . "\r\n";

        // Add model
        $body .= "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"model\"\r\n\r\n";
        $body .= $model . "\r\n";

        // if ( $edit_type === 'variation' ) {
        //     // Add response format
        //     $body .= "--{$boundary}\r\n";
        //     $body .= "Content-Disposition: form-data; name=\"response_format\"\r\n\r\n";
        //     $body .= "b64_json\r\n";
        // }

        $body .= "--{$boundary}--\r\n";

        return $body;
    }

    /**
     * Process reference image for editing mode
     *
     * @param string $reference_image_url The reference image URL
     * @return string|false Processed image URL/data or false on failure
     */
    private function process_reference_image( $reference_image_url )
    {
        if ( empty( $reference_image_url ) ) {
            return false;
        }
        return $this->convert_image_to_base64( $reference_image_url );
    }

    /**
     * Process reference image for editing mode and extract dimensions
     *
     * @param string $reference_image_url The reference image URL
     * @return array|false Array with image_data, width, height or false on failure
     */
    private function process_reference_image_with_dimensions( $reference_image_url )
    {
        if ( empty( $reference_image_url ) ) {
            return false;
        }

        // Get the original image data first to extract dimensions
        $image_data = $this->get_local_image_data( $reference_image_url );
        if ( $image_data === false ) {
            $image_data = $this->get_remote_image_data( $reference_image_url );
        }

        if ( $image_data === false ) {
            return false;
        }

        // Extract dimensions using GD
        if ( ! extension_loaded( 'gd' ) ) {
            return false;
        }

        $image = imagecreatefromstring( $image_data );
        if ( $image === false ) {
            return false;
        }

        $width  = imagesx( $image );
        $height = imagesy( $image );
        imagedestroy( $image );

        if ( $width === false || $height === false ) {
            return false;
        }

        // Now convert to base64 for API usage
        $processed_image = $this->convert_image_to_base64( $reference_image_url );
        if ( $processed_image === false ) {
            return false;
        }

        return [
            'image_data' => $processed_image,
            'width'      => $width,
            'height'     => $height
         ];
    }

    /**
     * Select optimal size for image editing based on reference image aspect ratio
     *
     * @param int $width Reference image width
     * @param int $height Reference image height
     * @return string Optimal size for OpenAI image editing API
     */
    private function select_optimal_size_for_editing( $width, $height )
    {
        // Default to square if dimensions are invalid
        if ( $width <= 0 || $height <= 0 ) {
            return '1024x1024';
        }

        // Calculate aspect ratio
        $aspect_ratio = $width / $height;

        // Define available sizes and their aspect ratios
        $available_sizes = [
            '1024x1024' => 1.0, // Square (1:1)
            '1536x1024' => 1.5, // Landscape (3:2)
            '1024x1536' => 0.67 // Portrait (2:3)
         ];

        // Find the closest aspect ratio match
        $closest_size        = '1024x1024'; // Default
        $smallest_difference = PHP_FLOAT_MAX;

        foreach ( $available_sizes as $size => $size_ratio ) {
            $difference = abs( $aspect_ratio - $size_ratio );
            if ( $difference < $smallest_difference ) {
                $smallest_difference = $difference;
                $closest_size        = $size;
            }
        }

        return $closest_size;
    }

    /**
     * Get file extension from MIME type
     *
     * @param string $mime_type MIME type
     * @return string File extension
     */
    private function get_extension_from_mime_type( $mime_type )
    {
        switch ( $mime_type ) {
            case 'image/jpeg':
                return 'jpg';
            case 'image/png':
                return 'png';
            case 'image/gif':
                return 'gif';
            case 'image/webp':
                return 'webp';
            case 'image/bmp':
                return 'bmp';
            default:
                return 'png';
        }
    }
}
