<?php
/**
 * AI Client Wrapper (Provider-Agnostic)
 *
 * @package AICG
 */

namespace AICG;

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

/**
 * Class Ai_Client
 *
 * Unified interface for executing AI prompts via OpenRouter or WP 7.0 Native AI Client.
 */
class Ai_Client
{
    /**
     * OpenRouter API instance
     */
    private $openrouter;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->openrouter = new Openrouter_Api();
    }

    /**
     * Get the active AI provider setting
     */
    public static function get_provider()
    {
        $provider = get_option('roidaico_ai_provider', 'openrouter');
        if ($provider === 'wp_ai_client' && !function_exists('wp_ai_client_prompt')) {
            return 'openrouter';
        }
        return $provider;
    }

    /**
     * Test connection to the active provider
     */
    public function test_connection($api_key = null)
    {
        if (self::get_provider() === 'wp_ai_client') {
            if (!function_exists('wp_ai_client_prompt')) {
                return new \WP_Error('not_supported', __('WordPress AI Client is not supported on this version of WordPress.', 'roidnet-ai-content-generator'));
            }
            if (function_exists('wp_get_connectors')) {
                $connectors = wp_get_connectors();
                if (empty($connectors)) {
                    return new \WP_Error('no_connectors', __('No AI connectors are configured. Please set them up in Settings > Connectors.', 'roidnet-ai-content-generator'));
                }
            }
            return true;
        }

        return $this->openrouter->test_connection($api_key);
    }

    /**
     * Get available models for setting or displaying
     */
    public function get_models($api_key = null)
    {
        if (self::get_provider() === 'wp_ai_client') {
            return array(
                array(
                    'id' => 'wp_ai_client_default',
                    'name' => __('Managed by WordPress (Provider-Agnostic)', 'roidnet-ai-content-generator'),
                    'context_length' => 0,
                    'pricing' => array(),
                )
            );
        }

        return $this->openrouter->get_models($api_key);
    }

    public function generate_keywords($topic, $count = 10, $language = '')
    {
        if (empty($language)) {
            $language = get_option('roidaico_default_language', 'en');
        }

        if (self::get_provider() === 'wp_ai_client') {
            $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
            );

            $schema = array(
                'type' => 'array',
                'items' => array(
                    'type' => 'string'
                )
            );

            $builder = wp_ai_client_prompt($prompt)
                ->using_system_instruction('You are an SEO expert that generates targeted keywords. Always respond with valid JSON arrays only.')
                ->as_json_response($schema);

            if (method_exists($builder, 'using_model_preference')) {
                $builder->using_model_preference('openai/gpt-4o-mini', 'claude-3-5-haiku', 'gemini-1.5-flash');
            }

            $response = $builder->generate_text();

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

            return self::parse_json_keywords($response);
        }

        return $this->openrouter->generate_keywords($topic, $count, $language);
    }

    /**
     * Generate content using the active provider
     */
    public function generate_content($keyword, $options = array())
    {
        if (self::get_provider() === 'wp_ai_client') {
            $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
            );

            $schema = array(
                'type' => 'object',
                'properties' => array(
                    'title' => array( 'type' => 'string' ),
                    'meta_description' => array( 'type' => 'string' ),
                    'content' => array( 'type' => 'string' ),
                    'excerpt' => array( 'type' => 'string' ),
                    'focus_keyword' => array( 'type' => 'string' ),
                    'featured_image_prompt' => array( 'type' => 'string' ),
                    'tags' => array(
                        'type' => 'array',
                        'items' => array( 'type' => 'string' )
                    )
                ),
                'required' => array( 'title', 'content', 'meta_description', 'excerpt', 'focus_keyword', 'featured_image_prompt', 'tags' )
            );

            $builder = wp_ai_client_prompt($prompt)
                ->using_system_instruction('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.')
                ->using_temperature(0.7)
                ->as_json_response($schema);

            if (method_exists($builder, 'using_model_preference')) {
                $builder->using_model_preference('openai/gpt-4o-mini', 'claude-3-5-haiku', 'gemini-1.5-flash');
            }

            $response = $builder->generate_text();

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

            return self::parse_json_article($response);
        }

        return $this->openrouter->generate_content($keyword, $options);
    }

    /**
     * Generate an image via the active provider (Pro feature)
     */
    public function generate_image($prompt)
    {
        if (self::get_provider() === 'wp_ai_client') {
            if (!function_exists('wp_ai_client_prompt')) {
                return new \WP_Error('not_supported', __('WordPress AI Client is not supported on this version of WordPress.', 'roidnet-ai-content-generator'));
            }

            $builder = wp_ai_client_prompt($prompt);
            
            $image_model = get_option('roidaico_ai_image_model', '');
            if (!empty($image_model) && method_exists($builder, 'using_model_preference')) {
                $builder->using_model_preference($image_model);
            }

            $image_file = $builder->generate_image();

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

            $data_uri = $image_file->getDataUri();

            if (preg_match('/^data:(image\/[a-z]+);base64,(.*)$/i', $data_uri, $matches)) {
                return base64_decode($matches[2]);
            }

            return new \WP_Error('invalid_image_data', __('Invalid image data received from WordPress AI Client.', 'roidnet-ai-content-generator'));
        }

        return $this->openrouter->generate_image($prompt);
    }

    /**
     * Get available image models
     */
    public function get_image_models($api_key = null)
    {
        if (self::get_provider() === 'wp_ai_client') {
            return array(
                array(
                    'id' => 'wp_ai_client_default',
                    'name' => __('Managed by WordPress (Provider-Agnostic)', 'roidnet-ai-content-generator'),
                    'price' => 'Free/Managed',
                )
            );
        }

        return $this->openrouter->get_image_models($api_key);
    }

    /**
     * Parse article JSON response robustly
     *
     * @param string $content
     * @return array|\WP_Error
     */
    public static function parse_json_article($content)
    {
        $json_str = trim($content);
        
        // Remove markdown backticks if present
        if (strpos($json_str, '```') === 0) {
            $json_str = preg_replace('/^```(?:json)?\s*/i', '', $json_str);
            $json_str = preg_replace('/\s*```$/', '', $json_str);
        }
        $json_str = trim($json_str);
        // [NEW FIX] Escape unescaped control characters to prevent json_decode failures
        $json_str = str_replace(array("\r\n", "\r", "\n", "\t"), array("\\n", "\\n", "\\n", "\\t"), $json_str);
        // Remove any remaining invalid control characters
        $json_str = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $json_str);
        
        $article = json_decode($json_str, true);
        
        if (!$article) {
            preg_match('/\{.*\}/s', $json_str, $matches);
            if (!empty($matches[0])) {
                $article = json_decode($matches[0], true);
            }
        }
        
        if (!is_array($article) || !isset($article['title']) || !isset($article['content'])) {
            error_log('AICG JSON Parse Failure. Error: ' . json_last_error_msg());
            error_log('Raw AI Response: ' . $content);
            return new \WP_Error(
                'parse_error', 
                sprintf(
                    __('Invalid article format. JSON Error: %s', 'roidnet-ai-content-generator'),
                    json_last_error_msg()
                )
            );
        }
        
        return $article;
    }

    /**
     * Parse keywords JSON response robustly
     *
     * @param string $content
     * @return array|\WP_Error
     */
    public static function parse_json_keywords($content)
    {
        $json_str = trim($content);
        if (strpos($json_str, '```') === 0) {
            $json_str = preg_replace('/^```(?:json)?\s*/i', '', $json_str);
            $json_str = preg_replace('/\s*```$/', '', $json_str);
        }
        $json_str = trim($json_str);
        // [NEW FIX] Escape unescaped control characters to prevent json_decode failures
        $json_str = str_replace(array("\r\n", "\r", "\n", "\t"), array("\\n", "\\n", "\\n", "\\t"), $json_str);
        $json_str = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $json_str);
        
        $keywords = json_decode($json_str, true);
        if (!$keywords) {
            preg_match('/\[.*\]/s', $json_str, $matches);
            if (!empty($matches[0])) {
                $keywords = json_decode($matches[0], true);
            }
        }
        
        if (!is_array($keywords)) {
            error_log('AICG Keywords JSON Parse Failure. Error: ' . json_last_error_msg());
            error_log('Raw AI Response: ' . $content);
            return new \WP_Error(
                'parse_error',
                sprintf(
                    __('Invalid keywords format. JSON Error: %s', 'roidnet-ai-content-generator'),
                    json_last_error_msg()
                )
            );
        }
        
        return array_map('sanitize_text_field', $keywords);
    }

    /**
     * Translate keyword using the active provider
     */
    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
        );

        if (self::get_provider() === 'wp_ai_client') {
            if (!function_exists('wp_ai_client_prompt')) {
                return new \WP_Error('not_supported', __('WordPress AI Client is not supported.', 'roidnet-ai-content-generator'));
            }
            
            $builder = wp_ai_client_prompt($prompt)
                ->using_system_instruction('You are a professional SEO translator. Translate keywords accurately for SEO, returning only the translated text.')
                ->using_temperature(0.3);
                
            if (method_exists($builder, 'using_model_preference')) {
                $builder->using_model_preference('openai/gpt-4o-mini', 'claude-3-5-haiku', 'gemini-1.5-flash');
            }
            
            $response = $builder->generate_text();
            if (is_wp_error($response)) {
                return $response;
            }
            return trim($response, " \t\n\r\0\x0B\"'");
        }

        return $this->openrouter->translate_keyword($keyword, $target_lang);
    }
}
