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

/**
 * AYSA Structured Data Class
 * Creates Schema.org JSON-LD markup only when none exists
 * 
 * @package AYSA
 * @since 1.0.0
 */

class AYSA_Structured_Data {
    
    private $existing_schema = array();
    private $debug = false;
    
    /**
     * Initialize the structured data functionality
     */
    public function __construct() {
        // Enable debug mode if WP_DEBUG is on
        $this->debug = defined('WP_DEBUG') && WP_DEBUG;
        
        // Hook into WordPress head with high priority to detect existing schema
        add_action('wp_head', array($this, 'detect_existing_schema'), 0);
        
        // Hook into WordPress head with lower priority to output new schema
        add_action('wp_head', array($this, 'output_structured_data'), 999);
        
        // Hook into WordPress head with even lower priority to catch late schema additions
        add_action('wp_head', array($this, 'final_schema_check'), 1000);
        
        // Hook into save actions to generate structured data
        add_action('save_post', array($this, 'generate_structured_data_on_save'), 10, 2);
        add_action('edited_term', array($this, 'generate_structured_data_for_term'), 10, 3);
        
        // Add AJAX handlers
        add_action('wp_ajax_aysa_validate_schema', array($this, 'ajax_validate_schema'));
        add_action('wp_ajax_aysa_test_schema', array($this, 'ajax_test_schema'));
        add_action('wp_ajax_aysa_get_schema_status', array($this, 'ajax_get_schema_status'));
    }
    
    /**
     * Detect existing Schema.org markup using output buffering
     */
    public function detect_existing_schema() {
        // Start output buffering to capture existing schema
        ob_start(array($this, 'capture_existing_schema'));
    }
    
    /**
     * Capture and parse existing Schema.org markup
     */
    public function capture_existing_schema($content) {
        // Look for existing JSON-LD schema
        $schema_pattern = '/<script[^>]*type=["\']application\/ld\+json["\'][^>]*>(.*?)<\/script>/is';
        
        if (preg_match_all($schema_pattern, $content, $matches)) {
            foreach ($matches[1] as $schema_json) {
                $schema_data = json_decode($schema_json, true);
                if ($schema_data) {
                    $this->existing_schema[] = $schema_data;
                    if ($this->debug) {
                        aysa_debug_log("AYSA: Detected existing schema: " . json_encode($schema_data));
                    }
                }
            }
        }
        
        // Return content unchanged - we don't remove existing schema
        return $content;
    }
    
    /**
     * Output new structured data only if none exists
     */
    public function output_structured_data() {
        if (is_admin()) {
            return;
        }
        
        // Check if all schema output is disabled
        if (get_option('aysa_disable_all_schema_output', false)) {
            if ($this->debug) {
                aysa_debug_log("AYSA Structured Data: All schema output is disabled via option");
            }
            return;
        }
        
        // Check if current URL is in schema blacklist
        $current_url = $this->get_current_url();
        $blacklist = get_option('aysa_schema_blacklist', array());
        
        if (in_array($current_url, $blacklist)) {
            if ($this->debug) {
                aysa_debug_log("AYSA: Schema output blocked for URL: $current_url (in blacklist)");
            }
            return;
        }
        
        // Stop output buffering
        if (ob_get_level()) {
            ob_end_flush();
        }
        
        // Only create new schema if no existing schema was detected
        if (empty($this->existing_schema)) {
            $new_schema = $this->create_new_schema();
            
            if (!empty($new_schema)) {
                echo "\n<!-- AYSA Structured Data (No existing schema found) -->\n";
                foreach ($new_schema as $schema) {
                    echo '<script type="application/ld+json">' . "\n";
                    echo wp_json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
                    echo "</script>\n";
                }
                echo "<!-- End AYSA Structured Data -->\n\n";
                
                if ($this->debug) {
                    aysa_debug_log("AYSA: Created new schema because no existing schema was found");
                }
            }
        } else {
            if ($this->debug) {
                aysa_debug_log("AYSA: Skipping schema creation - existing schema detected: " . count($this->existing_schema) . " schemas");
            }
        }
    }
    
    /**
     * Final check for schema that might have been added after our initial detection
     */
    public function final_schema_check() {
        // This method is now simplified - just for logging purposes
        if (is_admin()) {
            return;
        }
        
        if ($this->debug && is_singular('product') && class_exists('WooCommerce')) {
            aysa_debug_log("AYSA: WooCommerce product page detected - schema handled by WooCommerce");
        }
    }
    
    /**
     * Create new Schema.org markup when none exists
     */
    private function create_new_schema() {
        $new_schema = array();
        
        // Skip schema creation for WooCommerce products - they have their own schema
        if (is_singular('product') && class_exists('WooCommerce')) {
            if ($this->debug) {
                aysa_debug_log("AYSA: Skipping schema creation for WooCommerce product - WooCommerce has its own schema");
            }
            return $new_schema;
        }
        
        // Always add organization schema if no existing schema
        $organization_schema = $this->get_organization_schema();
        if ($organization_schema) {
            $new_schema[] = $organization_schema;
        }
        
        // Add breadcrumb schema
        $breadcrumb_schema = $this->get_breadcrumb_schema();
        if ($breadcrumb_schema) {
            $new_schema[] = $breadcrumb_schema;
        }
        
        // Add content-specific schema based on current page
        if (is_singular('product')) {
            // Skip product schema for WooCommerce
            if ($this->debug) {
                aysa_debug_log("AYSA: Skipping product schema - WooCommerce handles this");
            }
        } elseif (is_singular()) {
            $article_schema = $this->get_article_schema(get_post());
            if ($article_schema) {
                $new_schema[] = $article_schema;
            }
        } elseif (is_archive()) {
            $archive_schema = $this->get_archive_schema();
            if ($archive_schema) {
                $new_schema[] = $archive_schema;
            }
        } elseif (is_category() || is_tag() || is_tax()) {
            $term = get_queried_object();
            $collection_schema = $this->get_collection_page_schema($term, get_taxonomy($term->taxonomy));
            if ($collection_schema) {
                $new_schema[] = $collection_schema;
            }
        }
        
        return $new_schema;
    }
    
    /**
     * Get organization schema
     */
    private function get_organization_schema() {
        $schema = array(
            '@type' => 'Organization',
            '@id' => home_url('/#organization'),
            'name' => get_bloginfo('name'),
            'url' => home_url(),
        );
        
        // Add logo if available
        $custom_logo_id = get_theme_mod('custom_logo');
        if ($custom_logo_id) {
            $logo_url = wp_get_attachment_image_url($custom_logo_id, 'full');
            if ($logo_url) {
                $schema['logo'] = array(
                    '@type' => 'ImageObject',
                    'url' => $logo_url
                );
            }
        }
        
        // Add contact information
        $contact_info = $this->get_contact_info();
        if (!empty($contact_info)) {
            $schema['contactPoint'] = $contact_info;
        }
        
        return $schema;
    }
    
    /**
     * Get contact information
     */
    private function get_contact_info() {
        $contact_info = array();
        
        // Get contact info from AYSA settings or WordPress options
        $phone = get_option('aysa_contact_phone', '');
        $email = get_option('aysa_contact_email', '');
        
        if ($phone) {
            $contact_info[] = array(
                '@type' => 'ContactPoint',
                'telephone' => $phone,
                'contactType' => 'customer service'
            );
        }
        
        if ($email) {
            $contact_info[] = array(
                '@type' => 'ContactPoint',
                'email' => $email,
                'contactType' => 'customer service'
            );
        }
        
        return $contact_info;
    }
    
    /**
     * Get breadcrumb schema
     */
    private function get_breadcrumb_schema() {
        $breadcrumbs = $this->get_breadcrumbs();
        
        if (empty($breadcrumbs)) {
            return null;
        }
        
        $schema = array(
            '@type' => 'BreadcrumbList',
            '@id' => home_url('/#breadcrumb'),
            'itemListElement' => array()
        );
        
        foreach ($breadcrumbs as $index => $breadcrumb) {
            $schema['itemListElement'][] = array(
                '@type' => 'ListItem',
                'position' => $index + 1,
                'name' => $breadcrumb['title'],
                'item' => $breadcrumb['url']
            );
        }
        
        return $schema;
    }
    
    /**
     * Get breadcrumbs for current page
     */
    private function get_breadcrumbs() {
        $breadcrumbs = array();
        
        // Always add home
        $breadcrumbs[] = array(
            'title' => get_bloginfo('name'),
            'url' => home_url()
        );
        
        if (is_singular()) {
            $post = get_post();
            
            // Add category breadcrumbs for posts
            if ($post->post_type === 'post') {
                $categories = get_the_category($post->ID);
                if (!empty($categories)) {
                    $category = $categories[0];
                    $breadcrumbs[] = array(
                        'title' => $category->name,
                        'url' => get_category_link($category->term_id)
                    );
                }
            }
            
            // Add current page
            $breadcrumbs[] = array(
                'title' => get_the_title($post->ID),
                'url' => get_permalink($post->ID)
            );
        } elseif (is_category() || is_tag() || is_tax()) {
            $term = get_queried_object();
            $breadcrumbs[] = array(
                'title' => $term->name,
                'url' => get_term_link($term)
            );
        }
        
        return $breadcrumbs;
    }
    
    /**
     * Get product schema
     */
    private function get_product_schema($post) {
        if (!$post || $post->post_type !== 'product') {
            return null;
        }
        
        $schema = array(
            '@type' => 'Product',
            '@id' => get_permalink($post->ID) . '#product',
            'name' => get_the_title($post->ID),
            'description' => get_the_excerpt($post->ID) ?: get_the_title($post->ID),
            'url' => get_permalink($post->ID)
        );
        
        // Get AYSA data
        $aysa_data = $this->get_aysa_meta_data($post->ID, 'post');
        
        // Use AYSA title if available
        if (!empty($aysa_data['meta_title'])) {
            $schema['name'] = $aysa_data['meta_title'];
        }
        
        // Use AYSA description if available
        if (!empty($aysa_data['meta_description'])) {
            $schema['description'] = $aysa_data['meta_description'];
        }
        
        // Add keywords if available
        if (!empty($aysa_data['keywords'])) {
            $schema['keywords'] = $aysa_data['keywords'];
        }
        
        // Add featured image
        if (has_post_thumbnail($post->ID)) {
            $image_id = get_post_thumbnail_id($post->ID);
            $image_url = wp_get_attachment_image_url($image_id, 'full');
            $image_alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
            
            if ($image_url) {
                $schema['image'] = array(
                    '@type' => 'ImageObject',
                    'url' => $image_url,
                    'alt' => $image_alt ?: get_the_title($post->ID)
                );
            }
        }
        
        return $schema;
    }
    
    /**
     * Get article schema
     */
    private function get_article_schema($post) {
        if (!$post) {
            return null;
        }
        
        $schema = array(
            '@type' => 'Article',
            '@id' => get_permalink($post->ID) . '#article',
            'headline' => get_the_title($post->ID),
            'description' => get_the_excerpt($post->ID) ?: get_the_title($post->ID),
            'url' => get_permalink($post->ID),
            'datePublished' => get_the_date('c', $post->ID),
            'dateModified' => get_the_modified_date('c', $post->ID),
            'author' => array(
                '@type' => 'Person',
                'name' => get_the_author_meta('display_name', $post->post_author)
            ),
            'publisher' => array(
                '@type' => 'Organization',
                'name' => get_bloginfo('name'),
                'url' => home_url()
            )
        );
        
        // Get AYSA data
        $aysa_data = $this->get_aysa_meta_data($post->ID, 'post');
        
        // Use AYSA title if available
        if (!empty($aysa_data['meta_title'])) {
            $schema['headline'] = $aysa_data['meta_title'];
        }
        
        // Use AYSA description if available
        if (!empty($aysa_data['meta_description'])) {
            $schema['description'] = $aysa_data['meta_description'];
        }
        
        // Add keywords if available
        if (!empty($aysa_data['keywords'])) {
            $schema['keywords'] = $aysa_data['keywords'];
        }
        
        // Add featured image
        if (has_post_thumbnail($post->ID)) {
            $image_id = get_post_thumbnail_id($post->ID);
            $image_url = wp_get_attachment_image_url($image_id, 'full');
            $image_alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
            
            if ($image_url) {
                $schema['image'] = array(
                    '@type' => 'ImageObject',
                    'url' => $image_url,
                    'alt' => $image_alt ?: get_the_title($post->ID)
                );
            }
        }
        
        return $schema;
    }
    
    /**
     * Get archive schema
     */
    private function get_archive_schema() {
        $schema = array(
            '@type' => 'CollectionPage',
            '@id' => home_url('/#archive'),
            'name' => get_bloginfo('name'),
            'description' => get_bloginfo('description'),
            'url' => home_url()
        );
        
        return $schema;
    }
    
    /**
     * Get collection page schema for categories/tags
     */
    private function get_collection_page_schema($term, $taxonomy) {
        if (!$term || !$taxonomy) {
            return null;
        }
        
        $schema = array(
            '@type' => 'CollectionPage',
            '@id' => get_term_link($term) . '#collection',
            'name' => $term->name,
            'description' => $term->description ?: $term->name,
            'url' => get_term_link($term)
        );
        
        // Get AYSA data for term
        $aysa_data = $this->get_aysa_meta_data($term->term_id, 'term');
        
        // Use AYSA title if available
        if (!empty($aysa_data['meta_title'])) {
            $schema['name'] = $aysa_data['meta_title'];
        }
        
        // Use AYSA description if available
        if (!empty($aysa_data['meta_description'])) {
            $schema['description'] = $aysa_data['meta_description'];
        }
        
        // Add keywords if available
        if (!empty($aysa_data['keywords'])) {
            $schema['keywords'] = $aysa_data['keywords'];
        }
        
        return $schema;
    }
    
    /**
     * Get AYSA meta data for entity
     */
    private function get_aysa_meta_data($entity_id, $entity_type) {
        $data = array();
        
        if ($entity_type === 'post') {
            $data['meta_title'] = get_post_meta($entity_id, '_aysa_ai_title', true);
            $data['meta_description'] = get_post_meta($entity_id, '_aysa_ai_description', true);
            $data['keywords'] = get_post_meta($entity_id, '_aysa_ai_secondary_keywords', true);
            $data['image_alt'] = get_post_meta($entity_id, '_aysa_ai_image_alt', true);
        } elseif ($entity_type === 'term') {
            $data['meta_title'] = get_term_meta($entity_id, '_aysa_ai_title', true);
            $data['meta_description'] = get_term_meta($entity_id, '_aysa_ai_description', true);
            $data['keywords'] = get_term_meta($entity_id, '_aysa_ai_secondary_keywords', true);
        }
        
        return $data;
    }
    
    /**
     * Generate structured data on post save
     */
    public function generate_structured_data_on_save($post_id, $post) {
        // Only for published posts
        if ($post->post_status !== 'publish') {
            return;
        }
        
        // Cache the structured data
        $this->cache_structured_data($post_id, 'post');
    }
    
    /**
     * Generate structured data on term save
     */
    public function generate_structured_data_for_term($term_id, $tt_id, $taxonomy) {
        // Cache the structured data
        $this->cache_structured_data($term_id, 'term');
    }
    
    /**
     * Cache structured data for entity
     */
    private function cache_structured_data($entity_id, $entity_type) {
        // This could be used for performance optimization
        // For now, we'll generate schema on-demand
    }
    
    /**
     * AJAX handler to validate schema
     */
    public function ajax_validate_schema() {
        // Verify nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'aysa_schema_nonce')) {
            wp_send_json_error('Nonce verification failed');
            return;
        }
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }
        
        $entity_id = intval(wp_unslash($_POST['entity_id'] ?? 0));
        $entity_type = sanitize_text_field(wp_unslash($_POST['entity_type'] ?? ''));
        
        if (!$entity_id || !$entity_type) {
            wp_send_json_error('Invalid entity ID or type');
            return;
        }
        
        $schema = $this->get_entity_structured_data($entity_id, $entity_type);
        
        if (!$schema) {
            wp_send_json_error('No schema found for this entity');
            return;
        }
        
        $validation_result = $this->validate_schema_structure($schema);
        
        wp_send_json_success(array(
            'schema' => $schema,
            'validation' => $validation_result
        ));
    }
    
    /**
     * AJAX handler to test schema
     */
    public function ajax_test_schema() {
        // Verify nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'aysa_schema_nonce')) {
            wp_send_json_error('Nonce verification failed');
            return;
        }
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }
        
        $entity_id = intval(wp_unslash($_POST['entity_id'] ?? 0));
        $entity_type = sanitize_text_field(wp_unslash($_POST['entity_type'] ?? ''));
        
        if (!$entity_id || !$entity_type) {
            wp_send_json_error('Invalid entity ID or type');
            return;
        }
        
        $schema = $this->get_entity_structured_data($entity_id, $entity_type);
        
        if (!$schema) {
            wp_send_json_error('No schema found for this entity');
            return;
        }
        
        $test_result = $this->test_with_google_rich_results($schema);
        
        wp_send_json_success(array(
            'schema' => $schema,
            'test_result' => $test_result
        ));
    }
    
    /**
     * AJAX handler to get schema status
     */
    public function ajax_get_schema_status() {
        // Verify nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'aysa_schema_nonce')) {
            wp_send_json_error('Nonce verification failed');
            return;
        }
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }
        
        $entity_id = intval(wp_unslash($_POST['entity_id'] ?? 0));
        $entity_type = sanitize_text_field(wp_unslash($_POST['entity_type'] ?? ''));
        
        if (!$entity_id || !$entity_type) {
            wp_send_json_error('Invalid entity ID or type');
            return;
        }
        
        $status = $this->get_schema_status($entity_id, $entity_type);
        
        wp_send_json_success($status);
    }
    
    /**
     * Get structured data for specific entity
     */
    private function get_entity_structured_data($entity_id, $entity_type) {
        if ($entity_type === 'post') {
            $post = get_post($entity_id);
            if ($post && $post->post_type === 'product') {
                return $this->get_product_schema($post);
            } elseif ($post) {
                return $this->get_article_schema($post);
            }
        } elseif ($entity_type === 'term') {
            $term = get_term($entity_id);
            if ($term && !is_wp_error($term)) {
                $taxonomy = get_taxonomy($term->taxonomy);
                return $this->get_collection_page_schema($term, $taxonomy);
            }
        }
        
        return null;
    }
    
    /**
     * Get schema status for entity
     */
    private function get_schema_status($entity_id, $entity_type) {
        $status = array(
            'entity_id' => $entity_id,
            'entity_type' => $entity_type,
            'has_aysa_data' => false,
            'has_schema' => false,
            'schema_type' => null,
            'recommendations' => array()
        );
        
        // Check if entity has AYSA data
        $aysa_data = $this->get_aysa_meta_data($entity_id, $entity_type);
        if (!empty($aysa_data['meta_title']) || !empty($aysa_data['meta_description']) || !empty($aysa_data['keywords'])) {
            $status['has_aysa_data'] = true;
        }
        
        // Check if schema would be generated
        $schema = $this->get_entity_structured_data($entity_id, $entity_type);
        if ($schema) {
            $status['has_schema'] = true;
            $status['schema_type'] = $schema['@type'] ?? null;
        }
        
        // Add recommendations
        if (!$status['has_aysa_data']) {
            $status['recommendations'][] = 'Generate AYSA AI data to improve schema quality';
        }
        
        if (!$status['has_schema']) {
            $status['recommendations'][] = 'This entity type does not generate schema markup';
        }
        
        return $status;
    }
    
    /**
     * Validate schema structure
     */
    private function validate_schema_structure($schema) {
        $errors = array();
        $warnings = array();
        
        // Basic validation
        if (!isset($schema['@type'])) {
            $errors[] = 'Missing @type property';
        }
        
        if (!isset($schema['name']) && !isset($schema['headline'])) {
            $warnings[] = 'Missing name or headline property';
        }
        
        if (!isset($schema['description'])) {
            $warnings[] = 'Missing description property';
        }
        
        return array(
            'valid' => empty($errors),
            'errors' => $errors,
            'warnings' => $warnings
        );
    }
    
    /**
     * Get current URL for blacklist checking
     */
    private function get_current_url() {
        if (is_home() || is_front_page()) {
            return home_url('/');
        }
        
        global $wp;
        return home_url($wp->request . '/');
    }
    
    /**
     * Test schema with Google Rich Results
     */
    private function test_with_google_rich_results($schema) {
        // This would integrate with Google's Rich Results Test API
        // For now, return a mock result
        return array(
            'tested' => true,
            'eligible' => true,
            'message' => 'Schema appears to be valid for Google Rich Results'
        );
    }
} 
