<?php
/**
 * FluentC WordPress Insert File.
 *
 * This file contains the actions to Insert objects into the html
 *
 * @package FluentCPlugin
 * @author  FluentC <wp@fluentc.io>
 */

namespace FluentC\Actions;

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

use FluentC\Models\Hooks;
use FluentC\Services\Url;
use FluentC\Services\Widget;
use FluentC\Services\Connect;
use FluentC\Utils\Language;

/**
 * Insert interface
 * DOM or HTML changes
 *
 * @since 1.2
 */
class Insert implements Hooks {

	/**
	 * FluentC widget class
	 *
	 * @var object
	 */
	protected $fluentc_widget_c;
	/**
	 * FluentC connection class
	 *
	 * @var object
	 */
	protected $fluentc_language;

	/**
	 * FluentC URL class
	 *
	 * @var object
	 */
	protected $fluentc_url;
	/**
	 * FluentC connection class
	 *
	 * @var object
	 */
	protected $fluentc_connect;

	/**
	 * Constructor
	 *
	 * @since 1.2
	 */
	public function __construct() {
		$this->fluentc_widget_c = new Widget();
		$this->fluentc_connect  = new Connect();
		$this->fluentc_url      = new Url();
		$this->fluentc_language = new Language();
	}
	/**
	 * Hooks for Autoloading
	 *
	 * @since 1.2
	 */
	public function hooks() {
		$api_key = get_option('fluentc_api_key');
    
		// Only add frontend hooks if API key exists.
		if (!empty($api_key)) {
			add_action('wp_enqueue_scripts', array($this, 'insert_fluentc_widget_js'));
			add_action('wp_enqueue_scripts', array($this, 'insert_fluentc_widget'));
			add_action('wp_enqueue_scripts', array($this, 'insert_href_lang'));
			add_action('wp_footer', array($this, 'insert_fluentc_widget_div'));
			add_filter('language_attributes', array($this, 'lang_attribute'), 10, 2);
			add_shortcode('display_fluentc_div', array($this, 'fluentc_display_div'));

			// Suppress WP core's default canonical so it doesn't duplicate the
			// one FluentC (or an SEO plugin overridden below) emits with the
			// translated URL.
			remove_action('wp_head', 'rel_canonical');

			// Each known SEO plugin emits its own canonical; replace its value
			// with the FluentC translated URL so the SEO plugin's tag is correct
			// instead of stacking a second contradictory canonical alongside it.
			add_filter('wpseo_canonical',              array($this, 'fluentc_canonical_url')); // Yoast
			add_filter('rank_math/frontend/canonical', array($this, 'fluentc_canonical_url')); // RankMath
			add_filter('aioseo_canonical_url',         array($this, 'fluentc_canonical_url')); // AIOSEO
			add_filter('seopress_canonical',           array($this, 'fluentc_canonical_url')); // SEOPress
		}
	}
	/**
	 * Update the Language Attribute in the HTML
	 *
	 * @param string $output output of lang.
	 * @param string $doctype doctype.
	 */
	public function lang_attribute( $output, $doctype ) {
		$language_code = $this->fluentc_language->get_fluentc_language();

		// When no translation is active (we're on the source-language
		// page), fall back to the site's source language so <html> still
		// has a lang attribute. Without this, the strip-then-don't-replace
		// branch below left the source page rendering as a bare <html>.
		if ( empty( $language_code ) ) {
			$language_code = $this->fluentc_language->fluentc_site_language();
		}

		// No FluentC language data at all — leave WP's default attribute alone.
		if ( empty( $language_code ) ) {
			return $output;
		}

		// Strip any existing lang attribute (and its leading whitespace so
		// we don't end up with a double space) and append the resolved one.
		$output = preg_replace( '/\s*lang="[^"]*"/', '', $output );
		return $output . ' lang="' . esc_attr( $language_code ) . '"';
	}

	/**
	 * Inserts the FluentC html tag
	 */
	public function insert_fluentc_widget_div() {

		$widgetapikey = get_option( 'fluentc_api_key' );
		if(!$widgetapikey){
			return;
		}
		$widget       = $this->fluentc_connect->fetch_widget_options( $widgetapikey );
		if(!$widget  ){
			return;
		}
		$apperance    = $widget->data->fetchSiteOptions->appearance;
		if ( ! $apperance ) {
			$apperance = 'float';
		}
		if ( 'float' === $apperance ) {
				$this->fluentc_widget_c->insert_fluentc_div();
		}
		// List and Dropdown need the block setup.
	}
	/**
	 * Inserts the WidgetJS
	 */
	public function insert_fluentc_widget_js() {

		$this->fluentc_widget_c->insert_fluentc_js();
	}

	/**
	 * Insert the widget code into the Header
	 */
	public function insert_fluentc_widget() {
		$widgetapikey = get_option( 'fluentc_api_key' );
		if ( $widgetapikey ) {
			$language_code = $this->fluentc_language->get_fluentc_language();
			// if language code issset.
			if ( $language_code ) {
				$fluentc_widget = $this->fluentc_widget_c->insert_fluentc_widget( false, $language_code );
				return $fluentc_widget;
			} else {
				$fluentc_widget = $this->fluentc_widget_c->insert_fluentc_widget( true );
				return $fluentc_widget;
			}
		}
		return;
	}
	/**
	 * Updates Hreflang link
	 */
	public function insert_href_lang() {
		$widgetapikey = get_option('fluentc_api_key');
		if (!$widgetapikey) {
			// Optionally log or handle error, but don't output broken links
			// do_action('qm/error', 'FluentC API Not Set'); 
			return;
		}

		$all_languages = $this->fluentc_connect->get_language_list($widgetapikey);
		if (empty($all_languages) || !is_array($all_languages)) {
			return; // Cannot generate links without language list
		}

		$current_fluentc_language = $this->fluentc_language->get_fluentc_language(); // Language of current page (e.g., 'es', or null/empty for default)
		$site_default_language = $this->fluentc_language->fluentc_site_language(); // Default language of the site (e.g., 'en')

		// Get WordPress installation URL details
		$wp_home_url_option = get_option('home'); // e.g., https://example.com/advisor
		$parsed_wp_home = wp_parse_url($wp_home_url_option);
		$wp_scheme = $parsed_wp_home['scheme'] ?? 'http';
		$wp_host = $parsed_wp_home['host'] ?? '';
		// $wp_base_path will be like "/advisor" or "" (no trailing slash initially)
		$wp_base_path = isset($parsed_wp_home['path']) ? rtrim($parsed_wp_home['path'], '/') : '';

		// Get the language-neutral slug part of the current URL
		// For example, if current URL is /advisor/es/foo/bar?q=1, this should be "foo/bar"
		$language_neutral_current_slug = $this->get_language_neutral_slug($all_languages, $wp_base_path);
		
		// Preserve original query string
		$original_query_string = wp_parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
		$query_suffix = $original_query_string ? '?' . $original_query_string : '';

		// --- Output Canonical URL for the current language ---
		$canonical_path_parts = [$wp_base_path];
		if ($current_fluentc_language && $current_fluentc_language !== $site_default_language) {
			$canonical_path_parts[] = $current_fluentc_language;
		}
		if (!empty($language_neutral_current_slug)) {
			$canonical_path_parts[] = $language_neutral_current_slug;
		}
		
		$canonical_path = implode('/', array_filter($canonical_path_parts, function($part) { return $part !== ''; }));
		// Ensure leading slash, handle empty path for site root + default lang
		$canonical_path = '/' . ltrim($canonical_path, '/');
		if (empty(trim(implode("",$canonical_path_parts),'/')) && $current_fluentc_language && $current_fluentc_language !== $site_default_language){
			 // handles cases like /es/ for homepage of ES if wp_base_path and slug are empty
			 $canonical_path = '/' . $current_fluentc_language . '/';
		}


		// Add trailing slash if the slug part is not empty or if it's a language-only path
		if (!empty($language_neutral_current_slug) || ($current_fluentc_language && $current_fluentc_language !== $site_default_language && empty($language_neutral_current_slug))) {
		    $canonical_path = trailingslashit($canonical_path);
		}
		// Special case for site root in default language (e.g. /advisor/ or /)
		elseif (empty($language_neutral_current_slug) && (!$current_fluentc_language || $current_fluentc_language === $site_default_language)) {
			$canonical_path = trailingslashit($canonical_path);
		}


		$canonical_url = $wp_scheme . '://' . $wp_host . $canonical_path . $query_suffix;

		// Only emit our own canonical when no known SEO plugin is active.
		// When one is active, its *_canonical filter (registered in hooks())
		// already returns the FluentC URL via fluentc_canonical_url(), so
		// emitting again here would duplicate.
		$seo_plugin_active =
			defined('WPSEO_VERSION') ||      // Yoast
			defined('RANK_MATH_VERSION') ||  // RankMath
			defined('AIOSEO_VERSION') ||     // AIOSEO
			defined('SEOPRESS_VERSION');     // SEOPress

		if (!$seo_plugin_active) {
			echo '<link rel="canonical" href="' . esc_url($canonical_url) . '" />' . "";
		}
		echo '<meta name="generator" content="FluentC v' . esc_attr(FLUENTC_TRANSLATION_VERSION) . '" />' . "";

		// --- Output hreflang links ---
		// Captured inside the loop so we can emit a matching x-default
		// link after it, pointing at the site's source-language URL.
		$default_lang_hreflang_url = null;
		foreach ($all_languages as $lang_code) {
			$hreflang_path_parts = [$wp_base_path];
			if ($lang_code !== $site_default_language) {
				$hreflang_path_parts[] = $lang_code;
			}
			if (!empty($language_neutral_current_slug)) {
				$hreflang_path_parts[] = $language_neutral_current_slug;
			}

			$hreflang_path = implode('/', array_filter($hreflang_path_parts, function($part) { return $part !== ''; }));
			$hreflang_path = '/' . ltrim($hreflang_path, '/');
			if (empty(trim(implode("",$hreflang_path_parts),'/')) && $lang_code !== $site_default_language){
				// handles cases like /es/ for homepage of ES if wp_base_path and slug are empty
				$hreflang_path = '/' . $lang_code . '/';
		   }


			// Add trailing slash if the slug part is not empty or if it's a language-only path (for non-default lang)
			if (!empty($language_neutral_current_slug) || ($lang_code !== $site_default_language && empty($language_neutral_current_slug))) {
				$hreflang_path = trailingslashit($hreflang_path);
			} 
			// Special case for site root in default language (e.g. /advisor/ or /)
			elseif (empty($language_neutral_current_slug) && ($lang_code === $site_default_language)) {
				$hreflang_path = trailingslashit($hreflang_path);
			}
			

			$hreflang_url = $wp_scheme . '://' . $wp_host . $hreflang_path . $query_suffix;
			if ($lang_code === $site_default_language) {
				$default_lang_hreflang_url = $hreflang_url;
			}
			echo '<link rel="alternate" hreflang="' . esc_attr($lang_code) . '" href="' . esc_url($hreflang_url) . '" />' . "";
		}

		// x-default points at the source-language URL. Google uses this
		// when a user's locale doesn't match any of the listed hreflang
		// alternates — making the source page the safe default.
		if (!empty($default_lang_hreflang_url)) {
			echo '<link rel="alternate" hreflang="x-default" href="' . esc_url($default_lang_hreflang_url) . '" />' . "";
		}
	}

	/**
	 * Gets the language-neutral slug from the current request URI.
	 * Example: if WP is in /advisor/ and request is /advisor/es/foo/bar, returns "foo/bar".
	 * If WP is in root and request is /es/foo/bar, returns "foo/bar".
	 * If request is /advisor/foo/bar (default lang), returns "foo/bar".
	 *
	 * @param array $all_languages All available language codes.
	 * @param string $wp_base_path The base path of the WordPress installation (e.g., "/advisor" or "").
	 * @return string The language-neutral slug.
	 */
	private function get_language_neutral_slug($all_languages, $wp_base_path) {
		$request_uri = $_SERVER['REQUEST_URI'];
		$path_from_domain_root = rtrim(wp_parse_url($request_uri, PHP_URL_PATH), '/'); // Path like /advisor/es/foo or /foo

		// 1. Remove $wp_base_path from the beginning of $path_from_domain_root
		$path_relative_to_wp_home = $path_from_domain_root;
		if (!empty($wp_base_path) && strpos($path_from_domain_root, $wp_base_path) === 0) {
			$path_relative_to_wp_home = substr($path_from_domain_root, strlen($wp_base_path));
		}
		$path_relative_to_wp_home = ltrim($path_relative_to_wp_home, '/'); // Now like "es/foo" or "foo" or ""

		$segments = explode('/', $path_relative_to_wp_home);

		// 2. Check if the first segment is a language code (and not an empty string from a trailing slash)
		if (!empty($segments[0]) && in_array($segments[0], $all_languages)) {
			array_shift($segments); // Remove language code
		}

		return implode('/', $segments); // Returns "foo" or "foo/bar" or ""
	}

	/**
	 * Filter callback for SEO plugins (Yoast / RankMath / AIOSEO / SEOPress).
	 * Returns the FluentC translated canonical URL so the SEO plugin's
	 * <link rel="canonical"> tag carries our URL instead of its own
	 * source-URL value. Construction mirrors insert_href_lang() above —
	 * keep both in sync.
	 *
	 * @param string $default the SEO plugin's would-be canonical.
	 * @return string
	 */
	public function fluentc_canonical_url($default) {
		$widgetapikey = get_option('fluentc_api_key');
		if (!$widgetapikey) {
			return $default;
		}

		$all_languages = $this->fluentc_connect->get_language_list($widgetapikey);
		if (empty($all_languages) || !is_array($all_languages)) {
			return $default;
		}

		$current_fluentc_language = $this->fluentc_language->get_fluentc_language();
		$site_default_language = $this->fluentc_language->fluentc_site_language();

		$wp_home_url_option = get_option('home');
		$parsed_wp_home = wp_parse_url($wp_home_url_option);
		$wp_scheme = $parsed_wp_home['scheme'] ?? 'http';
		$wp_host = $parsed_wp_home['host'] ?? '';
		$wp_base_path = isset($parsed_wp_home['path']) ? rtrim($parsed_wp_home['path'], '/') : '';

		$language_neutral_current_slug = $this->get_language_neutral_slug($all_languages, $wp_base_path);

		$original_query_string = wp_parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
		$query_suffix = $original_query_string ? '?' . $original_query_string : '';

		$canonical_path_parts = [$wp_base_path];
		if ($current_fluentc_language && $current_fluentc_language !== $site_default_language) {
			$canonical_path_parts[] = $current_fluentc_language;
		}
		if (!empty($language_neutral_current_slug)) {
			$canonical_path_parts[] = $language_neutral_current_slug;
		}

		$canonical_path = implode('/', array_filter($canonical_path_parts, function($part) { return $part !== ''; }));
		$canonical_path = '/' . ltrim($canonical_path, '/');
		if (empty(trim(implode("",$canonical_path_parts),'/')) && $current_fluentc_language && $current_fluentc_language !== $site_default_language){
			 $canonical_path = '/' . $current_fluentc_language . '/';
		}

		if (!empty($language_neutral_current_slug) || ($current_fluentc_language && $current_fluentc_language !== $site_default_language && empty($language_neutral_current_slug))) {
			$canonical_path = trailingslashit($canonical_path);
		}
		elseif (empty($language_neutral_current_slug) && (!$current_fluentc_language || $current_fluentc_language === $site_default_language)) {
			$canonical_path = trailingslashit($canonical_path);
		}

		return $wp_scheme . '://' . $wp_host . $canonical_path . $query_suffix;
	}

	/*
	* Shortcode for displaying FluentC Div.
	*/
public function fluentc_display_div( ) {
  

    $output = '<div id="fluentc-widget"></div>';
    return $output;
}

}
