<?php
/**
 * OpenRouter API Handler
 *
 * @package AIContentGenerator
 */

namespace AICG;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Handles all OpenRouter API communications
 */
class Openrouter_Api
{

    /**
     * API base URL
     */
    const API_URL = 'https://openrouter.ai/api/v1';

    /**
     * Get API key
     */
    private function get_api_key()
    {
        return get_option('roidaico_openrouter_api_key', '');
    }

    /**
     * Get selected model
     */
    private function get_model()
    {
        return get_option('roidaico_openrouter_model', 'openai/gpt-4o-mini');
    }

    /**
     * Make API request
     */
    private function request($endpoint, $data = array(), $method = 'POST', $api_key = null)
    {
        $key = $api_key ?: $this->get_api_key();

        if (empty($key)) {
            return new \WP_Error('no_api_key', __('OpenRouter API key is not configured.', 'roidnet-ai-content-generator'));
        }

        $args = array(
            'method' => $method,
            'timeout' => 300,
            'headers' => array(
                'Authorization' => 'Bearer ' . $key,
                'Content-Type' => 'application/json',
                'HTTP-Referer' => home_url(),
                'X-Title' => get_bloginfo('name'),
            ),
        );

        if (!empty($data) && $method !== 'GET') {
            $args['body'] = wp_json_encode($data);
        }

        $response = wp_remote_request(self::API_URL . $endpoint, $args);

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

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

        if (wp_remote_retrieve_response_code($response) !== 200) {
            $error_message = isset($decoded['error']['message'])
                ? $decoded['error']['message']
                : __('Unknown API error.', 'roidnet-ai-content-generator');
            return new \WP_Error('api_error', $error_message);
        }

        return $decoded;
    }

    /**
     * Test API connection
     */
    public function test_connection($api_key = null)
    {
        $result = $this->request('/models', array(), 'GET', $api_key);

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

        return true;
    }

    /**
     * Get available models
     */
    public function get_models($api_key = null)
    {
        $cached = get_transient('roidaico_openrouter_models');

        if ($cached !== false && empty($api_key)) {
            return $cached;
        }

        $result = $this->request('/models', array(), 'GET', $api_key);

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

        $models = array();
        if (isset($result['data']) && is_array($result['data'])) {
            foreach ($result['data'] as $model) {
                // Filter for text generation models
                if (isset($model['id'])) {
                    $models[] = array(
                        'id' => $model['id'],
                        'name' => isset($model['name']) ? $model['name'] : $model['id'],
                        'context_length' => isset($model['context_length']) ? $model['context_length'] : 0,
                        'pricing' => isset($model['pricing']) ? $model['pricing'] : array(),
                    );
                }
            }
        }

        // Cache for 1 hour
        set_transient('roidaico_openrouter_models', $models, HOUR_IN_SECONDS);

        return $models;
    }

    /**
     * Generate keywords for a topic
     */
    public function generate_keywords($topic, $count = 10, $language = '')
    {
        if (empty($language)) {
            $language = get_option('roidaico_default_language', 'en');
        }

        $prompt = sprintf(
            'Generate %d unique, SEO-optimized keywords related to the topic: "%s". 
            The keywords should be suitable for blog article titles.
            Return ONLY a JSON array of keywords, no explanations.
            Language: %s
            Example format: ["keyword 1", "keyword 2", "keyword 3"]',
            $count,
            $topic,
            $language
        );

        $data = array(
            'model' => $this->get_model(),
            'messages' => array(
                array(
                    'role' => 'system',
                    'content' => 'You are an SEO expert that generates targeted keywords. Always respond with valid JSON arrays only.',
                ),
                array(
                    'role' => 'user',
                    'content' => $prompt,
                ),
            ),
            'temperature' => 0.7,
            'max_tokens' => 1000,
        );

        $result = $this->request('/chat/completions', $data);

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

        if (!isset($result['choices'][0]['message']['content'])) {
            return new \WP_Error('invalid_response', __('Invalid API response.', 'roidnet-ai-content-generator'));
        }

        return Ai_Client::parse_json_keywords($result['choices'][0]['message']['content']);
    }

    /**
     * Generate article content
     */
    public function generate_content($keyword, $options = array())
    {
        $defaults = array(
            'tone' => get_option('roidaico_default_tone', 'professional'),
            'length' => get_option('roidaico_default_length', 'medium'),
            'language' => get_option('roidaico_default_language', 'en'),
            'internal_links' => array(),
            'custom_instructions' => get_option('roidaico_custom_instructions', ''),
            'images_count' => get_option('roidaico_images_count', 2),
        );

        $options = wp_parse_args($options, $defaults);

        // Determine word count based on length
        $word_counts = array(
            'short'  => 600,
            'medium' => 1200,
            'long'   => 2500,
        );
        $target_words = isset($word_counts[$options['length']]) ? $word_counts[$options['length']] : 1200;

        // Build internal links instruction
        $links_instruction = '';
        if (!empty($options['internal_links'])) {
            $links_instruction = "\n\nInclude these internal links naturally within the content:\n";
            foreach ($options['internal_links'] as $link) {
                $links_instruction .= sprintf('- [%s](%s)', $link['title'], $link['url']) . "\n";
            }
        }

        // Build custom instructions section
        $custom_instructions = '';
        if (!empty($options['custom_instructions'])) {
            $custom_instructions = "\n\nAdditional Instructions:\n" . $options['custom_instructions'];
        }

        // Build images instruction
        $images_instruction = '';
        $images_count = intval($options['images_count']);
        if ($images_count > 0) {
            $images_instruction = sprintf(
                "\n\nImage Placeholders: Include %d image placeholder(s) in the content using this format: [IMAGE: visual keywords in English]. The description inside the bracket MUST be in English and consists of 3-5 visual keywords ONLY for a stock photo search (e.g., 'istanbul blue mosque' instead of a full sentence). Place them naturally throughout the article.",
                $images_count
            );
        }

        $length_instruction = '';
        if ($options['length'] === 'long') {
            $length_instruction = "\n- EXTREMELY IMPORTANT: This is a LONG-FORM article. Provide deep, exhaustive coverage with many subsections, detailed explanations, and comprehensive analysis for every point. Ensure the formatting includes multiple subheadings to organize the vast amount of information.";
        }

        $prompt = sprintf(
            'Write a comprehensive, SEO-optimized article about: "%s"

Requirements:
- Tone: %s
- Minimum word count: at least %d words (be very detailed)
- Language: %s
- DO NOT include the H1 title inside the "content" field (it is handled separately)
- Start content directly with an introduction starting with H2 or a paragraph
- Use proper heading structure (H2, H3, H4)
- Include an introduction and conclusion
- Make content engaging and informative
- Optimize for the focus keyword%s
- Output JSON format directly, no other explanation or code blocks.
%s%s%s

Return the article in this JSON format:
{
    "title": "Article title here",
    "meta_description": "SEO meta description (150-160 characters)",
    "content": "Full HTML article content here",
    "excerpt": "Short excerpt for preview",
    "focus_keyword": "main focus keyword",
    "featured_image_prompt": "A short, 3-5 word English search query for Pexels (e.g., \'hair transplant clinic\')",
    "tags": ["tag1", "tag2", "tag3"]
}',
            $keyword,
            $options['tone'],
            $target_words,
            $options['language'],
            $length_instruction,
            $links_instruction,
            $custom_instructions,
            $images_instruction
        );

        $data = array(
            'model' => $this->get_model(),
            'messages' => array(
                array(
                    'role' => 'system',
                    'content' => 'You are an expert content writer and SEO specialist. Write high-quality, engaging articles that rank well in search engines. Always respond with valid JSON only.',
                ),
                array(
                    'role' => 'user',
                    'content' => $prompt,
                ),
            ),
            'temperature' => 0.7,
            'max_tokens' => 8000,
        );

        $result = $this->request('/chat/completions', $data);

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

        if (!isset($result['choices'][0]['message']['content'])) {
            return new \WP_Error('invalid_response', __('Invalid API response.', 'roidnet-ai-content-generator'));
        }

        return Ai_Client::parse_json_article($result['choices'][0]['message']['content']);
    }

    /**
     * Generate an image via OpenRouter API (Pro feature)
     */
    public function generate_image($prompt, $model = null)
    {
        if (empty($model)) {
            $model = get_option('roidaico_ai_image_model', 'google/gemini-2.5-flash-image');
        }

        // Fallback for deprecated model
        if ($model === 'black-forest-labs/flux-1-schnell') {
            $model = 'google/gemini-2.5-flash-image';
        }

        $data = array(
            'model' => $model,
            'messages' => array(
                array(
                    'role' => 'user',
                    'content' => $prompt,
                ),
            ),
            'modalities' => array('image'),
        );

        $result = $this->request('/chat/completions', $data);

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

        $image_data_uri = '';

        // Check for standard OpenRouter / OpenAI structure for generated image modality
        if (!empty($result['choices'][0]['message']['images'][0]['image_url']['url'])) {
            $image_data_uri = $result['choices'][0]['message']['images'][0]['image_url']['url'];
        } elseif (!empty($result['choices'][0]['message']['content'])) {
            $image_data_uri = trim($result['choices'][0]['message']['content']);
        }

        if (empty($image_data_uri)) {
            return new \WP_Error('invalid_response', __('Invalid API response for image generation.', 'roidnet-ai-content-generator'));
        }

        // Extract base64 data
        if (preg_match('/^data:(image\/[a-z0-9]+);base64,(.*)$/is', $image_data_uri, $matches)) {
            return base64_decode(preg_replace('/\s+/', '', $matches[2]));
        }

        // Check if it's a URL
        if (filter_var($image_data_uri, FILTER_VALIDATE_URL)) {
            $image_response = wp_safe_remote_get($image_data_uri, array('timeout' => 60));
            if (!is_wp_error($image_response) && wp_remote_retrieve_response_code($image_response) === 200) {
                return wp_remote_retrieve_body($image_response);
            }
        }

        // Just in case it returned it without prefix
        $decoded = base64_decode($image_data_uri, true);
        if ($decoded !== false && !empty($decoded)) {
            return $decoded;
        }

        return new \WP_Error('parse_error', __('Could not parse image from response.', 'roidnet-ai-content-generator'));
    }

    /**
     * Get available image models from OpenRouter
     */
    public function get_image_models($api_key = null)
    {
        $cached = get_transient('roidaico_openrouter_image_models');

        if ($cached !== false && empty($api_key)) {
            return $cached;
        }

        $result = $this->request('/models?output_modalities=image', array(), 'GET', $api_key);

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

        $models = array();
        if (isset($result['data']) && is_array($result['data'])) {
            foreach ($result['data'] as $model) {
                $is_image_model = false;
                
                // Check architecture output_modalities
                if (isset($model['architecture']['output_modalities']) && is_array($model['architecture']['output_modalities'])) {
                    if (in_array('image', $model['architecture']['output_modalities'])) {
                        $is_image_model = true;
                    }
                }
                
                if ($is_image_model && isset($model['id'])) {
                    $price = '';
                    $flat_prices = array();
                    
                    if (isset($model['pricing']['image'])) {
                        $img_price = floatval($model['pricing']['image']);
                        if ($img_price >= 0.001) {
                            $flat_prices[] = $img_price;
                        }
                    }
                    if (isset($model['pricing']['request'])) {
                        $req_price = floatval($model['pricing']['request']);
                        if ($req_price >= 0.001) {
                            $flat_prices[] = $req_price;
                        }
                    }
                    
                    if (!empty($flat_prices)) {
                        $max_price = max($flat_prices);
                        $price = '$' . rtrim(rtrim(sprintf('%.4f', $max_price), '0'), '.');
                    }
                    
                    $models[] = array(
                        'id' => $model['id'],
                        'name' => isset($model['name']) ? $model['name'] : $model['id'],
                        'price' => $price,
                    );
                }
            }
        }

        // If no image models found, return a default list
        if (empty($models)) {
            $models = array(
                array(
                    'id' => 'google/gemini-2.5-flash-image',
                    'name' => 'Google: Gemini 2.5 Flash Image',
                    'price' => '$0.03',
                ),
                array(
                    'id' => 'openai/gpt-5-image',
                    'name' => 'OpenAI: GPT-5 Image',
                    'price' => '$0.04',
                ),
            );
        }

        // Cache for 1 hour
        set_transient('roidaico_openrouter_image_models', $models, HOUR_IN_SECONDS);

        return $models;
    }

    /**
     * Translate keyword for SEO targeting
     */
    public function translate_keyword($keyword, $target_lang)
    {
        $prompt = sprintf(
            "Translate this SEO keyword: '%s' into '%s' for search engine optimization (SEO) targeting. Return ONLY the translated keyword text itself. Do not include quotes, markdown formatting, explanations, or any other text.",
            $keyword,
            $target_lang
        );

        $data = array(
            'model' => $this->get_model(),
            'messages' => array(
                array(
                    'role' => 'system',
                    'content' => 'You are a professional SEO translator. Translate keywords accurately for SEO, returning only the translated text.',
                ),
                array(
                    'role' => 'user',
                    'content' => $prompt,
                ),
            ),
            'temperature' => 0.3,
            'max_tokens' => 150,
        );

        $result = $this->request('/chat/completions', $data);

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

        if (!isset($result['choices'][0]['message']['content'])) {
            return new \WP_Error('invalid_response', __('Invalid API response.', 'roidnet-ai-content-generator'));
        }

        return trim($result['choices'][0]['message']['content'], " \t\n\r\0\x0B\"'");
    }
}
