<?php
// SUNUCUDA JSON EKLENTİSİ YOKSA MANUEL OLARAK TANIMLA (POLYFILL)
if (!function_exists('json_decode') || !function_exists('json_encode')) {
    require_once __DIR__ . '/JSON.php';
    if (!function_exists('json_decode')) {
        function json_decode($content, $assoc = false) {
            // 16 = SERVICES_JSON_LOOSE_TYPE (objeleri array'e çevirir)
            $json = new Services_JSON($assoc ? 16 : 0);
            return $json->decode($content);
        }
    }
    if (!function_exists('json_encode')) {
        function json_encode($content, $options = 0) {
            $json = new Services_JSON();
            return $json->encode($content);
        }
    }
    // PHP 8 hatalarını engellemek için constants
    if (!defined('JSON_UNESCAPED_UNICODE')) define('JSON_UNESCAPED_UNICODE', 256);
    if (!defined('JSON_PRETTY_PRINT')) define('JSON_PRETTY_PRINT', 128);
}
/**
 * YouTube Converter Projesi - Konfigürasyon Dosyası
 */

// API yanıtlarını bozmamak için canlı ortamda hata gösterimini kapat
error_reporting(0);
ini_set('display_errors', 0);

/**
 * Sunucuda hangi komut çalıştırma fonksiyonu açıksa onu otomatik kullanır.
 * Bulduğu çalışan metodu 'exec_method.txt' dosyasına kaydeder (Performans optimizasyonu).
 */
function run_shell_command($cmd) {
    $output = [];
    $returnCode = 1;
    $cacheFile = STORAGE_DIR . 'exec_method.txt';
    $activeMethod = file_exists($cacheFile) ? trim(file_get_contents($cacheFile)) : '';

    $methods = [
        'exec' => function($c) use (&$output, &$returnCode) {
            exec($c, $output, $returnCode);
            return ['output' => $output, 'code' => $returnCode];
        },
        'shell_exec' => function($c) use (&$output, &$returnCode) {
            $res = shell_exec($c);
            $output = $res ? explode("\n", trim($res)) : [];
            return ['output' => $output, 'code' => $res === null ? 1 : 0];
        },
        'system' => function($c) use (&$output, &$returnCode) {
            ob_start();
            system($c, $returnCode);
            $res = ob_get_clean();
            $output = $res ? explode("\n", trim($res)) : [];
            return ['output' => $output, 'code' => $returnCode];
        },
        'proc_open' => function($c) use (&$output, &$returnCode) {
            $descriptorspec = [0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => ["pipe", "w"]];
            $process = proc_open($c, $descriptorspec, $pipes);
            if (is_resource($process)) {
                $res = stream_get_contents($pipes[1]);
                fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]);
                $returnCode = proc_close($process);
                $output = $res ? explode("\n", trim($res)) : [];
                return ['output' => $output, 'code' => $returnCode];
            }
            return ['output' => [], 'code' => 1];
        }
    ];

    // Önbellekteki metod hala geçerliyse direkt onu kullan (Zaman kaybını önler)
    if ($activeMethod && isset($methods[$activeMethod]) && function_exists($activeMethod) && is_callable($activeMethod)) {
        return $methods[$activeMethod]($cmd);
    }

    // Hiçbir metod kayıtlı değilse tek tek tara ve ilk bulduğunu dosyaya not et
    foreach (['exec', 'shell_exec', 'system', 'proc_open'] as $method) {
        if (function_exists($method) && is_callable($method)) {
            file_put_contents($cacheFile, $method);
            return $methods[$method]($cmd);
        }
    }
    
    // Bütün yollar kapalıysa
    return ['output' => ['ERROR: Tüm terminal komut fonksiyonları (exec, shell_exec vb.) sunucu tarafından engellenmiş!'], 'code' => 999];
}

// Dinamik Domain Tespiti (Hardcoded Domain Yasağına Uygun)
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || ($_SERVER['SERVER_PORT'] ?? 80) == 443 ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost:8000';
define('SITE_URL', $protocol . '://' . $host);

// İndirme ve Medya Klasör Yolları
define('BASE_DIR', __DIR__);
define('STORAGE_DIR', BASE_DIR . '/storage/');

// Yt-dlp Çalıştırılabilir Dosya Yolu
if (file_exists(BASE_DIR . '/bin/yt-dlp')) {
    define('YTDLP_BIN', BASE_DIR . '/bin/yt-dlp');
} else {
    define('YTDLP_BIN', 'yt-dlp');
}

// Session Başlatma
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Veritabanı Konfigürasyonu
define('DB_HOST', $_ENV['DB_HOST'] ?? '127.0.0.1');
define('DB_NAME', $_ENV['DB_NAME'] ?? 'youtubedonusturu_sa');
define('DB_USER', $_ENV['DB_USER'] ?? 'youtubedonusturu_admin');
define('DB_PASS', $_ENV['DB_PASS'] ?? 'Yt123donusturucu');

/**
 * PDO Veritabanı Bağlantısı Fonksiyonu
 */
function getDbConnection() {
    static $pdo = null;
    if ($pdo === null) {
        try {
            $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4";
            $pdo = new PDO($dsn, DB_USER, DB_PASS, [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ]);
        } catch (PDOException $e) {
            return null;
        }
    }
    return $pdo;
}

/**
 * Ziyaretçi Takip Fonksiyonu (F5 Yenilemelerinde Artmaz)
 */
function trackVisitor() {
    // Aynı oturumda (session) tekrar F5 atıldığında sayacı artırma
    if (!empty($_SESSION['is_visited_session'])) {
        return;
    }
    $_SESSION['is_visited_session'] = true;

    $ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';

    // Dosya tabanlı yedek sayaç
    $counterFile = STORAGE_DIR . 'visitors.json';
    $stats = ['total_views' => 0, 'unique_visitors' => 0, 'ips' => []];
    if (file_exists($counterFile)) {
        $stats = json_decode(file_get_contents($counterFile), true) ?? $stats;
    }

    $stats['total_views'] = ($stats['total_views'] ?? 0) + 1;
    if (!in_array($ip, $stats['ips'] ?? [])) {
        $stats['ips'][] = $ip;
        $stats['unique_visitors'] = count($stats['ips']);
    }
    file_put_contents($counterFile, json_encode($stats));

    // Veritabanı kaydı
    $db = getDbConnection();
    if ($db) {
        try {
            $db->exec("CREATE TABLE IF NOT EXISTS ziyaretler (
                id INT AUTO_INCREMENT PRIMARY KEY,
                ip VARCHAR(45),
                user_agent TEXT,
                visited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )");

            // Bugün aynı IP zaten kaydedildiyse tekrar ekleme
            $chk = $db->prepare("SELECT id FROM ziyaretler WHERE ip = ? AND DATE(visited_at) = CURDATE() LIMIT 1");
            $chk->execute([$ip]);
            if (!$chk->fetch()) {
                $stmt = $db->prepare("INSERT INTO ziyaretler (ip, user_agent) VALUES (?, ?)");
                $stmt->execute([$ip, substr($ua, 0, 255)]);
            }
        } catch (Exception $e) {}
    }
}


/**
 * Ziyaretçi İstatistiklerini Alma
 */
function getVisitorStats() {
    $db = getDbConnection();
    if ($db) {
        try {
            $totalViews = (int)$db->query("SELECT COUNT(*) FROM ziyaretler")->fetchColumn();
            $uniqueVisitors = (int)$db->query("SELECT COUNT(DISTINCT ip) FROM ziyaretler")->fetchColumn();
            $todayVisitors = (int)$db->query("SELECT COUNT(DISTINCT ip) FROM ziyaretler WHERE DATE(visited_at) = CURDATE()")->fetchColumn();
            
            if ($totalViews > 0) {
                return [
                    'total_views' => $totalViews,
                    'unique_visitors' => $uniqueVisitors,
                    'today_visitors' => $todayVisitors
                ];
            }
        } catch (Exception $e) {}
    }

    $counterFile = STORAGE_DIR . 'visitors.json';
    $stats = ['total_views' => 0, 'unique_visitors' => 0, 'today_visitors' => 0];
    if (file_exists($counterFile)) {
        $fileData = json_decode(file_get_contents($counterFile), true) ?? [];
        $stats['total_views'] = $fileData['total_views'] ?? 0;
        $stats['unique_visitors'] = $fileData['unique_visitors'] ?? 0;
        $stats['today_visitors'] = ceil(($fileData['unique_visitors'] ?? 0) / 2);
    }
    return $stats;
}

/**
 * Admin Konfigürasyonu ve Şifre Yönetimi
 */
function getAdminConfig() {
    $configFile = STORAGE_DIR . 'admin_config.json';
    if (!file_exists($configFile)) {
        $defaultConfig = [
            'username' => 'admin',
            'password_hash' => password_hash('AdminPassword123!', PASSWORD_BCRYPT),
            'system_mode' => 'original'
        ];
        file_put_contents($configFile, json_encode($defaultConfig));
        return $defaultConfig;
    }
    $data = json_decode(file_get_contents($configFile), true);
    if (!isset($data['password_hash'])) {
        $data['password_hash'] = password_hash('AdminPassword123!', PASSWORD_BCRYPT);
    }
    if (!isset($data['system_mode'])) {
        $data['system_mode'] = 'original';
    }
    return $data;
}

function verifyAdminLogin($user, $pass) {
    // 1. Veritabanından Kullanıcı Kontrolü (`users` tablosu)
    $db = getDbConnection();
    if ($db) {
        try {
            $stmt = $db->prepare("SELECT * FROM users WHERE username = ? OR email = ? LIMIT 1");
            $stmt->execute([$user, $user]);
            $userData = $stmt->fetch();

            if ($userData) {
                $dbPass = $userData['password'];

                // Bcrypt şifre kontrolü
                if (password_verify($pass, $dbPass)) {
                    return true;
                }

                // Eski MD5 hash kontrolü ve otomatik Bcrypt yükseltmesi
                if (md5($pass) === $dbPass) {
                    $newHash = password_hash($pass, PASSWORD_BCRYPT);
                    $upStmt = $db->prepare("UPDATE users SET password = ? WHERE id = ?");
                    $upStmt->execute([$newHash, $userData['id']]);
                    return true;
                }
                return false;
            }
        } catch (Exception $e) {}
    }

    // 2. Veritabanı Yoksa / Kullanıcı Bulunamadıysa Dosya Tabanlı Kontrol
    $config = getAdminConfig();
    if ($user !== ($config['username'] ?? 'admin')) {
        return false;
    }
    return password_verify($pass, $config['password_hash']);
}

function updateAdminPassword($newPass) {
    $newHash = password_hash($newPass, PASSWORD_BCRYPT);

    // 1. Veritabanını Güncelle (`users` tablosu)
    $db = getDbConnection();
    if ($db) {
        try {
            $stmt = $db->prepare("UPDATE users SET password = ? WHERE username = 'admin' OR id = 1");
            $stmt->execute([$newHash]);

            // Kullanıcı yoksa oluştur
            if ($stmt->rowCount() === 0) {
                $insStmt = $db->prepare("INSERT INTO users (username, email, password) VALUES ('admin', 'admin@example.com', ?)");
                $insStmt->execute([$newHash]);
            }
        } catch (Exception $e) {}
    }

    // 2. Dosya Tabanlı Yapılandırmayı Güncelle
    $configFile = STORAGE_DIR . 'admin_config.json';
    $config = getAdminConfig();
    $config['password_hash'] = $newHash;
    file_put_contents($configFile, json_encode($config));
}

/**
 * İndirme İstatistiğini Veritabanına Kaydetme
 */
function logConversion($url, $format, $token) {
    $db = getDbConnection();
    if ($db) {
        try {
            $db->exec("CREATE TABLE IF NOT EXISTS conversions (
                id INT AUTO_INCREMENT PRIMARY KEY,
                url TEXT,
                format VARCHAR(20),
                token VARCHAR(64),
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )");

            $stmt = $db->prepare("INSERT INTO conversions (url, format, token) VALUES (?, ?, ?)");
            $stmt->execute([$url, $format, $token]);
        } catch (Exception $e) {}
    }
}





