<?php
/**
 * FluentC WordPress File.
 *
 * This file contains the WordPress functions for updating WordPress.
 *
 * @package FluentCPlugin
 */

namespace FluentC\Actions;

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

use FluentC\Models\Hooks;
use FluentC\Models\Htmltags;
use FluentC\Services\Connect;
use FluentC\Utils\Language;
use FluentC\Services\Cache;
use FluentC\Services\Html_Processor;
use FluentC\Services\Translation_Manager;

/**
 * WordPress specific modifications
 */
class Wordpress implements Hooks {

    /**
     * FluentC connection class
     *
     * @var Connect
     */
    protected $fluentc_connect;

    /**
     * FluentC Html tags class
     *
     * @var Htmltags
     */
    protected $fluentc_htmltags;

    /**
     * FluentC language class
     *
     * @var Language
     */
    protected $fluentc_language;

    /**
     * FluentC cache class
     *
     * @var Cache
     */
    protected $fluentc_cache;

    /**
     * Translated text
     *
     * @var array
     */
    protected $translated_text;

    /**
     * Current language code
     *
     * @var string|null
     */
    protected $language_code;

    /**
     * Site default language
     *
     * @var string
     */
    protected $site_language;

    /**
     * FluentC API Key
     *
     * @var string
     */
    protected $widgetapikey;
 
    /**
     * HtmlProcessor instance
     *
     * @var Html_Processor|null
     */
    protected $htmlProcessor;

    /**
     * Translation manager
     *
     * @var Translation_Manager|null
     */
    private $translation_manager;
    
    /**
     * Flag to track if output buffer is active
     *
     * @var bool
     */
    private $output_buffer_active = false;
    
    /**
     * Constructor.
     *
     * @since 1.2
     */
    public function __construct() {
        $this->fluentc_connect = new Connect();
        $this->fluentc_language = new Language();
        $this->fluentc_htmltags = new Htmltags();
        $this->fluentc_cache = new Cache();
        $this->translated_text = array();
        $this->widgetapikey = get_option('fluentc_api_key');
        
        // Get language information using the improved methods
        // This will get the current language from globals or query vars
        $this->language_code = function_exists('fluentc_get_current_language') 
            ? fluentc_get_current_language() 
            : $this->fluentc_language->get_fluentc_language();
        
        // Get site default language
        $this->site_language = function_exists('fluentc_get_default_language')
            ? fluentc_get_default_language()
            : $this->fluentc_language->fluentc_site_language();
            
        // Initialize HTML processor if we have an API key and a language code
        if (!empty($this->widgetapikey) && !empty($this->language_code)) {
            $this->init_html_processor();
        }
    }

    /**
     * Initialize HTML Processor
     *
     * @return void
     */
    protected function init_html_processor() {
        try {
            $this->htmlProcessor = new Html_Processor();
        } catch (\Exception $e) {
            error_log('FluentC: Error initializing HTML Processor: ' . $e->getMessage());
            $this->htmlProcessor = null;
        }
    }

    /**
     * Hooks for Autoloading
     *
     * @since 1.2
     */
    public function hooks() {
        // Check for API key before adding most hooks
        $api_key = get_option('fluentc_api_key');
        if (empty($api_key)) {
            // Only add essential hooks for configuration
            add_action('admin_notices', array($this, 'admin_notice_missing_api_key'));
            return;
        }
        
        add_filter('woocommerce_ajax_get_endpoint', array($this, 'correct_multilingual_ajax_endpoint'), 100, 2);
        add_action('init', array($this, 'init_output_buffering'), 0);
        add_action('shutdown', array($this, 'fluentc_flush_output_buffer'), 0);
        
        // Add hook to refresh language code after it might have been set.
        add_action('fluentc_language_set', array($this, 'refresh_language_code'));

        // Translate WP Grid Builder REST responses when available
        add_filter('wp_grid_builder/rest_api/response', array($this, 'filter_wpgb_rest_response'), 10, 2);
        
    }
    
    /**
     *  
     *  Add a notice to remind users to configure the plugin
     * 
     */
    public function admin_notice_missing_api_key() {
        if (!current_user_can('manage_options') || (function_exists('get_current_screen') && get_current_screen()->id === 'toplevel_page_fluentc-settings')) {
            return;
        }
        
        echo '<div class="notice notice-warning is-dismissible">';
        echo '<p><strong>FluentC Translation:</strong> ';
        echo 'Please <a href="' . admin_url('admin.php?page=fluentc-settings') . '">configure your API key</a> to enable translation features.</p>';
        echo '</div>';
    }
    
    /**
     * Refreshes the language code when it changes
     *
     * @param string $language_code The new language code
     * @return void
     */
    public function refresh_language_code($language_code) {
        $this->language_code = $language_code;
        
        // Reset translation manager to use new language
        $this->translation_manager = null;
        
        // Re-initialize HTML processor
        if (!empty($this->widgetapikey) && !empty($this->language_code)) {
            $this->init_html_processor();
        }
    }

    /**
     * Corrects WooCommerce AJAX endpoints in multilingual context
     *
     * @param string $endpoint The endpoint URL
     * @param string $request The request
     * @return string The corrected endpoint URL
     */
    public function correct_multilingual_ajax_endpoint($endpoint, $request) {
        // Validate the endpoint URL
        if (empty($endpoint) || !is_string($endpoint)) {
            return $endpoint;
        }
    
        // Get the site's home URL
        $home_url = home_url('/');
        
        // Parse the current URL
        $parsed_url = parse_url($endpoint);
        
        // Check if parse_url returned false or didn't return an array
        if ($parsed_url === false || !is_array($parsed_url)) {
            return $endpoint;
        }
        
        // If the host is missing or incorrect, rebuild the URL
        if (!isset($parsed_url['host']) || $parsed_url['host'] !== parse_url($home_url, PHP_URL_HOST)) {
            $corrected_endpoint = $home_url;
            
            // Check if path exists before trying to access it
            if (isset($parsed_url['path'])) {
                // Remove the leading slash if it exists
                $path = ltrim($parsed_url['path'], '/');
                $corrected_endpoint .= $path;
            }
            
            // Add query parameters if they exist
            if (isset($parsed_url['query'])) {
                $corrected_endpoint .= '?' . $parsed_url['query'];
            }
            
            // Add language code if available and using global function
            if (function_exists('fluentc_add_language_to_url') && $this->language_code) {
                $corrected_endpoint = fluentc_add_language_to_url($corrected_endpoint);
            }
            
            return $corrected_endpoint;
        }
        
        return $endpoint;
    }

    /**
     * Initialize output buffering
     *
     * @return void
     */
    public function init_output_buffering() {
        // Prevent initializing output buffering multiple times
        if ($this->output_buffer_active) {
            return;
        }
        
        // Modified condition - handle AJAX requests differently
        $is_f_ajax = defined('DOING_AJAX') && DOING_AJAX;
        
        // Allow AJAX requests with language parameter to proceed or if hitting custom handler
        if ((is_admin() && !$is_f_ajax) || 
            is_404() || 
            defined('DOING_CRON') || 
            wp_is_xml_request() ||
            ($is_f_ajax && !isset($_REQUEST['fluentc_language']))) {
            return;
        }
        if (is_null($this->language_code) || $this->language_code === $this->site_language) {
            return;
        }
        
        // Make sure htmlProcessor is initialized before starting buffering
        if (empty($this->htmlProcessor) && !empty($this->widgetapikey) && !empty($this->language_code)) {
            $this->init_html_processor();
        }
        
        // Only start buffering if we have a processor ready
        if (!is_null($this->htmlProcessor)) {
            ob_start(array($this, 'process_final_output'));
            $this->output_buffer_active = true;
        }
    }

    /**
     * Process final output before sending to browser
     *
     * @param string $buffer The buffer content
     * @return string The processed content
     */
    public function process_final_output($buffer) {
        // Don't process admin pages
        if (defined('DOING_CRON') || wp_is_xml_request()) {
            return $buffer;
        }
        
        // Don't process RSS feeds
        if (is_feed()) {
            return $buffer;
        }

        // Process regular HTML content
        return $this->filter_content($buffer);
    }

    /**
     * Check if string is valid JSON
     *
     * @param string $string The string to check
     * @return bool True if valid JSON
     */
    private function is_json($string) {
        if (!is_string($string) || empty($string)) {
            return false;
        }
        
        json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }

    /**
     * Flush output buffer
     *
     * @return void
     */
    public function fluentc_flush_output_buffer() {
        // Only flush if we've started the buffer
        if ($this->output_buffer_active) {
            if (ob_get_level()) {
                ob_end_flush();
            }
            $this->output_buffer_active = false;
        }
    }

    /**
     * Filter content for translation
     *
     * @param string $content The content to filter
     * @return string The filtered content
     */
    public function filter_content($content) {
        if (!$this->should_process_content($content)) {
            return $content;
        }
        
        // If htmlProcessor is not initialized, try to initialize it now
        if (is_null($this->htmlProcessor)) {
            $this->init_html_processor();
            
            // If still null, return original content
            if (is_null($this->htmlProcessor)) {
                error_log('FluentC: HTML Processor not available - returning original content');
                return $content;
            }
        }
       
        // Get the current request path
        $path = $this->get_request_path();
        
        // Process the content using Base64 HTML processing
        try {
            $html = $this->htmlProcessor->processBase64Html(
                $this->widgetapikey,
                $content, 
                $this->site_language, 
                $this->language_code,
                $path
            );
            do_action('fluentc_after_translation');
            return $html ?: $content;
        } catch (\Exception $e) {
            error_log('FluentC: Error processing content: ' . $e->getMessage());
            return $content;
        }
    }

    /**
     * Check if content should be processed
     *
     * @param string $content The content to check
     * @return bool True if content should be processed
     */
    private function should_process_content($content) {
        // Need a language code different from site language, and the content must not be empty
        return $this->language_code && 
               $this->language_code !== $this->site_language && 
               !is_null($content) && 
               $content !== '';
    }

    /**
     * Get the current request path without language code
     *
     * @return string The request path
     */
    private function get_request_path() {
        // Start with the REQUEST_URI
        $request_uri = $_SERVER['REQUEST_URI'] ?? '/';
        
        // Parse the URL to get just the path
        $parsed = parse_url($request_uri);
        $path = $parsed['path'] ?? '/';
        
        // Get the home URL to determine if WordPress is in a subdirectory
        $home_url = home_url('/');
        $home_path = parse_url($home_url, PHP_URL_PATH);
        
        // Remove the home path from the beginning if WordPress is in a subdirectory
        if (!empty($home_path) && $home_path !== '/' && strpos($path, $home_path) === 0) {
            $path = substr($path, strlen($home_path));
        }
        
        // Ensure path starts with /
        if (empty($path) || $path[0] !== '/') {
            $path = '/' . $path;
        }
        
        // Remove language code from path if present
        $path = $this->remove_language_code_from_path($path);
        
        // Remove trailing slash unless it's just "/"
        if (strlen($path) > 1 && substr($path, -1) === '/') {
            $path = rtrim($path, '/');
        }
        
        return $path;
    }

    /**
     * Remove language code from path
     *
     * @param string $path The path to clean
     * @return string The cleaned path
     */
    private function remove_language_code_from_path($path) {
        // Get available languages
        if (function_exists('fluentc_get_available_languages')) {
            $languages = fluentc_get_available_languages();
        } else {
            // Fallback: get languages from the FluentC connect service
            $widgetapikey = get_option('fluentc_api_key');
            if (!empty($widgetapikey)) {
                $connect = new Connect();
                $languages = $connect->get_language_list($widgetapikey);
            } else {
                $languages = array();
            }
        }
        
        // If we have languages, try to remove them from the path
        if (!empty($languages) && is_array($languages)) {
            foreach ($languages as $lang) {
                // Check for language code at the beginning of the path
                // Patterns: /en/, /en-us/, /en_US/
                $lang_code = is_string($lang) ? $lang : (isset($lang->slug) ? $lang->slug : null);
                if (!empty($lang_code)) {
                    // Try to match the language code at the start of the path
                    if (preg_match('#^/(' . preg_quote($lang_code, '#') . ')(/|$)#i', $path, $matches)) {
                        $path = substr($path, strlen($matches[0]) - 1);
                        if (empty($path)) {
                            $path = '/';
                        }
                        break;
                    }
                }
            }
        }
        
        return $path;
    }


    /**
     * Filter WP Grid Builder REST API responses for translation by processing the entire payload.
     *
     * @param mixed            $response The REST response (array, object, string or WP_REST_Response).
     * @param \WP_REST_Request $request  The current REST request instance.
     * @return mixed The filtered response.
     */
    public function filter_wpgb_rest_response($response, $request) {
        if (is_wp_error($response)) {
            return $response;
        }

        if (is_null($this->language_code) || $this->language_code === $this->site_language) {
            return $response;
        }

        if ($response instanceof \WP_REST_Response) {
            $data = $response->get_data();
            $translated = $this->translate_rest_payload($data);
            if (!is_null($translated)) {
                $response->set_data($translated);
            }
            return $response;
        }

        if (is_array($response) || is_object($response)) {
            $translated = $this->translate_rest_payload($response);
            return is_null($translated) ? $response : $translated;
        }

        if (is_string($response)) {
            $translated = $this->filter_content($response);
            return $translated ?: $response;
        }

        return $response;
    }

    /**
     * Translate an entire REST payload by sending the JSON document to the translation service.
     *
     * @param mixed $payload Original payload (array|object).
     * @return array|null Translated payload array or null on failure.
     */
    private function translate_rest_payload($payload) {
        $json = wp_json_encode($payload);
        if ($json === false || $json === null) {
            return null;
        }

        $translated = $this->filter_content($json);
        if (empty($translated) || $translated === $json) {
            return null;
        }

        $decoded = json_decode($translated, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            error_log('FluentC: Unable to decode translated REST payload: ' . json_last_error_msg());
            return null;
        }

        return $decoded;
    }


    /**
     * Process JSON content
     *
     * @param string $json_string The JSON string to process
     * @return string The processed JSON string
     */
    public function process_json($json_string) {
        // Decode the JSON string
        $data = json_decode($json_string, true);
    
        // Return original if not a valid array
        if (!is_array($data)) {
            return $json_string;
        }
    
        // Process each facet
        if (isset($data['facets']) && is_array($data['facets'])) {
            foreach ($data['facets'] as $key => &$facet) {
                if (isset($facet['html'])) {
                    $processed_html = $this->filter_content($facet['html']);
                    $facet['html'] = $processed_html;
                }
        
                // Process name if it exists
                if (isset($facet['name'])) {
                    $facet['name'] = $this->filter_content($facet['name']);
                }
            }
        }
        
        // Process posts HTML if present
        if (isset($data['posts']) && is_string($data['posts'])) {
            $processed_html = $this->filter_content($data['posts']);
            $data['posts'] = $processed_html;
        }
        
        // Process content if present
        if (isset($data['content']) && is_string($data['content'])) {
            $processed_html = $this->filter_content($data['content']);
            $data['content'] = $processed_html;
        }
        
        // Encode the updated data back to JSON
        return json_encode($data);
    }

    /**
     * Clear translated text array
     *
     * @param mixed $content Not used
     * @return void
     */
    public function fluentc_shutdown($content) {
        // Empties the translated text cache
        $this->translated_text = array();
    }

    
}