<?php

if (!defined('WPINC')) {
    die;
}

class Aysa_Keyword_Processor {
    
    private $api_base_url;
    private $confidence_scorer;
    private $audit_logger;
    
    public function __construct() {
        $this->api_base_url = defined('AYSA_API_BASE_URL') ? AYSA_API_BASE_URL : 'https://api.aysa.ai/api/';
        $this->confidence_scorer = new Aysa_Confidence_Scorer();
        $this->audit_logger = new Aysa_Audit_Logger();
    }
    
    public function process($job_data) {
        $term_id = $job_data['term_id'];
        $taxonomy = $job_data['taxonomy'];
        
        $term = get_term($term_id, $taxonomy);
        if (is_wp_error($term) || !$term) {
            return new WP_Error('term_not_found', 'Term not found');
        }
        
        $existing_keyword = get_term_meta($term_id, 'aysa_primary_keyword', true);
        if (!empty($existing_keyword)) {
            return new WP_Error('keyword_exists', 'Term already has a primary keyword');
        }
        
        $term_data = $this->prepare_term_data($term, $job_data);
        $suggested_keywords = $this->generate_keyword_suggestions($term_data);
        
        if (is_wp_error($suggested_keywords)) {
            return $suggested_keywords;
        }
        
        if (empty($suggested_keywords)) {
            return new WP_Error('no_keywords', 'No keyword suggestions generated');
        }
        
        $best_keyword = $suggested_keywords[0];
        $confidence_score = $best_keyword['confidence'] ?? 0.5;
        
        $automation_config = get_option('aysa_automation_config', array());
        $threshold = $automation_config['confidence_threshold'] ?? 0.7;
        
        if ($confidence_score >= $threshold) {
            return $this->apply_keyword_assignment($term_id, $best_keyword, $confidence_score);
        } else {
            return $this->queue_keyword_for_review($term_id, $suggested_keywords, $confidence_score);
        }
    }
    
    private function prepare_term_data($term, $job_data) {
        $term_data = array(
            'term_id' => $term->term_id,
            'name' => $term->name,
            'slug' => $term->slug,
            'description' => $term->description,
            'taxonomy' => $term->taxonomy,
            'post_count' => $term->count,
            'related_content' => array()
        );
        
        $posts = get_posts(array(
            'post_type' => $term->taxonomy === 'product_cat' ? 'product' : 'post',
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Reviewed WordPress query: the taxonomy selector is required by the feature and is constrained by the surrounding post type, status, limit, or administrative scope.
            'tax_query' => array(
                array(
                    'taxonomy' => $term->taxonomy,
                    'field' => 'term_id',
                    'terms' => $term->term_id
                )
            ),
            'posts_per_page' => 5,
            'post_status' => 'publish'
        ));
        
        foreach ($posts as $post) {
            $term_data['related_content'][] = array(
                'title' => $post->post_title,
                'content' => wp_strip_all_tags(substr($post->post_content, 0, 500))
            );
        }
        
        return $term_data;
    }
    
    private function generate_keyword_suggestions($term_data) {
        $api_url = $this->api_base_url . 'KeywordAnalysis/suggestKeywords';
        
        $request_data = array(
            'termName' => $term_data['name'],
            'termDescription' => $term_data['description'],
            'taxonomy' => $term_data['taxonomy'],
            'relatedContent' => $term_data['related_content'],
            'postCount' => $term_data['post_count']
        );
        
        $response = wp_remote_post($api_url, array(
            'timeout' => 30,
            'headers' => array(
                'Content-Type' => 'application/json',
                'Accept' => 'application/json'
            ),
            'body' => wp_json_encode($request_data)
        ));
        
        if (is_wp_error($response)) {
            return $this->generate_fallback_keywords($term_data);
        }
        
        $response_code = wp_remote_retrieve_response_code($response);
        if ($response_code !== 200) {
            return $this->generate_fallback_keywords($term_data);
        }
        
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        if (!$data || !isset($data['keywords'])) {
            return $this->generate_fallback_keywords($term_data);
        }
        
        $keywords = array();
        foreach ($data['keywords'] as $keyword_data) {
            $keywords[] = array(
                'keyword' => sanitize_text_field($keyword_data['keyword']),
                'confidence' => floatval($keyword_data['confidence'] ?? 0.5),
                'search_volume' => intval($keyword_data['searchVolume'] ?? 0),
                'competition' => sanitize_text_field($keyword_data['competition'] ?? 'medium')
            );
        }
        
        usort($keywords, function($a, $b) {
            return $b['confidence'] <=> $a['confidence'];
        });
        
        return array_slice($keywords, 0, 5);
    }
    
    private function generate_fallback_keywords($term_data) {
        $keywords = array();
        
        $base_keyword = strtolower($term_data['name']);
        $keywords[] = array(
            'keyword' => $base_keyword,
            'confidence' => 0.6,
            'search_volume' => 0,
            'competition' => 'unknown'
        );
        
        if ($term_data['taxonomy'] === 'product_cat') {
            $keywords[] = array(
                'keyword' => $base_keyword . ' products',
                'confidence' => 0.5,
                'search_volume' => 0,
                'competition' => 'unknown'
            );
            
            $keywords[] = array(
                'keyword' => 'buy ' . $base_keyword,
                'confidence' => 0.4,
                'search_volume' => 0,
                'competition' => 'unknown'
            );
        } else {
            $keywords[] = array(
                'keyword' => $base_keyword . ' tips',
                'confidence' => 0.4,
                'search_volume' => 0,
                'competition' => 'unknown'
            );
            
            $keywords[] = array(
                'keyword' => $base_keyword . ' guide',
                'confidence' => 0.4,
                'search_volume' => 0,
                'competition' => 'unknown'
            );
        }
        
        return $keywords;
    }
    
    private function apply_keyword_assignment($term_id, $keyword_data, $confidence_score) {
        $old_data = array(
            'primary_keyword' => get_term_meta($term_id, 'aysa_primary_keyword', true),
            'secondary_keywords' => get_term_meta($term_id, 'aysa_secondary_keywords', true)
        );
        
        $applied_changes = array();
        
        if (empty($old_data['primary_keyword'])) {
            update_term_meta($term_id, 'aysa_primary_keyword', $keyword_data['keyword']);
            $applied_changes['primary_keyword'] = $keyword_data['keyword'];
        }
        
        update_term_meta($term_id, 'aysa_keyword_confidence', $confidence_score);
        update_term_meta($term_id, 'aysa_keyword_search_volume', $keyword_data['search_volume']);
        update_term_meta($term_id, 'aysa_keyword_competition', $keyword_data['competition']);
        
        $this->audit_logger->log_action(
            'keyword_assignment',
            $term_id,
            'term',
            $old_data,
            $applied_changes,
            $confidence_score,
            true
        );
        
        return array(
            'success' => true,
            'applied_changes' => $applied_changes,
            'confidence_score' => $confidence_score,
            'keyword_data' => $keyword_data,
            'message' => 'Keyword assigned automatically'
        );
    }
    
    private function queue_keyword_for_review($term_id, $suggested_keywords, $confidence_score) {
        $review_data = array(
            'term_id' => $term_id,
            'suggested_keywords' => $suggested_keywords,
            'confidence_score' => $confidence_score,
            'created_at' => current_time('mysql')
        );
        
        $existing_reviews = get_option('aysa_pending_keyword_reviews', array());
        $existing_reviews[$term_id] = $review_data;
        update_option('aysa_pending_keyword_reviews', $existing_reviews);
        
        return array(
            'success' => true,
            'queued_for_review' => true,
            'confidence_score' => $confidence_score,
            'suggestions_count' => count($suggested_keywords),
            'message' => 'Keyword assignment queued for manual review due to low confidence'
        );
    }
    
    public function get_pending_reviews() {
        return get_option('aysa_pending_keyword_reviews', array());
    }
    
    public function approve_keyword_review($term_id, $selected_keyword) {
        $pending_reviews = get_option('aysa_pending_keyword_reviews', array());
        
        if (!isset($pending_reviews[$term_id])) {
            return new WP_Error('review_not_found', 'Pending review not found');
        }
        
        $review_data = $pending_reviews[$term_id];
        
        $selected_keyword_data = null;
        foreach ($review_data['suggested_keywords'] as $keyword_data) {
            if ($keyword_data['keyword'] === $selected_keyword) {
                $selected_keyword_data = $keyword_data;
                break;
            }
        }
        
        if (!$selected_keyword_data) {
            return new WP_Error('invalid_keyword', 'Selected keyword not found in suggestions');
        }
        
        $result = $this->apply_keyword_assignment(
            $term_id, 
            $selected_keyword_data, 
            $review_data['confidence_score']
        );
        
        unset($pending_reviews[$term_id]);
        update_option('aysa_pending_keyword_reviews', $pending_reviews);
        
        return $result;
    }
    
    public function reject_keyword_review($term_id) {
        $pending_reviews = get_option('aysa_pending_keyword_reviews', array());
        
        if (!isset($pending_reviews[$term_id])) {
            return new WP_Error('review_not_found', 'Pending review not found');
        }
        
        unset($pending_reviews[$term_id]);
        update_option('aysa_pending_keyword_reviews', $pending_reviews);
        
        return array(
            'success' => true,
            'message' => 'Keyword assignment review rejected'
        );
    }
}
