<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Thin adapter that talks to the configured AI provider and returns plain text.
 *
 * Uses the existing provider system (OpenAI / Anthropic / Google, etc.).
 *
 * @since 2.1.0
 */
class AI_Magic_Layout_AI
{

    /**
     * @var mixed Provider instance (OpenAI/Anthropic/Google, etc.)
     */
    protected $provider;

    /**
     * Last API call cost
     * @var float
     */
    protected $last_cost = 0;

    /**
     * Last API call details
     * @var array
     */
    protected $last_details = array();

    /**
     * @param mixed $provider Any object that has generateText( $prompt ) method.
     */
    public function __construct($provider = null)
    {
        $this->provider = $provider;
    }

    /**
     * Check if provider is usable.
     *
     * @return bool
     */
    public function has_provider()
    {
        return (is_object($this->provider) && method_exists($this->provider, 'generateText'));
    }

    /**
     * Get last API call cost.
     *
     * @return float
     */
    public function get_last_cost()
    {
        return $this->last_cost;
    }

    /**
     * Get last API call details.
     *
     * @return array
     */
    public function get_last_details()
    {
        return $this->last_details;
    }

    /**
     * Rewrite a single text and return detailed result.
     *
     * @param string $original Original text
     * @param string $prompt Company/project info
     * @param string $custom_name Optional custom name for the page
     *
     * @return array {text: string, cost: float, old_text: string, new_text: string}
     */
    public function rewrite_text_single($original, $prompt, $custom_name = '')
    {
        $result = array(
            'text' => $original,
            'cost' => 0,
            'old_text' => $original,
            'new_text' => $original,
            'success' => false,
        );

        if (!$this->has_provider() || empty(trim($original))) {
            return $result;
        }

        // Detect if original content has HTML structure
        $has_html_structure = preg_match('/<(section|div|h[1-6]|p|ul|ol|li|a|img|figure|table|tr|td|th|blockquote|span|strong|em|b|i)[^>]*>/i', $original);

        if ($has_html_structure) {
            // Calculate approximate content length for guidance
            $text_only = strip_tags($original);
            $word_count = str_word_count($text_only);
            $char_count = strlen($text_only);

            // HTML STRUCTURE PRESERVATION MODE
            $single_prompt = "[CRITICAL INSTRUCTION - STRUCTURE PRESERVATION MODE]\n\n";
            $single_prompt .= "You are modifying an EXISTING HTML template. You MUST:\n";
            $single_prompt .= "1. Keep the EXACT same HTML structure (all tags, attributes, classes, IDs)\n";
            $single_prompt .= "2. ONLY replace text content INSIDE the HTML elements\n";
            $single_prompt .= "3. Do NOT add any new HTML tags\n";
            $single_prompt .= "4. Do NOT remove any existing HTML tags\n";
            $single_prompt .= "5. Do NOT modify attributes (src, href, class, id, etc.)\n";
            $single_prompt .= "6. Preserve ALL <img>, <input>, <a>, <section>, <div> tags exactly\n";
            $single_prompt .= "7. Do NOT wrap output in code blocks or JSON\n";
            $single_prompt .= "8. Do NOT use markdown formatting (**bold**, *italic*) - HTML only\n\n";

            // CRITICAL: Content length control
            $single_prompt .= "[CONTENT LENGTH RULES - VERY IMPORTANT]\n";
            $single_prompt .= "- Match the APPROXIMATE length of original content (~{$word_count} words, ~{$char_count} chars)\n";
            $single_prompt .= "- <h1>, <h2>, <h3>, <h4>, <h5>, <h6> = HEADINGS must be SHORT (1 line, max 10 words)\n";
            $single_prompt .= "- <p> = Paragraphs can be longer but similar length to original\n";
            $single_prompt .= "- Short text stays SHORT, long text can stay LONG\n";
            $single_prompt .= "- DO NOT expand a 3-word heading into a 500-word essay!\n\n";

            $single_prompt .= "[COMPANY INFORMATION]\n" . (string) $prompt . "\n\n";

            if (!empty($custom_name)) {
                $single_prompt .= "[PAGE CONTEXT]\n";
                $single_prompt .= "Page name: " . $custom_name . "\n";
                $single_prompt .= "Generate content appropriate for this page.\n\n";
            }

            $single_prompt .= "[EXISTING HTML TEMPLATE - PRESERVE STRUCTURE]\n";
            $single_prompt .= $original . "\n\n";
            $single_prompt .= "[OUTPUT]\n";
            $single_prompt .= "Return the modified HTML with ONLY text content replaced. Keep exact same structure and SIMILAR content length.";
        } else {
            // PLAIN TEXT REWRITE MODE
            $single_prompt = "Rewrite the following text professionally and readably according to the given company information. ";
            $single_prompt .= "Do NOT create page structure, HTML/shortcode or Elementor/WPBakery/Gutenberg elements. ";
            $single_prompt .= "Return only plain text. Avoid unnecessary embellishments and overly long sentences.\n\n";

            $single_prompt .= "Company information:\n" . (string) $prompt . "\n\n";

            if (!empty($custom_name)) {
                $single_prompt .= "New page name: " . $custom_name . "\n";
                $single_prompt .= "Generate content appropriate for this page name.\n\n";
            }

            $single_prompt .= "Original text:\n" . $original . "\n\n";
            $single_prompt .= "Return only the new text, no explanations.";
        }

        // Estimate input tokens for cost calculation
        $input_tokens = 0;
        if (class_exists('AI_Magic_Cost_Calculator')) {
            $input_tokens = AI_Magic_Cost_Calculator::estimate_tokens($single_prompt);
        }

        $response = $this->provider->generateText($single_prompt);

        $new_text = $original;
        $output_tokens = 0;

        if (is_array($response) && isset($response['type']) && $response['type'] === 'success') {

            if (isset($response['data'])) {
                if (is_string($response['data'])) {
                    $new_text = $response['data'];
                } elseif (is_array($response['data'])) {
                    if (isset($response['data']['text']) && is_string($response['data']['text'])) {
                        $new_text = $response['data']['text'];
                    } elseif (isset($response['data']['post_content']) && is_string($response['data']['post_content'])) {
                        $new_text = $response['data']['post_content'];
                    }
                }
            }

            if (isset($response['raw_text']) && is_string($response['raw_text']) && $new_text === $original) {
                $new_text = $response['raw_text'];
            }

            // Try to get usage info from response
            if (isset($response['usage'])) {
                if (isset($response['usage']['prompt_tokens'])) {
                    $input_tokens = (int) $response['usage']['prompt_tokens'];
                }
                if (isset($response['usage']['completion_tokens'])) {
                    $output_tokens = (int) $response['usage']['completion_tokens'];
                }
            }

            $result['success'] = true;
        }

        // Estimate output tokens if not provided
        if ($output_tokens === 0 && class_exists('AI_Magic_Cost_Calculator')) {
            $output_tokens = AI_Magic_Cost_Calculator::estimate_tokens($new_text);
        }

        // Calculate cost
        $cost = 0;
        if (class_exists('AI_Magic_Cost_Calculator')) {
            $model = get_option('ai_magic_openai_model', 'gpt-4o-mini');
            $cost = AI_Magic_Cost_Calculator::calculate_cost($model, $input_tokens, $output_tokens);
        }

        $result['text'] = trim((string) $new_text);
        $result['new_text'] = trim((string) $new_text);
        $result['cost'] = $cost;

        $this->last_cost = $cost;
        $this->last_details = array(
            'input_tokens' => $input_tokens,
            'output_tokens' => $output_tokens,
            'old_text' => mb_substr($original, 0, 100),
            'new_text' => mb_substr($new_text, 0, 100),
        );

        return $result;
    }

    /**
     * Rewrite a list of texts based on the given prompt (company info, etc.).
     *
     * @param array  $texts  Each item must contain 'value' key with original text.
     * @param string $prompt High-level instructions (company name, sector, language, etc.)
     * @param string $custom_name Optional custom name for the page
     *
     * @return array New text values in the same order as $texts.
     */
    public function rewrite_texts(array $texts, $prompt, $custom_name = '')
    {

        if (!$this->has_provider()) {
            return array();
        }

        $new_values = array();
        $total_cost = 0;

        foreach ($texts as $key => $item) {

            $original = isset($item['value']) ? (string) $item['value'] : (is_string($item) ? $item : '');

            if ($original === '') {
                $new_values[$key] = $original;
                continue;
            }

            $result = $this->rewrite_text_single($original, $prompt, $custom_name);
            $new_values[$key] = $result['text'];
            $total_cost += $result['cost'];
        }

        $this->last_cost = $total_cost;

        return $new_values;
    }

}
