<?php
// translate.php (safe debug-ready)
// Pastikan file ini berada di root project dan tersedia untuk fetch dari browser.

declare(strict_types=1);
error_reporting(E_ALL);
ini_set('display_errors', '0');      // jangan tampilkan error ke browser (kembalikan JSON)
ini_set('log_errors', '1');
ini_set('error_log', __DIR__ . '/translate_errors.log');

header('Content-Type: application/json; charset=utf-8');

// small helper to respond and exit
function jsonErr($msg, $code = 500, $extra = []) {
    http_response_code($code);
    $out = array_merge(['ok' => false, 'error' => $msg], $extra);
    // write to log for debugging
    file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | ERROR: " . json_encode($out, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
    echo json_encode($out, JSON_UNESCAPED_UNICODE);
    exit;
}

// catch fatal shutdown errors
register_shutdown_function(function(){
    $err = error_get_last();
    if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | FATAL: " . json_encode($err, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        http_response_code(500);
        echo json_encode(['ok' => false, 'error' => 'Fatal error occurred. See translate_errors.log.']);
    }
});

try {
    // load config and $pdo (jika ada)
    $cfgPath = __DIR__ . '/Login/config.php';
    if (file_exists($cfgPath)) {
        require_once $cfgPath;
    } else {
        // jika tidak ada koneksi DB, kita masih bisa jalan untuk test (tanpa cache)
        $pdo = null;
    }

    // read JSON input
    $raw = file_get_contents('php://input');
    $input = json_decode($raw, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        jsonErr('Invalid JSON input: ' . json_last_error_msg(), 400, ['raw' => substr($raw,0,1000)]);
    }

    $target = $input['target'] ?? 'auto';
    $items  = $input['items'] ?? [];

    if (!is_array($items) || empty($items)) {
        jsonErr('No items to translate', 400);
    }

    // normalize target language
    $tgt = strtolower($target);
    if ($tgt === 'auto') {
        $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en';
        $tgt = substr($accept, 0, 2) ?: 'en';
    }

    // optional: prepare cache array
    $cached = [];

    // if DB/ PDO available, try read cache
    if (!empty($pdo)) {
        try {
            $keys = array_column($items,'key');
            if (!empty($keys)) {
                $placeholders = implode(',', array_fill(0, count($keys), '?'));
                $stmt = $pdo->prepare("SELECT cache_key, out_text FROM translations_cache WHERE tgt_lang = ? AND cache_key IN ($placeholders)");
                $params = array_merge([$tgt], $keys);
                $stmt->execute($params);
                while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) {
                    $cached[$r['cache_key']] = $r['out_text'];
                }
            }
        } catch (Throwable $e) {
            // log but continue (so translation still works)
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | DB CACHE READ ERROR: " . $e->getMessage() . PHP_EOL, FILE_APPEND);
        }
    }

    // prepare list to translate
    $toTranslate = [];
    foreach ($items as $it) {
        if (!isset($cached[$it['key']])) {
            $toTranslate[$it['key']] = $it['text'];
        }
    }

    $translated = [];

    // If nothing to translate (all cached), merge & return
    if (empty($toTranslate)) {
        $result = $cached;
        echo json_encode(['ok' => true, 'map' => $result], JSON_UNESCAPED_UNICODE);
        exit;
    }

    // === Choose provider ===
    // Default: LibreTranslate public instance (suitable for testing)
    $LT_URL = 'https://libretranslate.de/translate';

    foreach ($toTranslate as $key => $srcText) {
        // call provider
        $post = http_build_query([
            'q' => $srcText,
            'source' => 'auto',
            'target' => $tgt,
            'format' => 'text'
        ]);
        $ch = curl_init($LT_URL);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $post,
            CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/x-www-form-urlencoded'],
            CURLOPT_TIMEOUT => 15,
        ]);
        $resp = curl_exec($ch);
        $curlErr = curl_error($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($resp === false || $curlErr) {
            // provider failed — fallback to original text, but log
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | CURL ERROR: " . $curlErr . PHP_EOL, FILE_APPEND);
            $translated[$key] = $srcText;
            continue;
        }

        // if provider returned HTML (starts with <), log and error
        $trim = ltrim($resp);
        if (strlen($trim) > 0 && $trim[0] === '<') {
            // log full response to file (truncated)
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | PROVIDER RETURNED HTML (HTTP $httpCode): " . substr($resp, 0, 2000) . PHP_EOL, FILE_APPEND);
            // Use fallback: return source (safe) and continue
            $translated[$key] = $srcText;
            continue;
        }

        $j = json_decode($resp, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | INVALID JSON FROM PROVIDER: " . json_last_error_msg() . " -- raw: " . substr($resp,0,2000) . PHP_EOL, FILE_APPEND);
            $translated[$key] = $srcText;
            continue;
        }

        // LibreTranslate returns { translatedText: "..." }
        if (isset($j['translatedText'])) {
            $translated[$key] = $j['translatedText'];
        } elseif (isset($j[0]['translatedText'])) {
            // in case provider returns array
            $translated[$key] = $j[0]['translatedText'];
        } else {
            // fallback
            $translated[$key] = $srcText;
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | UNEXPECTED PROVIDER RESPONSE: " . substr($resp,0,2000) . PHP_EOL, FILE_APPEND);
        }
    }

    // save to cache if PDO available
    if (!empty($pdo)) {
        try {
            $ins = $pdo->prepare("REPLACE INTO translations_cache (cache_key, src_lang, tgt_lang, src_text, out_text) VALUES (?,?,?,?,?)");
            foreach ($translated as $key => $out) {
                $src = $toTranslate[$key] ?? '';
                $ins->execute([$key, null, $tgt, $src, $out]);
            }
        } catch (Throwable $e) {
            file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | DB CACHE WRITE ERROR: " . $e->getMessage() . PHP_EOL, FILE_APPEND);
        }
    }

    $result = $cached + $translated;
    echo json_encode(['ok' => true, 'map' => $result], JSON_UNESCAPED_UNICODE);
    exit;

} catch (Throwable $ex) {
    // unexpected error
    file_put_contents(__DIR__ . '/translate_errors.log', date('Y-m-d H:i:s') . " | EXCEPTION: " . $ex->getMessage() . PHP_EOL . $ex->getTraceAsString() . PHP_EOL, FILE_APPEND);
    jsonErr('Server exception: ' . $ex->getMessage());
}
