<?php
if (!defined('ABSPATH')) exit;

/**
 * Server-side, SEO-relevant localization:
 * - <title> (pre_get_document_title)
 * - <meta name="description"> (wp_head, if no SEO plugin takes over)
 * - Yoast & Rank Math hooks
 *
 * Source priority per key:
 *   DB  >  SEO JSON (i18n/seo/{locale}.json)  >  regular JSON  >  fallback
 *
 * Special logic:
 * - Canonical (English) keys per page can be mapped via "aliases" in the SEO JSON,
 *   e.g. de-DE: {"aliases":{"leistungen":"services","kontakt":"contact"}}
 * - Optional: global option "awxct_seo_aliases" (JSON) to merge additional aliases.
 */
class AWXCT_SEO_Meta {

  public static function init() {
    // Native WP
    add_filter('pre_get_document_title', [__CLASS__, 'filter_wp_title'], 20);
    add_action('wp_head', [__CLASS__, 'print_meta_description'], 1);

    // Yoast
    add_filter('wpseo_title',               [__CLASS__, 'filter_yoast_title'], 20);
    add_filter('wpseo_metadesc',            [__CLASS__, 'filter_yoast_desc'],  20);
    add_filter('wpseo_opengraph_title',     [__CLASS__, 'filter_yoast_title'], 20);
    add_filter('wpseo_opengraph_desc',      [__CLASS__, 'filter_yoast_desc'],  20);
    add_filter('wpseo_twitter_title',       [__CLASS__, 'filter_yoast_title'], 20);
    add_filter('wpseo_twitter_description', [__CLASS__, 'filter_yoast_desc'],  20);

    // Rank Math
    add_filter('rank_math/frontend/title',        [__CLASS__, 'filter_rankmath_title'], 20);
    add_filter('rank_math/frontend/description',  [__CLASS__, 'filter_rankmath_desc'],  20);
    add_filter('rank_math/opengraph/facebook/title',       [__CLASS__, 'filter_rankmath_title'], 20);
    add_filter('rank_math/opengraph/facebook/description', [__CLASS__, 'filter_rankmath_desc'],  20);
    add_filter('rank_math/opengraph/twitter/title',        [__CLASS__, 'filter_rankmath_title'], 20);
    add_filter('rank_math/opengraph/twitter/description',  [__CLASS__, 'filter_rankmath_desc'],  20);
  }

  /* ================= Helpers ================= */

  private static function lang(): string {
    return apply_filters('awxct_current_lang', '') ?: get_locale();
  }

  // Fetch value with priority: DB > SEO JSON > regular JSON > fallback
  private static function get(string $key, string $fallback = ''): string {
    if (function_exists('awxct_get_json_value')) {
      $val = awxct_get_json_value(self::lang(), $key, $fallback);
    } else {
      $val = $fallback;
    }
    return is_string($val) ? $val : $fallback;
  }

  // Load aliases: Option → SEO JSON → filter (merged). Keys lower-cased.
  private static function aliases(string $locale): array {
    static $cache = [];
    if (isset($cache[$locale])) return $cache[$locale];

    $map = [];

    // 1) Option (JSON or array): awxct_seo_aliases
    $opt = get_option('awxct_seo_aliases', []);
    if (is_string($opt)) {
      $tmp = json_decode($opt, true);
      if (is_array($tmp)) $opt = $tmp;
    }
    if (is_array($opt) && isset($opt[$locale]) && is_array($opt[$locale])) {
      $map = $opt[$locale];
    }

    // 3) Filter extension point (default: return $map as is)
    $map = apply_filters('awxct_seo_aliases', $map, $locale);

    // Normalize
    $norm = [];
    foreach ((array)$map as $k => $v) {
      if ($k === '' || $v === '' || !is_string($k) || !is_string($v)) continue;
      $norm[strtolower(trim($k))] = trim($v);
    }

    return $cache[$locale] = $norm;
  }

  // Provide a priority list of possible keys for the current context
  private static function ctx_keys(string $what): array {
    $keys = [];
    $loc  = self::lang();

    if (is_front_page() || (is_home() && !is_front_page())) {
      $keys[] = "meta.home.$what";
    } elseif (is_singular()) {
      $post = get_queried_object();
      $pt   = get_post_type($post) ?: 'post';
      $slug = $post->post_name ?? '';
      $id   = (string) ($post->ID ?? '');

      // Apply alias (local slug -> canonical English key)
      $aliasMap  = self::aliases($loc);
      $canonSlug = $slug && isset($aliasMap[strtolower($slug)]) ? $aliasMap[strtolower($slug)] : $slug;

      // most specific → generic
      if ($canonSlug) $keys[] = "meta.post.$pt.$canonSlug.$what";
      if ($canonSlug) $keys[] = "meta.post.$canonSlug.$what";
      if ($id)        $keys[] = "meta.post.$pt.$id.$what";
      if ($id)        $keys[] = "meta.post.$id.$what";
      $keys[] = "meta.post.$pt.$what";
      $keys[] = "meta.post.$what";
    } elseif (is_post_type_archive()) {
      $pt = get_query_var('post_type');
      if (is_array($pt)) $pt = reset($pt);
      if ($pt) $keys[] = "meta.archive.$pt.$what";
      $keys[] = "meta.archive.$what";
    } elseif (is_tax() || is_category() || is_tag()) {
      $term = get_queried_object();
      $tax  = $term->taxonomy ?? '';
      $slug = $term->slug ?? '';
      $id   = (string) ($term->term_id ?? '');

      // Apply alias to taxonomy slugs
      $aliasMap  = self::aliases($loc);
      $canonSlug = $slug && isset($aliasMap[strtolower($slug)]) ? $aliasMap[strtolower($slug)] : $slug;

      if ($tax && $canonSlug) $keys[] = "meta.tax.$tax.$canonSlug.$what";
      if ($tax && $id)        $keys[] = "meta.tax.$tax.$id.$what";
      if ($tax)               $keys[] = "meta.tax.$tax.$what";
      $keys[] = "meta.tax.$what";
    } elseif (is_search()) {
      $keys[] = "meta.search.$what";
      $keys[] = "meta.archive.$what";
    } elseif (is_404()) {
      $keys[] = "meta.404.$what";
    }

    // Generic fallbacks
    $keys[] = "meta.$what";

    return array_values(array_unique($keys));
  }

  private static function resolve_key_list(array $keys, string $fallback = ''): string {
    foreach ($keys as $k) {
      $val = self::get($k, '');
      if (is_string($val) && trim($val) !== '') return $val;
    }
    return $fallback;
  }

  /* ================= Native WP ================= */

  public static function filter_wp_title(string $current): string {
    $title = self::resolve_key_list(self::ctx_keys('title'), $current);
    return wp_strip_all_tags($title);
  }

  public static function print_meta_description(): void {
    // If an SEO plugin is active, leave its output untouched
    if (class_exists('WPSEO_Frontend') || defined('RANK_MATH_VERSION')) return;

    $desc = self::resolve_key_list(self::ctx_keys('description'), '');
    if ($desc !== '') {
      echo '<meta name="description" content="' . esc_attr($desc) . '">' . "\n";
      echo '<meta property="og:description" content="' . esc_attr($desc) . '">' . "\n";
      echo '<meta name="twitter:description" content="' . esc_attr($desc) . '">' . "\n";
    }
  }

  /* ================= Yoast ================= */

  public static function filter_yoast_title($current) {
    return self::resolve_key_list(self::ctx_keys('title'), (string)$current);
  }
  public static function filter_yoast_desc($current) {
    return self::resolve_key_list(self::ctx_keys('description'), (string)$current);
  }

  /* ================= Rank Math ================= */

  public static function filter_rankmath_title($current) {
    return self::resolve_key_list(self::ctx_keys('title'), (string)$current);
  }
  public static function filter_rankmath_desc($current) {
    return self::resolve_key_list(self::ctx_keys('description'), (string)$current);
  }
}

AWXCT_SEO_Meta::init();
