<?php
/**
 * HVAC Announcements AJAX Handler
 *
 * @package HVAC_Community_Events
 * @since 1.0.0
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class HVAC_Announcements_Ajax
 *
 * Handles AJAX requests for announcement CRUD operations
 */
class HVAC_Announcements_Ajax {
    
    /**
     * Instance of this class
     *
     * @var HVAC_Announcements_Ajax
     */
    private static $instance = null;
    
    /**
     * Get instance of this class
     *
     * @return HVAC_Announcements_Ajax
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        $this->init_hooks();
    }
    
    /**
     * Initialize AJAX hooks
     */
    private function init_hooks() {
        // AJAX actions for logged-in users
        add_action('wp_ajax_hvac_get_announcements', array($this, 'get_announcements'));
        add_action('wp_ajax_hvac_get_announcement', array($this, 'get_announcement'));
        add_action('wp_ajax_hvac_create_announcement', array($this, 'create_announcement'));
        add_action('wp_ajax_hvac_update_announcement', array($this, 'update_announcement'));
        add_action('wp_ajax_hvac_delete_announcement', array($this, 'delete_announcement'));
        add_action('wp_ajax_hvac_get_announcement_categories', array($this, 'get_categories'));
        add_action('wp_ajax_hvac_get_announcement_tags', array($this, 'get_tags'));
        add_action('wp_ajax_hvac_view_announcement', array($this, 'view_announcement'));
        
        // Clear cache when announcements are modified
        add_action('save_post_' . HVAC_Announcements_CPT::get_post_type(), array($this, 'clear_announcements_cache'));
        add_action('delete_post', array($this, 'maybe_clear_announcements_cache'));
        add_action('transition_post_status', array($this, 'clear_announcements_cache_on_status_change'), 10, 3);
    }
    
    /**
     * Clear all announcements caches
     */
    public function clear_announcements_cache() {
        // Clear all cached announcement lists by flushing the group
        // Since we can't iterate cache keys in standard WP, we'll use a version key approach
        $version = wp_cache_get('announcements_cache_version', 'hvac_announcements');
        if (false === $version) {
            $version = 1;
        } else {
            $version++;
        }
        wp_cache_set('announcements_cache_version', $version, 'hvac_announcements', 0);
    }
    
    /**
     * Maybe clear announcements cache when a post is deleted
     *
     * @param int $post_id Post ID
     */
    public function maybe_clear_announcements_cache($post_id) {
        $post = get_post($post_id);
        if ($post && $post->post_type === HVAC_Announcements_CPT::get_post_type()) {
            $this->clear_announcements_cache();
        }
    }
    
    /**
     * Clear cache when announcement status changes
     *
     * @param string $new_status New status
     * @param string $old_status Old status  
     * @param WP_Post $post Post object
     */
    public function clear_announcements_cache_on_status_change($new_status, $old_status, $post) {
        if ($post->post_type === HVAC_Announcements_CPT::get_post_type()) {
            $this->clear_announcements_cache();
        }
    }
    
    /**
     * Check rate limiting for AJAX requests
     *
     * @return bool True if within limits, sends error and exits if exceeded
     */
    private function check_rate_limit() {
        $user_id = get_current_user_id();
        $transient_key = 'hvac_ajax_rate_' . $user_id;
        $request_count = get_transient($transient_key);
        
        if (false === $request_count) {
            $request_count = 0;
        }
        
        // Allow 30 requests per minute
        if ($request_count >= 30) {
            wp_send_json_error('Rate limit exceeded. Please wait a moment and try again.');
            exit;
        }
        
        // Increment and set transient for 60 seconds
        set_transient($transient_key, $request_count + 1, 60);
        
        return true;
    }
    
    /**
     * Get paginated announcements
     */
    public function get_announcements() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        // Check permissions
        if (!HVAC_Announcements_Permissions::current_user_can_read()) {
            wp_send_json_error('Insufficient permissions');
        }
        
        // Get parameters
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        $per_page = isset($_POST['per_page']) ? intval($_POST['per_page']) : 20;
        $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : 'any';
        $search = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : '';
        
        // Build cache key based on parameters, user role, and cache version
        $is_master = HVAC_Announcements_Permissions::is_master_trainer();
        $cache_version = wp_cache_get('announcements_cache_version', 'hvac_announcements');
        if (false === $cache_version) {
            $cache_version = 1;
        }
        
        $cache_key = 'hvac_announcements_v' . $cache_version . '_' . md5(serialize(array(
            'page' => $page,
            'per_page' => $per_page,
            'status' => $status,
            'search' => $search,
            'is_master' => $is_master
        )));
        
        // Try to get from cache
        $cached_response = wp_cache_get($cache_key, 'hvac_announcements');
        if ($cached_response !== false && empty($search)) { // Don't cache search results
            wp_send_json_success($cached_response);
            return;
        }
        
        // Build query args
        $args = array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'posts_per_page' => $per_page,
            'paged' => $page,
            'orderby' => 'date',
            'order' => 'DESC',
        );
        
        // Filter by status
        if ($status !== 'any') {
            $args['post_status'] = $status;
        } else {
            $args['post_status'] = array('publish', 'draft', 'private');
        }
        
        // Add search
        if (!empty($search)) {
            $args['s'] = $search;
        }
        
        // For non-master trainers, only show published announcements
        if (!$is_master) {
            $args['post_status'] = 'publish';
        }
        
        // Query announcements
        $query = new WP_Query($args);
        
        $announcements = array();
        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                
                $categories = wp_get_post_terms(get_the_ID(), HVAC_Announcements_CPT::get_category_taxonomy(), array('fields' => 'names'));
                $tags = wp_get_post_terms(get_the_ID(), HVAC_Announcements_CPT::get_tag_taxonomy(), array('fields' => 'names'));
                
                $announcements[] = array(
                    'id' => get_the_ID(),
                    'title' => get_the_title(),
                    'excerpt' => wp_kses_post(get_the_excerpt()), // Sanitize HTML content
                    'status' => get_post_status(),
                    'date' => get_the_date('Y-m-d H:i:s'),
                    'author' => get_the_author(),
                    'categories' => $categories,
                    'tags' => $tags,
                    'featured_image' => get_the_post_thumbnail_url(get_the_ID(), 'thumbnail'),
                    'can_edit' => HVAC_Announcements_Permissions::current_user_can_edit(get_the_ID()),
                    'can_delete' => HVAC_Announcements_Permissions::current_user_can_delete(get_the_ID()),
                );
            }
            wp_reset_postdata();
        }
        
        $response = array(
            'announcements' => $announcements,
            'total' => $query->found_posts,
            'pages' => $query->max_num_pages,
            'current_page' => $page,
        );
        
        // Cache the response if not a search query (cache for 2 minutes)
        if (empty($search)) {
            wp_cache_set($cache_key, $response, 'hvac_announcements', 120);
        }
        
        wp_send_json_success($response);
    }
    
    /**
     * Get single announcement for editing
     */
    public function get_announcement() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        $post_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
        
        if (!$post_id) {
            wp_send_json_error('Invalid announcement ID');
        }
        
        // Check permissions
        if (!HVAC_Announcements_Permissions::current_user_can_edit($post_id)) {
            wp_send_json_error('Insufficient permissions');
        }
        
        $post = get_post($post_id);
        
        if (!$post || $post->post_type !== HVAC_Announcements_CPT::get_post_type()) {
            wp_send_json_error('Announcement not found');
        }
        
        $categories = wp_get_post_terms($post_id, HVAC_Announcements_CPT::get_category_taxonomy(), array('fields' => 'ids'));
        $tags = wp_get_post_terms($post_id, HVAC_Announcements_CPT::get_tag_taxonomy(), array('fields' => 'names'));
        
        $announcement = array(
            'id' => $post->ID,
            'title' => $post->post_title,
            'content' => $post->post_content,
            'excerpt' => $post->post_excerpt,
            'status' => $post->post_status,
            'date' => $post->post_date,
            'categories' => $categories,
            'tags' => implode(', ', $tags),
            'featured_image_id' => get_post_thumbnail_id($post->ID),
            'featured_image_url' => get_the_post_thumbnail_url($post->ID, 'medium'),
        );
        
        wp_send_json_success($announcement);
    }
    
    /**
     * Create new announcement
     */
    public function create_announcement() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        // Check permissions
        if (!HVAC_Announcements_Permissions::current_user_can_create()) {
            wp_send_json_error('Insufficient permissions');
        }
        
        // Validate required fields
        if (empty($_POST['title'])) {
            wp_send_json_error('Title is required');
        }
        
        // Prepare post data
        $post_data = array(
            'post_title' => sanitize_text_field($_POST['title']),
            'post_content' => wp_kses_post($_POST['content']),
            'post_excerpt' => sanitize_textarea_field($_POST['excerpt']),
            'post_status' => sanitize_text_field($_POST['status']),
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_author' => get_current_user_id(),
        );
        
        // Set publish date if provided
        if (!empty($_POST['publish_date'])) {
            $post_data['post_date'] = sanitize_text_field($_POST['publish_date']);
            $post_data['post_date_gmt'] = get_gmt_from_date($post_data['post_date']);
        }
        
        // Create post
        $post_id = wp_insert_post($post_data);
        
        if (is_wp_error($post_id)) {
            wp_send_json_error($post_id->get_error_message());
        }
        
        // Set categories
        if (!empty($_POST['categories'])) {
            $categories = array_map('intval', (array) $_POST['categories']);
            wp_set_post_terms($post_id, $categories, HVAC_Announcements_CPT::get_category_taxonomy());
        }
        
        // Set tags
        if (!empty($_POST['tags'])) {
            $tags = array_map('trim', explode(',', sanitize_text_field($_POST['tags'])));
            wp_set_post_terms($post_id, $tags, HVAC_Announcements_CPT::get_tag_taxonomy());
        }
        
        // Set featured image
        if (!empty($_POST['featured_image_id'])) {
            set_post_thumbnail($post_id, intval($_POST['featured_image_id']));
        }
        
        wp_send_json_success(array(
            'id' => $post_id,
            'message' => __('Announcement created successfully', 'hvac'),
        ));
    }
    
    /**
     * Update existing announcement
     */
    public function update_announcement() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        $post_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
        
        if (!$post_id) {
            wp_send_json_error('Invalid announcement ID');
        }
        
        // Check permissions
        if (!HVAC_Announcements_Permissions::current_user_can_edit($post_id)) {
            wp_send_json_error('Insufficient permissions');
        }
        
        // Validate required fields
        if (empty($_POST['title'])) {
            wp_send_json_error('Title is required');
        }
        
        // Prepare post data
        $post_data = array(
            'ID' => $post_id,
            'post_title' => sanitize_text_field($_POST['title']),
            'post_content' => wp_kses_post($_POST['content']),
            'post_excerpt' => sanitize_textarea_field($_POST['excerpt']),
            'post_status' => sanitize_text_field($_POST['status']),
        );
        
        // Set publish date if provided
        if (!empty($_POST['publish_date'])) {
            $post_data['post_date'] = sanitize_text_field($_POST['publish_date']);
            $post_data['post_date_gmt'] = get_gmt_from_date($post_data['post_date']);
        }
        
        // Update post
        $result = wp_update_post($post_data);
        
        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }
        
        // Update categories
        if (isset($_POST['categories'])) {
            $categories = array_map('intval', (array) $_POST['categories']);
            wp_set_post_terms($post_id, $categories, HVAC_Announcements_CPT::get_category_taxonomy());
        }
        
        // Update tags
        if (isset($_POST['tags'])) {
            $tags = array_map('trim', explode(',', sanitize_text_field($_POST['tags'])));
            wp_set_post_terms($post_id, $tags, HVAC_Announcements_CPT::get_tag_taxonomy());
        }
        
        // Update featured image
        if (isset($_POST['featured_image_id'])) {
            if (empty($_POST['featured_image_id'])) {
                delete_post_thumbnail($post_id);
            } else {
                set_post_thumbnail($post_id, intval($_POST['featured_image_id']));
            }
        }
        
        wp_send_json_success(array(
            'id' => $post_id,
            'message' => __('Announcement updated successfully', 'hvac'),
        ));
    }
    
    /**
     * Delete announcement
     */
    public function delete_announcement() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        $post_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
        
        if (!$post_id) {
            wp_send_json_error('Invalid announcement ID');
        }
        
        // Check permissions
        if (!HVAC_Announcements_Permissions::current_user_can_delete($post_id)) {
            wp_send_json_error('Insufficient permissions');
        }
        
        // Delete post
        $result = wp_delete_post($post_id, true); // Force delete
        
        if (!$result) {
            wp_send_json_error('Failed to delete announcement');
        }
        
        wp_send_json_success(array(
            'message' => __('Announcement deleted successfully', 'hvac'),
        ));
    }
    
    /**
     * Get categories for select options
     */
    public function get_categories() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        // Check permissions - only users who can create announcements need category list
        if (!HVAC_Announcements_Permissions::current_user_can_create()) {
            wp_send_json_error('Insufficient permissions');
        }
        
        $categories = get_terms(array(
            'taxonomy' => HVAC_Announcements_CPT::get_category_taxonomy(),
            'hide_empty' => false,
        ));
        
        $options = array();
        if (!is_wp_error($categories)) {
            foreach ($categories as $category) {
                $options[] = array(
                    'id' => $category->term_id,
                    'name' => $category->name,
                );
            }
        }
        
        wp_send_json_success($options);
    }
    
    /**
     * Get tags for autocomplete
     */
    public function get_tags() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        // Check permissions - only users who can create announcements need tag list
        if (!HVAC_Announcements_Permissions::current_user_can_create()) {
            wp_send_json_error('Insufficient permissions');
        }
        
        $tags = get_terms(array(
            'taxonomy' => HVAC_Announcements_CPT::get_tag_taxonomy(),
            'hide_empty' => false,
        ));
        
        $tag_names = array();
        if (!is_wp_error($tags)) {
            foreach ($tags as $tag) {
                $tag_names[] = $tag->name;
            }
        }
        
        wp_send_json_success($tag_names);
    }
    
    /**
     * Get announcement content for modal viewing
     */
    public function view_announcement() {
        // Check rate limiting
        $this->check_rate_limit();
        
        // Verify nonce
        if (!check_ajax_referer('hvac_announcements_nonce', 'nonce', false)) {
            wp_send_json_error('Invalid security token');
        }
        
        $post_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
        
        if (!$post_id) {
            wp_send_json_error('Invalid announcement ID');
        }
        
        // Check permissions - only need read permission for viewing
        if (!HVAC_Announcements_Permissions::current_user_can_read()) {
            wp_send_json_error('Insufficient permissions');
        }
        
        // Check post status - only allow published posts for non-master trainers
        $post = get_post($post_id);
        if (!$post || $post->post_type !== HVAC_Announcements_CPT::get_post_type()) {
            wp_send_json_error('Announcement not found');
        }
        
        // Only allow viewing of published posts unless user is a master trainer
        if ($post->post_status !== 'publish' && !HVAC_Announcements_Permissions::is_master_trainer()) {
            wp_send_json_error('You do not have permission to view this announcement');
        }
        
        // Get announcement data
        $title = get_the_title($post);
        $content = apply_filters('the_content', $post->post_content);
        $date = get_the_date('F j, Y', $post);
        $author = get_the_author_meta('display_name', $post->post_author);
        
        wp_send_json_success(array(
            'title' => $title,
            'content' => $content,
            'date' => $date,
            'author' => $author
        ));
    }
}