<?php
/**
 * OpenRouter API Handler
 *
 * @package HDSofT\AISummary
 */

namespace HDSofT\AISummary;

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

/**
 * Robustly parses LLM "JSON" that may include illegal control characters.
 *
 * @param string $raw Raw response content.
 * @return array
 * @throws \JsonException|\RuntimeException
 */
function hdsoft_parse_llm_json( $raw ) {
    if ( preg_match( '/\{.*\}/s', $raw, $m ) ) {
        $json = $m[0];
    } else {
        throw new \RuntimeException( 'No JSON object found in response.' );
    }

    $json = preg_replace( '/^\xEF\xBB\xBF/', '', $json );
    $json = str_replace( array( "\r\n", "\r" ), "\n", $json );

    $json = preg_replace_callback( '/"(?:[^"\\\\]|\\\\.)*"/s', function ( $m ) {
        $s = $m[0];
        $s = preg_replace( '/[\x00-\x09\x0B-\x0C\x0E-\x1F]/', '\\n', $s );
        return $s;
    }, $json );

    if ( ! mb_check_encoding( $json, 'UTF-8' ) ) {
        $json = mb_convert_encoding( $json, 'UTF-8', 'auto' );
    }

    return json_decode( $json, true, 512, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE );
}

/**
 * OpenRouter API Handler Class
 */
class OpenRouter {

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

    /**
     * Default model
     */
    const DEFAULT_MODEL = 'anthropic/claude-3.5-sonnet';

    /**
     * API timeout in seconds
     */
    const API_TIMEOUT = 30;

    /**
     * Get API key
     *
     * @return string|false
     */
    private function get_api_key() {
        $api_key = get_option( 'hdsoft_ai_summary_openrouter_api_key' );
        return ! empty( $api_key ) ? $api_key : false;
    }

    /**
     * Get plugin settings
     *
     * @return array
     */
    private function get_settings() {
        $defaults = array(
            'model_name'     => self::DEFAULT_MODEL,
            'max_tokens'     => 300,
            'prompt_style'   => 'narrative',
            'summary_title'  => 'Summary',
        );

        $settings = get_option( 'hdsoft_ai_summary_settings', array() );
        return wp_parse_args( $settings, $defaults );
    }

    /**
     * Test API connection
     *
     * @return array|WP_Error
     */
    public function test_connection() {
        $api_key = $this->get_api_key();
        
        if ( ! $api_key ) {
            return new \WP_Error( 'no_api_key', __( 'OpenRouter API key is not configured.', 'hd-soft-ai-summary' ) );
        }

        // Validate API key format
        if ( ! $this->validate_api_key_format( $api_key ) ) {
            return new \WP_Error( 'invalid_key_format', __( 'Invalid API key format. OpenRouter keys should start with "sk-or-".', 'hd-soft-ai-summary' ) );
        }

        // Test with a simple request to get models
        $response = $this->make_request( 'GET', '/models' );

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

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

        // Check for invalid JSON response
        if ( ! $data ) {
            return new \WP_Error( 'invalid_json', __( 'Invalid JSON response from OpenRouter API.', 'hd-soft-ai-summary' ) );
        }

        // Check for API-level errors (even with 200 status)
        if ( isset( $data['error'] ) ) {
            $error_message = isset( $data['error']['message'] ) ? $data['error']['message'] : __( 'Unknown API error.', 'hd-soft-ai-summary' );
            
            // Specific handling for authentication errors
            if ( isset( $data['error']['code'] ) ) {
                $error_code = $data['error']['code'];
                if ( in_array( $error_code, array( 'invalid_api_key', 'authentication_failed', 'unauthorized' ), true ) ) {
                    return new \WP_Error( 'auth_error', __( 'Authentication failed: Invalid API key.', 'hd-soft-ai-summary' ) );
                }
            }
            
            return new \WP_Error( 'api_error', $error_message );
        }

        // Check for missing or empty data
        if ( ! isset( $data['data'] ) ) {
            return new \WP_Error( 'invalid_response', __( 'Invalid response structure from OpenRouter API.', 'hd-soft-ai-summary' ) );
        }

        if ( ! is_array( $data['data'] ) || empty( $data['data'] ) ) {
            return new \WP_Error( 'no_models', __( 'No models available. This may indicate an authentication issue.', 'hd-soft-ai-summary' ) );
        }

        // Find current model info
        $settings = $this->get_settings();
        $current_model = $settings['model_name'];
        $model_info = null;

        foreach ( $data['data'] as $model ) {
            if ( isset( $model['id'] ) && $model['id'] === $current_model ) {
                $model_info = $model;
                break;
            }
        }

        return array(
            'success'      => true,
            'model_info'   => $model_info,
            'total_models' => count( $data['data'] ),
        );
    }

    /**
     * Generate summary for content
     *
     * @param string $content Content to summarize.
     * @return string|WP_Error
     */
    public function generate_summary( $content ) {
        $api_key = $this->get_api_key();
        
        if ( ! $api_key ) {
            return new \WP_Error( 'no_api_key', __( 'OpenRouter API key is not configured.', 'hd-soft-ai-summary' ) );
        }

        if ( empty( $content ) ) {
            return new \WP_Error( 'empty_content', __( 'Content is empty.', 'hd-soft-ai-summary' ) );
        }

        $settings = $this->get_settings();
        
        // Prepare the prompt
        $prompt = $this->build_prompt( $content );

        // DEBUG: used prompt (verbatim)
        if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Prompt style: ' . ( $settings['prompt_style'] ?? 'n/a' ) . ', model: ' . ( $settings['model_name'] ?? 'n/a' ) . ', max_tokens: ' . ( $settings['max_tokens'] ?? 'n/a' ) );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Prompt Length: ' . strlen( $prompt ) . ', SHA1: ' . sha1( $prompt ) );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Used Prompt: ' . $prompt );
        }
        
        // Prepare API parameters
        $api_params = array(
            'model' => $settings['model_name'],
            'messages' => array(
                array(
                    'role'    => 'user',
                    'content' => $prompt,
                ),
            ),
            'max_tokens' => intval( $settings['max_tokens'] ),
            'temperature' => 0.2,
            'top_p' => 1,
            'frequency_penalty' => 0,
            'presence_penalty' => 0,
        );


        // Make API request
        $response = $this->make_request( 'POST', '/chat/completions', $api_params );

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

        $body = wp_remote_retrieve_body( $response );
        $response_code = wp_remote_retrieve_response_code( $response );
        $headers = wp_remote_retrieve_headers( $response );
        
        if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - HTTP Response Code: ' . $response_code );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Response Headers: ' . json_encode( $headers ) );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Response Body Length: ' . strlen( $body ) );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - Full Response Body (first 1000 chars): ' . substr( $body, 0, 1000 ) );
        }
        
        $data = json_decode( $body, true );

        if ( ! $data ) {
            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                error_log( 'HD SofT AI Summary ERROR - Failed to decode outer JSON. Body: ' . substr( $body, 0, 500 ) );
            }
            return new \WP_Error( 'invalid_json', __( 'Invalid JSON response from OpenRouter API.', 'hd-soft-ai-summary' ) );
        }

        if ( isset( $data['error'] ) ) {
            $error_message = isset( $data['error']['message'] ) ? $data['error']['message'] : __( 'Unknown API error.', 'hd-soft-ai-summary' );
            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                error_log( 'HD SofT AI Summary ERROR - API Error: ' . $error_message );
            }
            return new \WP_Error( 'api_error', $error_message );
        }

        if ( ! isset( $data['choices'][0]['message']['content'] ) ) {
            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                error_log( 'HD SofT AI Summary ERROR - No content in choices. Full data: ' . json_encode( $data ) );
            }
            return new \WP_Error( 'no_content', __( 'No content in API response.', 'hd-soft-ai-summary' ) );
        }

        // Check finish_reason for truncation
        $finish_reason = $data['choices'][0]['finish_reason'] ?? '';
        $native_finish_reason = $data['choices'][0]['native_finish_reason'] ?? '';

        if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - finish_reason: ' . $finish_reason . ', native_finish_reason: ' . $native_finish_reason );
        }

        if ( $finish_reason === 'length' || $native_finish_reason === 'length' ) {
            return new \WP_Error(
                'ai_output_truncated',
                __( 'AI output was cut off due to length limit. Reduce summary length or increase max_tokens.', 'hd-soft-ai-summary' )
            );
        }

        $response_content = trim( $data['choices'][0]['message']['content'] );
        
        if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - AI Response Content Length: ' . strlen( $response_content ) );
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( 'HD SofT AI Summary DEBUG - AI Response Content (full): ' . $response_content );
        }
        
        if ( empty( $response_content ) ) {
            return new \WP_Error( 'empty_summary', __( 'Generated summary is empty.', 'hd-soft-ai-summary' ) );
        }

        try {
            $json_data = hdsoft_parse_llm_json( $response_content );
            
            if ( is_array( $json_data ) && 
                 isset( $json_data['title'], $json_data['summary'] ) &&
                 ! empty( $json_data['summary'] ) ) {
                return array(
                    'title'   => sanitize_text_field( $json_data['title'] ),
                    'summary' => wp_kses_post( $json_data['summary'] ),
                );
            } else {
                if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                    error_log( 'HD SofT AI Summary ERROR - Missing title/summary in parsed JSON: ' . json_encode( $json_data ) );
                }
                return new \WP_Error( 'invalid_structure', __( 'JSON missing required fields.', 'hd-soft-ai-summary' ) );
            }
        } catch ( \Throwable $e ) {
            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                error_log( 'HD SofT AI Summary ERROR - JSON Parse Exception: ' . $e->getMessage() );
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                error_log( 'HD SofT AI Summary ERROR - Raw Response: ' . $response_content );
            }
            
            return new \WP_Error( 
                'invalid_json_response', 
                __( 'AI response was incomplete or malformed. Please try again.', 'hd-soft-ai-summary' )
            );
        }
    }

    /**
     * Build prompt for summary generation
     *
     * @param string $content Content to summarize.
     * @return string
     */
    private function build_prompt( $content ) {
        $settings = $this->get_settings();
        $max_tokens = intval( $settings['max_tokens'] );
        $prompt_style = isset( $settings['prompt_style'] ) ? $settings['prompt_style'] : 'narrative';
        
        // Get custom title label, fallback to 'Summary' if empty
        $title_label = trim( $settings['summary_title'] ?? '' );
        if ( empty( $title_label ) ) {
            $title_label = 'Summary';
        }
        
        $max_words = min( 80, max( 30, intval( $max_tokens * 0.3 ) ) );
        
        switch ( $prompt_style ) {
            case 'narrative':
                $template = "Please provide a concise summary of the following content.\n\nReturn only valid JSON. The summary must be a single paragraph without line breaks or numbering.\n\n{\n  \"title\": \"[word for '{title_label}' in the same language as the content]\",\n  \"summary\": \"[2-3 short sentences, maximum {max_words} words, in the same language as the content]\"\n}\n\n{content}";
                break;
                
            case 'structured':
                $template = "Please provide a concise summary of the following content.\n\nReturn only valid JSON. The summary must be a single paragraph without line breaks or numbering.\n\n{\n  \"title\": \"[word for '{title_label}' in the same language as the content]\",\n  \"summary\": \"[3 key facts as flowing text, maximum {max_words} words, in the same language as the content]\"\n}\n\n{content}";
                break;
                
            case 'executive':
                $template = "Please provide a concise summary of the following content.\n\nReturn only valid JSON. The summary must be a single paragraph without line breaks or numbering.\n\n{\n  \"title\": \"[word for '{title_label}' in the same language as the content]\",\n  \"summary\": \"[Professional summary with key findings, maximum {max_words} words, in the same language as the content]\"\n}\n\n{content}";
                break;
                
            default:
                // Default to narrative style
                $template = "Please provide a concise summary of the following content.\n\nReturn only valid JSON. The summary must be a single paragraph without line breaks or numbering.\n\n{\n  \"title\": \"[word for '{title_label}' in the same language as the content]\",\n  \"summary\": \"[2-3 short sentences, maximum {max_words} words, in the same language as the content]\"\n}\n\n{content}";
                break;
        }
        
        $prompt = str_replace( '{max_words}', $max_words, $template );
        $prompt = str_replace( '{title_label}', $title_label, $prompt );
        return str_replace( '{content}', $content, $prompt );
    }

    /**
     * Make HTTP request to OpenRouter API
     *
     * @param string $method HTTP method.
     * @param string $endpoint API endpoint.
     * @param array  $data Request data.
     * @return array|WP_Error
     */
    private function make_request( $method, $endpoint, $data = null ) {
        $api_key = $this->get_api_key();
        $url = self::API_BASE_URL . $endpoint;

        $headers = array(
            'Authorization' => 'Bearer ' . $api_key,
            'Content-Type'  => 'application/json',
            'HTTP-Referer'  => home_url(),
            'X-Title'       => get_bloginfo( 'name' ) . ' - HD SofT AI Summary',
        );

        $args = array(
            'method'  => $method,
            'headers' => $headers,
            'timeout' => self::API_TIMEOUT,
        );

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

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

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

        $response_code = wp_remote_retrieve_response_code( $response );
        
        if ( $response_code < 200 || $response_code >= 300 ) {
            $body = wp_remote_retrieve_body( $response );
            $error_data = json_decode( $body, true );
            
            $error_message = __( 'HTTP error: ', 'hd-soft-ai-summary' ) . $response_code;
            
            if ( $error_data && isset( $error_data['error']['message'] ) ) {
                $error_message .= ' - ' . $error_data['error']['message'];
            }
            
            return new \WP_Error( 'http_error', $error_message );
        }

        return $response;
    }

    /**
     * Get available models
     *
     * @return array|WP_Error
     */
    public function get_models() {
        $response = $this->make_request( 'GET', '/models' );

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

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

        if ( ! $data || ! isset( $data['data'] ) ) {
            return new \WP_Error( 'invalid_response', __( 'Invalid response from OpenRouter API.', 'hd-soft-ai-summary' ) );
        }

        // Filter and format models for dropdown
        $models = array();
        foreach ( $data['data'] as $model ) {
            // Skip models that don't support chat completions
            if ( ! isset( $model['id'] ) ) {
                continue;
            }

            $models[ $model['id'] ] = array(
                'name'        => $model['name'] ?? $model['id'],
                'description' => $model['description'] ?? '',
                'pricing'     => $model['pricing'] ?? array(),
            );
        }

        return $models;
    }

    /**
     * Validate API key format
     *
     * @param string $api_key API key to validate.
     * @return bool
     */
    public function validate_api_key_format( $api_key ) {
        // OpenRouter API keys typically start with 'sk-or-' and are at least 20 characters
        return ! empty( $api_key ) && 
               is_string( $api_key ) && 
               strlen( $api_key ) >= 20 && 
               ( strpos( $api_key, 'sk-or-' ) === 0 || strpos( $api_key, 'sk-' ) === 0 );
    }

    /**
     * Get usage statistics (if available)
     *
     * @return array|WP_Error
     */
    public function get_usage_stats() {
        $response = $this->make_request( 'GET', '/auth/key' );

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

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

        if ( ! $data ) {
            return new \WP_Error( 'invalid_response', __( 'Invalid response from OpenRouter API.', 'hd-soft-ai-summary' ) );
        }

        return $data;
    }
}
