<?php
/**
 * Sidebar AJAX Handler for Havenlytics
 *
 * @package     Havenlytics
 * @subpackage  Frontend
 * @copyright   Copyright (c) 2025, Havenlytics
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       2.0.0
 */

namespace HvnlyNab\Frontend;

// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * SidebarAjaxHandler class
 *
 * @since 2.0.0
 */
class SidebarAjaxHandler
{
    /**
     * Sidebar search filters ViewModel
     *
     * @var ViewModels\SidebarSearchFilters
     */
    private $sidebar_filters;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->sidebar_filters = new ViewModels\SidebarSearchFilters();

        add_action('wp_ajax_hvnly_sidebar_filter_search', array($this, 'sidebar_filter_search'));
        add_action('wp_ajax_nopriv_hvnly_sidebar_filter_search', array($this, 'sidebar_filter_search'));

        // Cache invalidation hooks for sidebar
        add_action('save_post_hvnly_property', array($this, 'clear_sidebar_cache'));
        add_action('delete_post', array($this, 'clear_sidebar_cache'));
        add_action('created_term', array($this, 'clear_sidebar_terms_cache'));
        add_action('edited_term', array($this, 'clear_sidebar_terms_cache'));
        add_action('delete_term', array($this, 'clear_sidebar_terms_cache'));
    }

    /**
     * Sidebar filter search with transient caching
     *
     * @return void
     */
    public function sidebar_filter_search() {
        // Unslash and sanitize nonce
        $nonce_raw = filter_input(INPUT_POST, 'nonce', FILTER_UNSAFE_RAW);
        $nonce = $nonce_raw ? sanitize_text_field($nonce_raw) : '';

        if (!wp_verify_nonce($nonce, 'hvnly_ajax_request')) {  
            wp_send_json_error('Security check failed');
        }

        try {
            // Sanitize page and per_page inputs
            $page = absint(filter_input(INPUT_POST, 'page', FILTER_VALIDATE_INT) ?: 1);
            $per_page = absint(filter_input(INPUT_POST, 'per_page', FILTER_VALIDATE_INT) ?: get_option('posts_per_page', 12));

            // Build query args specifically for sidebar filters
            $post_data_raw = filter_input_array(INPUT_POST, FILTER_UNSAFE_RAW) ?: array();
            $post_data = array_map('sanitize_text_field', $post_data_raw); // sanitize all POST fields

            $args = $this->sidebar_filters->build_sidebar_query_args($post_data, $page, $per_page);

            // Generate cache key for sidebar filters
            $cache_key = $this->sidebar_filters->generate_sidebar_cache_key($args, $page, $per_page);

            // Try to get cached sidebar results
            $cached_results = $this->sidebar_filters->get_cached_sidebar_results($args, $page, $per_page);

            if (false !== $cached_results) {
                wp_send_json_success($cached_results);
            }

            // No cache found - perform fresh query
            $properties_query = new \WP_Query($args);

            if (is_wp_error($properties_query->posts)) {
                wp_send_json_error('Query error occurred');
            }

            // Generate response data using existing template system
            $response_data = $this->generate_sidebar_search_response($properties_query, $page, $per_page, $post_data);

            // Cache the sidebar results
            $this->sidebar_filters->set_cached_sidebar_results($cache_key, $response_data);

            wp_send_json_success($response_data);

        } catch (\Exception $e) {
            wp_send_json_error('An error occurred while filtering properties. Please try again.');
        } catch (\Error $e) {
            wp_send_json_error('An error occurred while filtering properties. Please try again.');
        }
    }

    /**
     * Generate sidebar search response data
     *
     * @param \WP_Query $query Properties query
     * @param int       $page Current page
     * @param int       $per_page Posts per page
     * @param array     $filters Current filters
     * @return array
     */
    private function generate_sidebar_search_response($query, $page, $per_page, $filters)
    {
        global $wp_query;

        // Set up global query for template compatibility
        $original_query = $wp_query;
        $wp_query = $query;

        ob_start();

        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                hvnly_get_template_part('content', 'property');
            }
            wp_reset_postdata();
        } else {
            hvnly_get_template_part('content', 'none');
        }

        $html = ob_get_clean();

        // Restore original query
        $wp_query = $original_query;

        // Generate pagination
        ob_start();
        $this->generate_pagination_template($query, $page);
        $pagination_html = ob_get_clean();

        // Generate results count
        ob_start();
        $this->generate_results_count_template($query, $page, $per_page, $filters);
        $results_count_html = ob_get_clean();

        // Calculate start and end for display
        $start = (($page - 1) * $per_page) + 1;
        $end = min($page * $per_page, $query->found_posts);

        return [
            'html' => $html,
            'pagination_html' => $pagination_html,
            'results_count_html' => $results_count_html,
            'found_posts' => $query->found_posts,
            'max_pages' => $query->max_num_pages,
            'current_page' => $page,
            'post_count' => $query->post_count,
            'start' => $start,
            'end' => $end,
            'loaded_count' => min($page * $per_page, $query->found_posts),
        ];
    }

    /**
     * Generate pagination using existing template
     *
     * @param \WP_Query $query Properties query
     * @param int       $current_page Current page number
     * @return void
     */
    private function generate_pagination_template($query, $current_page)
    {
        global $wp_query;

        // Temporarily set the global query for template compatibility
        $original_query = $wp_query;
        $wp_query = $query;

        // Include your existing pagination template
        $template_path = locate_template('havenlytics/search/pagination.php');
        if (!$template_path) {
            $template_path = HVNLYNAB_PATH . 'templates/search/pagination.php';
        }

        if (file_exists($template_path)) {
            // Pass pagination type from global function
            $hvnly_passed_pagination_type = hvnly_get_pagination_type();
            include $template_path;
        }

        // Restore original query
        $wp_query = $original_query;
    }

    /**
     * Generate results count using existing template
     *
     * @param \WP_Query $query Properties query
     * @param int       $current_page Current page number
     * @param int       $per_page Posts per page
     * @param array     $filters Current filters
     * @return void
     */
    private function generate_results_count_template($query, $current_page, $per_page, $filters)
    {
        global $wp_query;

        // Temporarily set the global query for template compatibility
        $original_query = $wp_query;
        $wp_query = $query;

        // Prepare variables for template
        $total_properties = $query->found_posts;
        $start = (($current_page - 1) * $per_page) + 1;
        $end = min($current_page * $per_page, $total_properties);
        
        // Get current department name if filtered
        $hvnly_current_filters = array();
        if (!empty($filters['department'])) {
            $department_term = get_term_by('slug', sanitize_text_field($filters['department']), 'hvnly_prop_depts');
            if ($department_term && !is_wp_error($department_term)) {
                $hvnly_current_filters['property_type'] = array($department_term->name);
            }
        }

        // Get location names if filtered
        if (!empty($filters['hvnly_prop_locations'])) {
            $location_names = array();
            foreach ((array)$filters['hvnly_prop_locations'] as $location_slug) {
                $location_term = get_term_by('slug', $location_slug, 'hvnly_prop_locations');
                if ($location_term) {
                    $location_names[] = $location_term->name;
                }
            }
            if (!empty($location_names)) {
                $hvnly_current_filters['location'] = $location_names;
            }
        }

        // Include your existing results count template
        $template_path = locate_template('havenlytics/search/result-count.php');
        if (!$template_path) {
            $template_path = HVNLYNAB_PATH . 'templates/search/result-count.php';
        }

        if (file_exists($template_path)) {
            // Pass variables to template
            $args = array(
                'total_properties' => $total_properties,
                'start' => $start,
                'end' => $end,
                'current_filters' => $hvnly_current_filters
            );
            extract($args);
            include $template_path;
        }

        // Restore original query
        $wp_query = $original_query;
    }

    /**
     * Clear sidebar cache when property is saved or deleted
     *
     * @param int $post_id Post ID
     * @return void
     */
    public function clear_sidebar_cache($post_id)
    {
        if (get_post_type($post_id) !== 'hvnly_property') {
            return;
        }

        $this->sidebar_filters->clear_all_sidebar_cache();
        do_action('hvnly_cleared_sidebar_property_cache', $post_id);
    }

    /**
     * Clear sidebar cache when terms are modified
     *
     * @param int $term_id Term ID
     * @return void
     */
    public function clear_sidebar_terms_cache($term_id)
    {
        $term = get_term($term_id);
        if (!$term || is_wp_error($term)) {
            return;
        }

        $this->sidebar_filters->clear_all_sidebar_cache();
        do_action('hvnly_cleared_sidebar_terms_cache', $term_id, $term->taxonomy);
    }
}