<?php
// Basit çeviri adaptörü: provider seçimi (libre/google/deepl/azure/none)
// Amaç: maliyetsiz (libre/self-host) veya kullanıcı hesabına bağlı sağlayıcılarla çalışabilmek.

function tr_get_provider_settings($lang = null) {
    $lang = $lang ?: (function_exists('lang_is_default') ? lang_is_default('lang_code') : 'tr');
    // Ayarlar General Settings üzerinden okunur
    $provider = general_settings('translate_provider', $lang) ?: 'none';
    return [
        'provider' => $provider,
        'api_key' => general_settings('translate_api_key', $lang) ?: '',
        'endpoint' => general_settings('translate_endpoint', $lang) ?: '',
        'source' => general_settings('translate_source', $lang) ?: lang_is_default('lang_code'),
        'targets' => general_settings('translate_targets', $lang) ?: '', // örn: en,de,ar
        'glossary' => general_settings('translate_glossary', $lang) ?: '', // JSON
    ];
}

// Basit hash cache anahtarı
function tr_text_key($text, $src, $dest) {
    return hash('sha256', $src.'|'.$dest.'|'.trim($text));
}

// Basit in-memory cache (işlem başına). İstenirse DB tablo eklenebilir.
$GLOBALS['TR_CACHE'] = $GLOBALS['TR_CACHE'] ?? [];

function translate_text($text, $src, $dest, $glossary = []) {
    $key = tr_text_key($text, $src, $dest);
    if (isset($GLOBALS['TR_CACHE'][$key])) return $GLOBALS['TR_CACHE'][$key];

    $settings = tr_get_provider_settings();
    $provider = $settings['provider'];
    if ($provider === 'none' || trim($text) === '') {
        return $text; // çeviri kapalı
    }

    // Glossary yer tutucu basit kilitleme (çok basit yaklaşım)
    $placeholders = [];
    if (!empty($glossary) && is_array($glossary)) {
        foreach ($glossary as $term) {
            $ph = '__TR_TERM_'.hash('crc32b', $term).'__';
            $placeholders[$ph] = $term;
            $text = str_replace($term, $ph, $text);
        }
    }

    $translated = $text;
    try {
        switch ($provider) {
            case 'libre':
                // LibreTranslate (self-host veya public instance)
                $endpoint = rtrim($settings['endpoint'] ?: 'https://libretranslate.com/translate', '/');
                $payload = http_build_query([
                    'q' => $text,
                    'source' => $src,
                    'target' => $dest,
                    'format' => 'text'
                ]);
                $ctx = stream_context_create([
                    'http' => [
                        'method' => 'POST',
                        'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
                        'content' => $payload,
                        'timeout' => 10,
                    ]
                ]);
                $resp = @file_get_contents($endpoint, false, $ctx);
                if ($resp !== false) {
                    $json = json_decode($resp, true);
                    if (isset($json['translatedText'])) {
                        $translated = $json['translatedText'];
                    }
                }
                break;
            case 'google':
            case 'deepl':
            case 'azure':
            default:
                // Bu sağlayıcılar ücretli; ayar girilmediyse pas geç
                // İleride API entegrasyonları burada yapılacak.
                $translated = $text;
        }
    } catch (Exception $e) {
        $translated = $text;
    }

    // Glossary geri açma
    if (!empty($placeholders)) {
        foreach ($placeholders as $ph => $term) {
            $translated = str_replace($ph, $term, $translated);
        }
    }

    $GLOBALS['TR_CACHE'][$key] = $translated;
    return $translated;
}

// HTML çevirisi: HTML yapısını bozmadan yalnızca metin düğümlerini çevirir
function translate_html($html, $src, $dest, $glossary = []) {
    if (trim($html) === '' || $src === $dest) return $html;

    // Hızlı yol: LibreTranslate ile tüm HTML'i tek çağrıda çevir (format=html)
    $settings = tr_get_provider_settings();
    // Eğer sözlük kullanılıyorsa veya notranslate işaretleri içeriyorsa hızlı yolu atla
    $hasGlossary = !empty($glossary) && is_array($glossary);
    $hasNoTranslateMarks = (strpos($html, 'notranslate') !== false) || (strpos($html, 'data-no-translate') !== false);
    if (($settings['provider'] ?? 'none') === 'libre' && !$hasGlossary && !$hasNoTranslateMarks) {
        $endpoint = rtrim($settings['endpoint'] ?: 'https://libretranslate.com/translate', '/');
        $payload = http_build_query([
            'q' => $html,
            'source' => $src,
            'target' => $dest,
            'format' => 'html'
        ]);
        $ctx = stream_context_create([
            'http' => [
                'method' => 'POST',
                'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
                'content' => $payload,
                'timeout' => 60,
            ]
        ]);
        $resp = @file_get_contents($endpoint, false, $ctx);
        if ($resp !== false) {
            $json = json_decode($resp, true);
            if (isset($json['translatedText']) && is_string($json['translatedText']) && trim($json['translatedText']) !== '') {
                return $json['translatedText'];
            }
        }
        // Eğer başarısız olursa aşağıdaki düğüm düğüm yönteme düş
    }

    // Düğüm düğüm yöntem (eski yol)
    $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML('<?xml encoding="utf-8" ?>'.$html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    libxml_clear_errors();

    $xpath = new DOMXPath($dom);
    // Çevrilmeyecek etiketler (button ve select'i metin çevirisine dahil ediyoruz)
    $skip = ['script','style','code','pre','svg','noscript','textarea','input'];
    foreach ($xpath->query('//text()[normalize-space()]') as $node) {
        $parent = $node->parentNode;
        if (!$parent) continue;
        if (in_array(strtolower($parent->nodeName), $skip, true)) continue;
        // .notranslate veya data-no-translate olan ebeveyni atla
        $pEl = $parent;
        $skipNode = false;
        while ($pEl && $pEl->nodeType === XML_ELEMENT_NODE) {
            $class = $pEl->getAttribute('class');
            if (strpos($class, 'notranslate') !== false || $pEl->hasAttribute('data-no-translate')) { $skipNode = true; break; }
            $pEl = $pEl->parentNode;
        }
        if ($skipNode) continue;

        $text = $node->nodeValue;
        // Eğer sözlük terimleri bu metin içinde geçiyorsa metni parçalara ayır,
        // terimleri aynen koru, sadece diğer parçaları çevir. Böylece sıra/işaret
        // bozulması ve noktalama sapması engellenir.
        $translated = $text;
        $didSplitTranslate = false;
        if (!empty($glossary) && is_array($glossary)) {
            $terms = array_values(array_filter($glossary, function($t){ return is_string($t) && $t !== ''; }));
            if (!empty($terms)) {
                $quoted = array_map(function($t){ return preg_quote($t, '/'); }, $terms);
                $pattern = '/(' . implode('|', $quoted) . ')/u';
                $parts = @preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
                if (is_array($parts) && count($parts) > 1) {
                    $rebuilt = '';
                    foreach ($parts as $part) {
                        if ($part === '') { continue; }
                        if (in_array($part, $terms, true)) {
                            // Sözlük terimini aynen ekle
                            $rebuilt .= $part;
                        } else {
                            // Diğer parçaları çevir
                            $rebuilt .= translate_text($part, $src, $dest, []);
                        }
                    }
                    $translated = $rebuilt;
                    $didSplitTranslate = true;
                }
            }
        }
        if (!$didSplitTranslate) {
            $translated = translate_text($text, $src, $dest, $glossary);
        }
        if ($translated !== $text) {
            $node->nodeValue = $translated;
        }
    }
    // Attribute çevirileri: placeholder, title, aria-label ve input[value] (submit/button/reset)
    // notranslate ve data-no-translate işaretlerine saygı göster.
    $translateAttributes = function(DOMElement $el, array $attrs) use ($src, $dest, $glossary) {
        foreach ($attrs as $attr) {
            if ($el->hasAttribute($attr)) {
                $val = $el->getAttribute($attr);
                if ($val !== '') {
                    $new = translate_text($val, $src, $dest, $glossary);
                    if (is_string($new) && $new !== '' && $new !== $val) {
                        $el->setAttribute($attr, $new);
                    }
                }
            }
        }
    };

    // Yardımcı: bir eleman veya atalarında notranslate var mı?
    $hasNoTranslateOnAncestors = function(DOMElement $el) {
        $p = $el;
        while ($p && $p->nodeType === XML_ELEMENT_NODE) {
            $class = $p->getAttribute('class');
            if (strpos($class, 'notranslate') !== false || $p->hasAttribute('data-no-translate')) {
                return true;
            }
            $p = $p->parentNode instanceof DOMElement ? $p->parentNode : null;
        }
        return false;
    };

    // 1) placeholder / title / aria-label
    foreach ($xpath->query('//*[@placeholder or @title or @aria-label]') as $el) {
        if (!($el instanceof DOMElement)) continue;
        if ($hasNoTranslateOnAncestors($el)) continue;
        $translateAttributes($el, ['placeholder','title','aria-label']);
    }

    // 2) input[type=submit|button|reset][value]
    foreach ($xpath->query('//input[@value and (translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz") = "submit" or translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz") = "button" or translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz") = "reset")]') as $el) {
        if (!($el instanceof DOMElement)) continue;
        if ($hasNoTranslateOnAncestors($el)) continue;
        $translateAttributes($el, ['value']);
    }

    // Güncellenmiş HTML'yi döndür
    $out = $dom->saveHTML();
    // <?xml prologunu temizle
    $out = preg_replace('/^<\?xml.*?\?>/i', '', $out);
    return $out;
}

