<?php

/**
 * DALL-E Image Generator Class
 *
 * Handles image generation using OpenAI's DALL-E API
 *
 * @link       https://insya.com/ai-magic
 * @since      1.0.8
 *
 * @package    Ai_Magic
 * @subpackage Ai_Magic/admin
 */

// Load interface if not already loaded
if (!interface_exists('AI_Magic_Image_Provider_Interface')) {
    require_once plugin_dir_path(dirname(__FILE__)) . 'includes/interface-ai-magic-image-provider.php';
}

/**
 * DALL-E Image Generator
 *
 * @package    Ai_Magic
 * @subpackage Ai_Magic/admin
 * @author     AI Magic <info@insya.com>
 */
class AI_Magic_Dalle implements AI_Magic_Image_Provider_Interface
{
    /**
     * OpenAI API Key
     *
     * @var string
     */
    private $api_key;

    /**
     * API URL
     *
     * @var string
     */
    private $api_url = 'https://api.openai.com/v1/images/generations';

    /**
     * Default model
     *
     * @var string
     */
    private $model;

    /**
     * Default size
     *
     * @var string
     */
    private $default_size;

    /**
     * Default quality
     *
     * @var string
     */
    private $default_quality;

    /**
     * Default style
     *
     * @var string
     */
    private $default_style;

    /**
     * Constructor
     *
     * @since    1.0.8
     */
    public function __construct()
    {
        $this->api_key = get_option('ai_magic_api_key_openai', get_option('ai_magic_api_key', ''));
        $this->model = get_option('ai_magic_dalle_model', 'dall-e-3');
        $this->default_size = get_option('ai_magic_dalle_size', '1024x1024');
        $this->default_quality = get_option('ai_magic_dalle_quality', 'standard');
        $this->default_style = get_option('ai_magic_dalle_style', 'vivid');
    }

    /**
     * Generate an image from a prompt
     *
     * @since    1.0.8
     * @param    string    $prompt     Image description
     * @param    array     $options    Generation options
     * @return   array                 Response array
     */
    public function generateImage($prompt, $options = array())
    {
        if (empty($this->api_key)) {
            return array(
                'type' => 'error',
                'message' => __('OpenAI API Key is required for DALL-E image generation.', 'ai_magic')
            );
        }

        if (empty($prompt)) {
            return array(
                'type' => 'error',
                'message' => __('Image prompt is required.', 'ai_magic')
            );
        }

        // Merge options with defaults
        $size = isset($options['size']) ? $options['size'] : $this->default_size;
        $quality = isset($options['quality']) ? $options['quality'] : $this->default_quality;
        $style = isset($options['style']) ? $options['style'] : $this->default_style;
        $model = isset($options['model']) ? $options['model'] : $this->model;
        $n = isset($options['n']) ? min(absint($options['n']), 10) : 1;

        // Prepare request body
        $body = array(
            'model' => $model,
            'prompt' => $prompt,
            'n' => $n,
            'size' => $size
        );

        // DALL-E 3 specific options
        if ($model === 'dall-e-3') {
            $body['quality'] = $quality;
            $body['style'] = $style;
            $body['n'] = 1; // DALL-E 3 only supports n=1
        }

        // Make API request
        $response = wp_remote_post($this->api_url, array(
            'timeout' => 120,
            'headers' => array(
                'Authorization' => 'Bearer ' . $this->api_key,
                'Content-Type' => 'application/json'
            ),
            'body' => wp_json_encode($body)
        ));

        if (is_wp_error($response)) {
            return array(
                'type' => 'error',
                'message' => $response->get_error_message()
            );
        }

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

        if ($response_code !== 200) {
            $error_msg = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error';
            return array(
                'type' => 'error',
                'message' => 'DALL-E API Error: ' . $error_msg
            );
        }

        if (isset($data['data']) && !empty($data['data'])) {
            $images = array();
            foreach ($data['data'] as $image) {
                $images[] = array(
                    'url' => $image['url'],
                    'revised_prompt' => isset($image['revised_prompt']) ? $image['revised_prompt'] : $prompt
                );
            }

            return array(
                'type' => 'success',
                'data' => $images,
                'message' => __('Image generated successfully', 'ai_magic')
            );
        }

        return array(
            'type' => 'error',
            'message' => __('Failed to generate image', 'ai_magic')
        );
    }

    /**
     * Download image and save to WordPress Media Library
     *
     * @since    1.0.8
     * @param    string    $url         Image URL
     * @param    string    $filename    Desired filename
     * @param    int       $post_id     Optional post ID to attach to
     * @return   int|WP_Error           Attachment ID or error
     */
    public function saveToMediaLibrary($url, $filename = '', $post_id = 0)
    {
        if (empty($url)) {
            return new WP_Error('invalid_url', __('Invalid image URL', 'ai_magic'));
        }

        // Include required files
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
        require_once(ABSPATH . 'wp-admin/includes/image.php');

        // Download file to temp location
        $tmp_file = download_url($url);

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

        // Generate filename if not provided
        if (empty($filename)) {
            $filename = 'ai-magic-image-' . time() . '.png';
        }

        // Prepare file array
        $file_array = array(
            'name' => sanitize_file_name($filename),
            'tmp_name' => $tmp_file
        );

        // Upload to media library
        $attachment_id = media_handle_sideload($file_array, $post_id);

        // Clean up temp file
        if (file_exists($tmp_file)) {
            @unlink($tmp_file);
        }

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

        // Update attachment metadata
        update_post_meta($attachment_id, '_ai_magic_generated', true);
        update_post_meta($attachment_id, '_ai_magic_generator', 'dalle');

        return $attachment_id;
    }

    /**
     * Set as featured image for a post
     *
     * @since    1.0.8
     * @param    int    $post_id         Post ID
     * @param    int    $attachment_id   Attachment ID
     * @return   bool                    Success status
     */
    public function setAsFeaturedImage($post_id, $attachment_id)
    {
        if (!$post_id || !$attachment_id) {
            return false;
        }

        return set_post_thumbnail($post_id, $attachment_id);
    }

    /**
     * Generate image from post content/title and set as featured image
     *
     * @since    1.0.8
     * @param    int       $post_id    Post ID
     * @param    array     $options    Generation options
     * @return   array                 Response array
     */
    public function generateFeaturedImage($post_id, $options = array())
    {
        $post = get_post($post_id);
        if (!$post) {
            return array(
                'type' => 'error',
                'message' => __('Post not found', 'ai_magic')
            );
        }

        // Build prompt from title and content
        $title = $post->post_title;
        $content = wp_strip_all_tags($post->post_content);
        $excerpt = !empty($post->post_excerpt) ? $post->post_excerpt : wp_trim_words($content, 50);

        // Create image prompt
        $prompt = isset($options['prompt']) ? $options['prompt'] : '';
        
        if (empty($prompt)) {
            $prompt = sprintf(
                'Create a professional, high-quality featured image for a blog post titled "%s". The image should be visually appealing, relevant to the topic, and suitable for a website header. Style: modern, clean, professional. Topic summary: %s',
                $title,
                wp_trim_words($excerpt, 30)
            );
        }

        // Generate image
        $result = $this->generateImage($prompt, $options);

        if ($result['type'] !== 'success') {
            return $result;
        }

        // Download and save to media library
        $image_url = $result['data'][0]['url'];
        $filename = sanitize_title($title) . '-featured.png';

        $attachment_id = $this->saveToMediaLibrary($image_url, $filename, $post_id);

        if (is_wp_error($attachment_id)) {
            return array(
                'type' => 'error',
                'message' => $attachment_id->get_error_message()
            );
        }

        // Set as featured image
        $this->setAsFeaturedImage($post_id, $attachment_id);

        return array(
            'type' => 'success',
            'data' => array(
                'attachment_id' => $attachment_id,
                'url' => wp_get_attachment_url($attachment_id),
                'revised_prompt' => $result['data'][0]['revised_prompt']
            ),
            'message' => __('Featured image generated and set successfully', 'ai_magic')
        );
    }

    /**
     * Get available models
     *
     * @since    1.0.8
     * @return   array    List of models
     */
    public function getAvailableModels()
    {
        return array(
            array(
                'id' => 'dall-e-3',
                'name' => 'DALL-E 3',
                'description' => 'Latest model with best quality',
                'max_size' => '1792x1024',
                'supports_quality' => true,
                'supports_style' => true
            ),
            array(
                'id' => 'dall-e-2',
                'name' => 'DALL-E 2',
                'description' => 'Previous generation, faster and cheaper',
                'max_size' => '1024x1024',
                'supports_quality' => false,
                'supports_style' => false
            )
        );
    }

    /**
     * Get available sizes
     *
     * @since    1.0.8
     * @return   array    List of sizes
     */
    public function getAvailableSizes()
    {
        return array(
            'dall-e-3' => array(
                '1024x1024' => 'Square (1024×1024)',
                '1792x1024' => 'Landscape (1792×1024)',
                '1024x1792' => 'Portrait (1024×1792)'
            ),
            'dall-e-2' => array(
                '256x256' => 'Small (256×256)',
                '512x512' => 'Medium (512×512)',
                '1024x1024' => 'Large (1024×1024)'
            )
        );
    }

    /**
     * Get quality options (DALL-E 3 only)
     *
     * @since    1.0.8
     * @return   array    Quality options
     */
    public function getQualityOptions()
    {
        return array(
            'standard' => __('Standard', 'ai_magic'),
            'hd' => __('HD (Higher detail)', 'ai_magic')
        );
    }

    /**
     * Get style options (DALL-E 3 only)
     *
     * @since    1.0.8
     * @return   array    Style options
     */
    public function getStyleOptions()
    {
        return array(
            'vivid' => __('Vivid (Hyper-real and dramatic)', 'ai_magic'),
            'natural' => __('Natural (More natural, less hyper-real)', 'ai_magic')
        );
    }

    /**
     * Validate API key
     *
     * @since    1.0.8
     * @return   bool|WP_Error    True if valid, error otherwise
     */
    public function validateApiKey()
    {
        if (empty($this->api_key)) {
            return new WP_Error('missing_key', __('OpenAI API Key is missing', 'ai_magic'));
        }

        // Try to list models to validate key
        $response = wp_remote_get('https://api.openai.com/v1/models', array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $this->api_key
            ),
            'timeout' => 30
        ));

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

        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) {
            return new WP_Error('invalid_key', __('Invalid API Key', 'ai_magic'));
        }

        return true;
    }
}
