<?php
declare(strict_types=1);

/**
 * /includes/seo.php
 * Централізовані SEO-хелпери:
 * - seo_set([...]) для сторінок
 * - seo_render_head() у header.php
 * - seo_noindex() щоб закривати приватні зони
 *
 * SEO-ОНОВЛЕНО:
 * - canonical тепер ЧИСТИЙ: без lang і без шумових параметрів
 * - hreflang за замовчуванням вимкнений, щоб не плодити конфлікти canonical/hreflang
 * - JSON-LD теж працює на чистих URL
 */

if (!function_exists('seo_h')) {
    function seo_h(?string $s): string {
        return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('seo_is_absolute_url')) {
    function seo_is_absolute_url(string $url): bool {
        $url = trim($url);
        if ($url === '') return false;
        return (bool)preg_match('~^https?://~i', $url);
    }
}

if (!function_exists('seo_current_url')) {
    function seo_current_url(): string {
        if (function_exists('abs_url') && function_exists('current_uri')) {
            return (string)abs_url((string)current_uri());
        }
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        $uri  = $_SERVER['REQUEST_URI'] ?? '/';
        return $scheme . '://' . $host . $uri;
    }
}

if (!function_exists('seo_lang')) {
    function seo_lang(): string {
        $lang = function_exists('lang') ? (string)lang() : (string)($_SESSION['lang'] ?? 'uk');
        if (!in_array($lang, ['uk','ru','en'], true)) $lang = 'uk';
        return $lang;
    }
}

if (!function_exists('seo_base_url')) {
    function seo_base_url(): string {
        if (function_exists('abs_url')) return rtrim((string)abs_url('/'), '/');
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        return $scheme . '://' . $host;
    }
}

if (!function_exists('seo_abs')) {
    function seo_abs(string $url): string {
        $url = trim($url);
        if ($url === '') return $url;

        if (seo_is_absolute_url($url)) return $url;

        if (function_exists('abs_url')) {
            if ($url[0] !== '/') $url = '/' . $url;
            return (string)abs_url($url);
        }

        $base = seo_base_url();
        if ($url[0] !== '/') $url = '/' . $url;
        return $base . $url;
    }
}

if (!function_exists('seo_strip_noise_params')) {
    function seo_strip_noise_params(string $url): string {
        if ($url === '') return $url;

        $p = parse_url($url);
        $scheme = $p['scheme'] ?? '';
        $host   = $p['host'] ?? '';
        $port   = isset($p['port']) ? (':' . $p['port']) : '';
        $path   = $p['path'] ?? '';
        $query  = $p['query'] ?? '';
        $frag   = isset($p['fragment']) ? ('#' . $p['fragment']) : '';

        $qs = [];
        if ($query !== '') parse_str($query, $qs);

        if ($qs) {
            $removeExact = [
                'lang','to',
                'debug_flash','clear_flash','show_ok',
                'pjax','ajax','_t','ts','nonce','token',
                '_nrd','_nid',
                'gclid','fbclid','yclid','ymclid','gbraid','wbraid',
                '_ga','_gid','_gac','_gl','mc_cid','mc_eid',
                'ref','refid','source','src','spm','from','igshid'
            ];

            foreach (array_keys($qs) as $k) {
                $lk = strtolower((string)$k);

                if (str_starts_with($lk, 'utm_')) {
                    unset($qs[$k]);
                    continue;
                }

                if (in_array($lk, $removeExact, true)) {
                    unset($qs[$k]);
                    continue;
                }
            }

            if (!empty($qs)) {
                ksort($qs);
            }
        }

        $newQuery = (!empty($qs)) ? http_build_query($qs) : '';

        $base = '';
        if ($scheme !== '' && $host !== '') {
            $base = $scheme . '://' . $host . $port . $path;
        } else {
            $base = $path !== '' ? $path : $url;
        }

        return $base . ($newQuery !== '' ? ('?' . $newQuery) : '') . $frag;
    }
}

if (!function_exists('seo_strip_lang')) {
    function seo_strip_lang(string $url): string {
        if ($url === '') return $url;

        $p = parse_url($url);
        $scheme = $p['scheme'] ?? '';
        $host   = $p['host'] ?? '';
        $port   = isset($p['port']) ? (':' . $p['port']) : '';
        $path   = $p['path'] ?? '';
        $query  = $p['query'] ?? '';
        $frag   = isset($p['fragment']) ? ('#' . $p['fragment']) : '';

        $qs = [];
        if ($query !== '') parse_str($query, $qs);

        unset($qs['lang']);

        if (!empty($qs)) ksort($qs);

        $newQuery = (!empty($qs)) ? http_build_query($qs) : '';
        $base = '';

        if ($scheme !== '' && $host !== '') {
            $base = $scheme . '://' . $host . $port . $path;
        } else {
            $base = $path !== '' ? $path : $url;
        }

        return $base . ($newQuery !== '' ? ('?' . $newQuery) : '') . $frag;
    }
}

if (!function_exists('seo_defaults')) {
    function seo_defaults(): array {
        $siteName = function_exists('t') ? (string)t('site') : 'VMEREGI';
        $base = seo_base_url();
        return [
            'site_name'   => $siteName,
            'title'       => $siteName,
            'description' => '',
            'canonical'   => $base . '/',
            'image'       => '',
            'type'        => 'website',
            'noindex'     => false,
            'hreflang'    => false,
            'alternates'  => [],
            'jsonld'      => true,
        ];
    }
}

if (!function_exists('seo_set')) {
    function seo_set(array $data): void {
        if (!isset($GLOBALS['_SEO']) || !is_array($GLOBALS['_SEO'])) {
            $GLOBALS['_SEO'] = seo_defaults();
        }
        foreach ($data as $k => $v) {
            $GLOBALS['_SEO'][$k] = $v;
        }
    }
}

if (!function_exists('seo_get')) {
    function seo_get(string $key, $default = null) {
        if (!isset($GLOBALS['_SEO']) || !is_array($GLOBALS['_SEO'])) {
            $GLOBALS['_SEO'] = seo_defaults();
        }
        return $GLOBALS['_SEO'][$key] ?? $default;
    }
}

if (!function_exists('seo_noindex')) {
    function seo_noindex(bool $on = true): void {
        seo_set(['noindex' => $on]);
        if ($on && !headers_sent()) {
            header('X-Robots-Tag: noindex, nofollow, noarchive, nosnippet', true);
        }
    }
}

if (!function_exists('seo_locale')) {
    function seo_locale(string $lang): string {
        return match ($lang) {
            'uk' => 'uk_UA',
            'ru' => 'ru_RU',
            default => 'en_US',
        };
    }
}

if (!function_exists('seo_render_jsonld')) {
    function seo_render_jsonld(array $s, string $canon, string $lang): string {
        if (!empty($s['noindex'])) return '';

        $siteName = (string)($s['site_name'] ?? 'VMEREGI');
        $base = seo_base_url();

        $searchUrl  = $base . '/functional/search/?q={search_term_string}';

        $data = [
            [
                '@context' => 'https://schema.org',
                '@type' => 'WebSite',
                'name' => $siteName,
                'url' => $base . '/',
                'inLanguage' => $lang,
                'potentialAction' => [
                    '@type' => 'SearchAction',
                    'target' => $searchUrl,
                    'query-input' => 'required name=search_term_string'
                ],
            ],
            [
                '@context' => 'https://schema.org',
                '@type' => 'Organization',
                'name' => $siteName,
                'url'  => $base . '/',
            ]
        ];

        $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        if (!is_string($json) || $json === '') return '';
        return "<script type=\"application/ld+json\">" . $json . "</script>\n";
    }
}

if (!function_exists('seo_render_head')) {
    function seo_render_head(): string {
        $s = (isset($GLOBALS['_SEO']) && is_array($GLOBALS['_SEO'])) ? $GLOBALS['_SEO'] : seo_defaults();

        $title = trim((string)($s['title'] ?? ''));
        $desc  = trim((string)($s['description'] ?? ''));
        $canon = trim((string)($s['canonical'] ?? ''));
        $img   = trim((string)($s['image'] ?? ''));
        $type  = trim((string)($s['type'] ?? 'website'));
        $noidx = (bool)($s['noindex'] ?? false);

        if ($canon === '') $canon = seo_current_url();

        $lang = seo_lang();

        $canon = seo_abs($canon);
        $canon = seo_strip_noise_params($canon);
        $canon = seo_strip_lang($canon);

        if ($img !== '') {
            $img = seo_abs($img);
            $img = seo_strip_noise_params($img);
            $img = seo_strip_lang($img);
        }

        $out = "";

        $out .= $noidx
            ? "<meta name=\"robots\" content=\"noindex,nofollow,noarchive,nosnippet\">\n"
            : "<meta name=\"robots\" content=\"index,follow\">\n";

        if ($title !== '') $out .= "<title>" . seo_h($title) . "</title>\n";
        if ($desc !== '')  $out .= "<meta name=\"description\" content=\"" . seo_h($desc) . "\">\n";
        if ($canon !== '') $out .= "<link rel=\"canonical\" href=\"" . seo_h($canon) . "\">\n";

        if ($title !== '') $out .= "<meta property=\"og:title\" content=\"" . seo_h($title) . "\">\n";
        if ($desc !== '')  $out .= "<meta property=\"og:description\" content=\"" . seo_h($desc) . "\">\n";
        if ($canon !== '') $out .= "<meta property=\"og:url\" content=\"" . seo_h($canon) . "\">\n";
        $out .= "<meta property=\"og:type\" content=\"" . seo_h($type) . "\">\n";
        if (!empty($s['site_name'])) $out .= "<meta property=\"og:site_name\" content=\"" . seo_h((string)$s['site_name']) . "\">\n";
        $out .= "<meta property=\"og:locale\" content=\"" . seo_h(seo_locale($lang)) . "\">\n";
        if ($img !== '')   $out .= "<meta property=\"og:image\" content=\"" . seo_h($img) . "\">\n";

        $out .= "<meta name=\"twitter:card\" content=\"" . ($img !== '' ? "summary_large_image" : "summary") . "\">\n";
        if ($title !== '') $out .= "<meta name=\"twitter:title\" content=\"" . seo_h($title) . "\">\n";
        if ($desc !== '')  $out .= "<meta name=\"twitter:description\" content=\"" . seo_h($desc) . "\">\n";
        if ($img !== '')   $out .= "<meta name=\"twitter:image\" content=\"" . seo_h($img) . "\">\n";

        if (!$noidx && !empty($s['hreflang']) && !empty($s['alternates']) && is_array($s['alternates'])) {
            foreach ($s['alternates'] as $code => $href) {
                $href = seo_strip_lang(seo_strip_noise_params(seo_abs((string)$href)));
                if ($href === '') continue;
                $out .= "<link rel=\"alternate\" hreflang=\"" . seo_h((string)$code) . "\" href=\"" . seo_h($href) . "\">\n";
            }
        }

        if (!empty($s['jsonld'])) {
            $out .= seo_render_jsonld($s, $canon, $lang);
        }

        return $out;
    }
}