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

class AISB_API {

    public static function test($api_key = '') {
        $args = aisb_llm_args();
        if ($api_key !== '') {
            $args['api_key'] = $api_key;
        }
        if (empty($args['api_key']) && !AISB_LLM_API::core_text_generation_supported()) {
            return ['ok' => false, 'message' => __('API key is empty', 'pewit-ai-schema-builder')];
        }
        return aisb_llm_localize_test_result(AISB_LLM_API::test($args));
    }

    /**
     * @return array|WP_Error
     */
    public static function generate_schema($post_id, $schema_type = '') {
        $settings = aisb_get_settings();
        $args = aisb_llm_args(['max_tokens' => 1200]);
        if (!AISB_LLM_API::core_text_generation_supported() && empty($args['api_key'])) {
            return new WP_Error('aisb_no_key', __('API key is empty', 'pewit-ai-schema-builder'));
        }

        $post = get_post($post_id);
        if (!$post) {
            return new WP_Error('aisb_no_post', __('Post not found', 'pewit-ai-schema-builder'));
        }

        $schema_type = $schema_type ?: AISB_Schema::detect_type($post);
        if (!AISB_Schema::is_type_allowed($schema_type, $post)) {
            return new WP_Error('aisb_type_locked', __('This schema type requires Pro.', 'pewit-ai-schema-builder'));
        }

        $prompt = self::build_prompt($post, $schema_type, $settings);
        $text = AISB_LLM_API::complete($prompt, $args);
        if (is_wp_error($text)) {
            return aisb_llm_localize_error($text);
        }

        $json = self::extract_json($text);
        if (!$json) {
            return new WP_Error('aisb_bad_json', __('AI response was not valid JSON.', 'pewit-ai-schema-builder') . ' ' . substr($text, 0, 200));
        }

        $json = AISB_Schema::normalize($json, $schema_type, $post);
        $json = AISB_Rich_Results::enrich_from_post($json, $post_id);
        return $json;
    }

    private static function build_prompt($post, $schema_type, $settings) {
        $title = get_the_title($post);
        $url = get_permalink($post);
        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core content filter required to parse blocks/shortcodes in post body.
        $content = wp_strip_all_tags(apply_filters('the_content', $post->post_content));
        $content = substr(trim($content), 0, 6000);
        $etch_ctx = AISB_Etch::is_active() ? AISB_Etch::extract_prompt_context($post->ID) : '';
        if ($etch_ctx) {
            $content = trim($etch_ctx . "\n\n" . $content);
            $content = substr($content, 0, 8000);
        }
        $excerpt = has_excerpt($post) ? wp_strip_all_tags(get_the_excerpt($post)) : substr($content, 0, 400);
        $author = get_the_author_meta('display_name', $post->post_author);
        $date = get_the_date('c', $post);
        $modified = get_the_modified_date('c', $post);
        $site = get_bloginfo('name');

        $prompt = "Generate valid Schema.org JSON-LD for WordPress.\n";
        $prompt .= "Return ONLY a single JSON object (no markdown, no explanation).\n";
        $prompt .= "Use @context https://schema.org and @type {$schema_type}.\n";
        if (!empty($settings['global_context'])) {
            $prompt .= 'Website context: ' . trim($settings['global_context']) . "\n";
        }
        $prompt .= "Post type: {$post->post_type}\n";
        $prompt .= "Site name: {$site}\n";
        $prompt .= "Page title: {$title}\n";
        $prompt .= "URL: {$url}\n";
        $prompt .= "Author: {$author}\n";
        $prompt .= "Published: {$date}\n";
        $prompt .= "Modified: {$modified}\n";
        if ($excerpt) {
            $prompt .= "Excerpt: {$excerpt}\n";
        }
        if ($content) {
            $prompt .= "Content:\n{$content}\n";
        }

        if ($schema_type === 'Product' && function_exists('wc_get_product')) {
            $product = wc_get_product($post->ID);
            if ($product) {
                $prompt .= 'Product SKU: ' . $product->get_sku() . "\n";
                $prompt .= 'Price: ' . $product->get_price() . ' ' . get_woocommerce_currency() . "\n";
                $prompt .= 'Stock status: ' . $product->get_stock_status() . "\n";
                if ($product->get_image_id()) {
                    $prompt .= 'Image URL: ' . wp_get_attachment_url($product->get_image_id()) . "\n";
                }
            }
        }

        if ($schema_type === 'FAQPage') {
            $prompt .= "Extract FAQ pairs from headings/questions in the content. Include mainEntity as an array of Question objects with acceptedAnswer.\n";
        }
        if ($schema_type === 'LocalBusiness') {
            $prompt .= "Include PostalAddress in address. Add telephone and openingHoursSpecification when present in content.\n";
        }
        if ($schema_type === 'Event') {
            $prompt .= "Use ISO 8601 for startDate/endDate. Location as Place with name and address.\n";
        }
        if ($schema_type === 'HowTo') {
            $prompt .= "step must be an array of HowToStep with name and text.\n";
        }
        if ($schema_type === 'JobPosting') {
            $prompt .= "Use title (not name), hiringOrganization as Organization, jobLocation as Place.\n";
        }
        if (AISB_Etch::is_active()) {
            $prompt .= "Content may come from EtchWP blocks / Content Hub fields — use only factual data from the text.\n";
        }

        $field_ctx = AISB_Field_Mapper::context_for_prompt($post->ID);
        if ($field_ctx) {
            $prompt .= $field_ctx . "\n";
        }

        $prompt .= AISB_Schema::required_fields_hint($schema_type);
        $prompt .= "\nDo not invent facts. Use only information from the content provided.";

        return $prompt;
    }

    private static function extract_json($text) {
        $text = trim($text);
        $text = preg_replace('/^```json\s*/', '', $text);
        $text = preg_replace('/```$/', '', $text);
        $data = json_decode($text, true);
        if (is_array($data)) {
            return $data;
        }
        if (preg_match('/\{.*\}/s', $text, $m)) {
            $data = json_decode($m[0], true);
            if (is_array($data)) {
                return $data;
            }
        }
        return null;
    }
}
