<?php

/**
 * Anthropic (Claude) Provider Class
 *
 * Handles all Anthropic API interactions for content generation
 *
 * @link       https://insya.com/ai-magic
 * @since      1.0.7
 *
 * @package    Ai_Magic
 * @subpackage Ai_Magic/admin
 */

if (!class_exists('AI_Magic_OpenAI')) {
    require_once plugin_dir_path(__FILE__) . 'class-ai-magic-openai.php';
}

class AI_Magic_Anthropic implements AI_Magic_Provider_Interface
{
    /**
     * API Key for Anthropic
     *
     * @var string
     */
    private $api_key;

    /**
     * Model to use
     *
     * @var string
     */
    private $model;

    /**
     * Maximum tokens to generate
     *
     * @var int
     */
    private $max_tokens;

    /**
     * Temperature setting
     *
     * @var float
     */
    private $temperature;

    /**
     * Provider ID
     *
     * @var string
     */
    private $provider_id = 'anthropic';

    /**
     * Constructor - Initialize Anthropic provider with settings
     *
     * @since    1.0.7
     */
    public function __construct()
    {
        if (!interface_exists('AI_Magic_Provider_Interface')) {
            require_once plugin_dir_path(dirname(__FILE__)) . 'includes/interface-ai-magic-provider.php';
        }

        // Load provider-specific settings
        $this->load_provider_settings();
    }

    /**
     * Load provider-specific settings from database
     *
     * @since    1.0.8
     */
    private function load_provider_settings()
    {
        $this->api_key = get_option('ai_magic_api_key_anthropic', '');
        $this->model = get_option('ai_magic_anthropic_model', 'claude-3-5-sonnet-20241022');
        if ($this->model === 'custom') {
            $this->model = get_option('ai_magic_anthropic_custom_model', '');
        }
        $this->max_tokens = (int) get_option('ai_magic_anthropic_max_tokens', get_option('ai_magic_max_tokens', 4096));
        $this->temperature = (float) get_option('ai_magic_anthropic_temperature', get_option('ai_magic_temperature', 0.5));
    }

    /**
     * Get current provider settings
     *
     * @since    1.0.8
     * @return   array    Current settings
     */
    public function get_settings()
    {
        return array(
            'model' => $this->model,
            'max_tokens' => $this->max_tokens,
            'temperature' => $this->temperature
        );
    }

    /**
     * Build the prompt string based on settings and input
     * 
     * @param string $title_text The user input/title
     * @param array $overrides Optional overrides for settings
     * @return string The constructed prompt
     */
    public function buildPrompt($title_text, $overrides = array())
    {
        $openai = new AI_Magic_OpenAI();
        return $openai->buildPrompt($title_text, $overrides);
    }

    /**
     * Parse structured content from AI response
     * 
     * @param string $text The raw text from AI
     * @return object Parsed data object
     */
    public function parseContent($text)
    {
        $fields = array("title", "slug", "excerpt", "tags", "content");
        $parsed_data = array();

        foreach ($fields as $field) {
            preg_match("/#\s*$field\s*:\s*(.*?)(?=#\s*\w+\s*:|$)/si", $text, $matches);
            $parsed_data[$field] = isset($matches[1]) ? trim($matches[1]) : "";
        }

        if (empty($parsed_data['content']) && empty($parsed_data['title'])) {
            $parsed_data['content'] = $text;
        }

        return (object) $parsed_data;
    }

    /**
     * Generate text using Anthropic API
     *
     * @since    1.0.7
     * @param    string    $prompt    The prompt to send
     * @return   array                Response array
     */
    public function generateText($title_text)
    {
        if (empty($this->api_key)) {
            return array(
                'type' => 'error',
                'message' => __('Anthropic API Key is missing. Please configure it in settings.', 'ai_magic')
            );
        }

        $start_time = microtime(true);
        $prompt = $this->buildPrompt($title_text);

        $url = 'https://api.anthropic.com/v1/messages';
        $headers = array(
            'x-api-key' => $this->api_key,
            'anthropic-version' => '2023-06-01',
            'content-type' => 'application/json'
        );

        $body = array(
            'model' => $this->model,
            'max_tokens' => $this->max_tokens,
            'temperature' => $this->temperature,
            'messages' => array(
                array('role' => 'user', 'content' => $prompt)
            )
        );

        $args = array(
            'headers' => $headers,
            'body' => json_encode($body),
            'timeout' => 60
        );

        $response = wp_remote_post($url, $args);

        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' => 'Anthropic Error: ' . $error_msg);
        }

        if (isset($data['content'][0]['text'])) {
            $generated_text = $data['content'][0]['text'];
            $content = $this->parseContent($generated_text);

            $post_data = array(
                'post_title' => wp_strip_all_tags($content->title),
                'post_excerpt' => $content->excerpt,
                'post_content' => $content->content,
                'post_name' => $content->slug,
                'post_tags' => $content->tags,
                'post_status' => 'publish',
                'post_type' => 'ai_magic_logs',
                'post_author' => get_current_user_id()
            );

            $post_id = wp_insert_post($post_data);
            $end_time = microtime(true);
            $duration = ($end_time - $start_time) * 1000;

            update_post_meta($post_id, 'duration', $duration);
            update_post_meta($post_id, 'prompt', $title_text);
            update_post_meta($post_id, 'tags', $content->tags);
            update_post_meta($post_id, 'model', $data['model']);

            return array(
                'type' => 'success',
                'message' => 'Success',
                'data' => $post_data,
                'raw_text' => $generated_text
            );
        }

        return array('type' => 'error', 'message' => 'Invalid response from Anthropic');
    }

    /**
     * Generate SEO meta description
     *
     * @param string $title Post title
     * @param string $content Post content
     * @param array $keywords Focus keywords
     * @return array Response
     */
    public function generateMetaDescription($title, $content = '', $keywords = array())
    {
        $keyword_text = !empty($keywords) ? implode(', ', $keywords) : '';
        $prompt = "Write a compelling SEO meta description for an article titled \"$title\".";
        if (!empty($content)) {
            $content_preview = substr(strip_tags($content), 0, 500);
            $prompt .= " The article is about: $content_preview";
        }
        if (!empty($keyword_text)) {
            $prompt .= " Include these keywords naturally: $keyword_text.";
        }
        $prompt .= " The meta description must be between 150-160 characters, engaging, and encourage clicks. Return only the meta description text, nothing else.";

        $response = $this->generateSimpleText($prompt);
        if ($response['type'] === 'success') {
            $response['length'] = strlen($response['data']);
        }
        return $response;
    }

    /**
     * Generate focus keywords from content
     *
     * @param string $content Post content
     * @param int $count Number of keywords to generate
     * @return array Response
     */
    public function generateFocusKeywords($content, $count = 5)
    {
        $content_preview = substr(strip_tags($content), 0, 1000);
        $prompt = "Analyze this content and extract the $count most important SEO keywords or key phrases. Return only a comma-separated list of keywords, nothing else:\n\n$content_preview";

        $response = $this->generateSimpleText($prompt);
        if ($response['type'] === 'success') {
            $keywords = array_map('trim', explode(',', $response['data']));
            $response['data'] = array_filter($keywords);
        }
        return $response;
    }

    /**
     * Internal helper to generate a simple text response without structured parsing
     * 
     * @param string $prompt
     * @return array
     */
    private function generateSimpleText($prompt)
    {
        if (empty($this->api_key)) {
            return array('type' => 'error', 'message' => 'API Key missing');
        }

        $url = 'https://api.anthropic.com/v1/messages';
        $body = array(
            'model' => $this->model,
            'max_tokens' => 200,
            'temperature' => 0.7,
            'messages' => array(array('role' => 'user', 'content' => $prompt))
        );

        $response = wp_remote_post($url, array(
            'headers' => array(
                'x-api-key' => $this->api_key,
                'anthropic-version' => '2023-06-01',
                'content-type' => 'application/json'
            ),
            'body' => json_encode($body),
            'timeout' => 30
        ));

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

        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (isset($data['content'][0]['text'])) {
            return array(
                'type' => 'success',
                'data' => trim($data['content'][0]['text'])
            );
        }

        return array('type' => 'error', 'message' => 'Invalid response');
    }

    public function getModels()
    {
        // Anthropic doesn't have a public models endpoint that returns a list like OpenAI
        // So we return a static list of known models (Updated December 2025)
        return [
            ['id' => 'claude-4-5-opus', 'name' => 'Claude 4.5 Opus'],
            ['id' => 'claude-3-5-sonnet-20241022', 'name' => 'Claude 3.5 Sonnet'],
            ['id' => 'claude-3-5-haiku-20241022', 'name' => 'Claude 3.5 Haiku'],
            ['id' => 'claude-3-opus-20240229', 'name' => 'Claude 3 Opus'],
            ['id' => 'claude-3-sonnet-20240229', 'name' => 'Claude 3 Sonnet'],
            ['id' => 'claude-3-haiku-20240307', 'name' => 'Claude 3 Haiku'],
        ];
    }

    public function validateApiKey()
    {
        if (empty($this->api_key)) {
            return new WP_Error('missing_key', __('API Key is missing', 'ai_magic'));
        }
        // No easy validation endpoint without making a generation request
        return true;
    }
}
