<?php
// db.php - Valu-Basic SQLite Version
require_once 'config.php';
require_once 'security.php';
require_once 'SecurityHeaders.php';

// Security Headers setzen (bevor irgendwas ausgegeben wird)
if (!headers_sent()) {
    SecurityHeaders::setHeaders();
}

// Session nur starten wenn Headers noch nicht gesendet
if (session_status() === PHP_SESSION_NONE && !headers_sent()) {
    session_start();
}

// Session-Timeout prüfen
if (isset($_SESSION['user_id'])) {
    if (!Security::checkSessionTimeout()) {
        if (!headers_sent()) {
            header('Location: login.php?timeout=1');
            exit;
        }
    }
}

// SQLite Verbindung
try {
    $sqlitePath = defined('SQLITE_PATH') ? SQLITE_PATH : __DIR__ . '/data/valu_basic.sqlite';
    
    // data/ Verzeichnis erstellen falls nicht vorhanden
    $dataDir = dirname($sqlitePath);
    if (!is_dir($dataDir)) {
        mkdir($dataDir, 0755, true);
    }
    
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    
    $pdo = new PDO('sqlite:' . $sqlitePath, null, null, $options);
    $pdo->exec('PRAGMA journal_mode=WAL');
    $pdo->exec('PRAGMA foreign_keys=ON');
    
} catch(PDOException $e) {
    Security::logSecurityEvent('database_error', ['message' => $e->getMessage()]);
    die("Datenbankverbindung fehlgeschlagen.");
}

if (!isset($_SESSION['theme'])) {
    $_SESSION['theme'] = 'cloud';
}

function isLoggedIn() {
    return isset($_SESSION['user_id']) && 
           isset($_SESSION['username']) &&
           isset($_SESSION['login_time']);
}

function syncUserTheme() {
    global $pdo;
    if (isLoggedIn()) {
        try {
            $stmt = $pdo->prepare("SELECT theme FROM users WHERE username = ?");
            $stmt->execute([$_SESSION['username']]);
            $user = $stmt->fetch();
            
            if ($user && !empty($user['theme'])) {
                $_SESSION['theme'] = $user['theme'];
            }
        } catch (PDOException $e) {
            // Fehler ignorieren
        }
    }
}

function requireLogin() {
    if (!isLoggedIn()) {
        if (!headers_sent()) {
            header('Location: login.php');
            exit;
        } else {
            // Wenn Headers schon gesendet (z.B. AJAX), JSON-Error
            if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) || 
                (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'json') !== false)) {
                echo json_encode(['success' => false, 'error' => 'Not logged in']);
                exit;
            }
            exit('Not logged in');
        }
    }
    
    // Role aus DB nachladen falls nicht in Session (PDO)
    if (!isset($_SESSION['role']) && isset($_SESSION['user_id'])) {
        global $pdo;
        try {
            $stmt = $pdo->prepare("SELECT role, username FROM users WHERE id = ?");
            $stmt->execute([$_SESSION['user_id']]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            if ($row) {
                $_SESSION['role'] = $row['role'];
                if (!isset($_SESSION['username'])) {
                    $_SESSION['username'] = $row['username'];
                }
            }
        } catch (Exception $e) {
            // Fehler still loggen, kein Output
            error_log("requireLogin role lookup failed: " . $e->getMessage());
        }
    }
}

/**
 * Prüft ob aktueller User Admin ist
 */
function isAdmin() {
    // Original-Rolle prüfen falls gewechselt
    if (isset($_SESSION['original_role'])) {
        return $_SESSION['original_role'] === 'admin';
    }
    return isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
}

function isSuperAdmin(): bool {
    if (!isset($_SESSION['username'])) return false;
    if (!defined('SUPERADMIN_USERNAME')) return false;
    // Unterstützt einzelnen String oder kommagetrennte Liste
    $admins = array_map('trim', explode(',', SUPERADMIN_USERNAME));
    return in_array($_SESSION['username'], $admins, true);
}

/**
 * Prüft ob eine SuperAdmin-Einstellung aktiv ist.
 * Fallback: true (erlaubt) wenn Einstellung nicht gesetzt.
 */
function getSuperAdminSetting(string $key, bool $default = true): bool {
    global $db;
    try {
        $row = $db->selectOne(
            "SELECT setting_value FROM app_settings WHERE setting_key = ?",
            [$key]
        );
        if ($row === null) return $default;
        return $row['setting_value'] === '1';
    } catch (Exception $e) {
        return $default;
    }
}
// -------------------------------------------------------
// Permission-Cache (pro Request)
// -------------------------------------------------------
$_permissionCache = null;

function _loadPermissions() {
    global $pdo, $_permissionCache;
    if ($_permissionCache !== null) return $_permissionCache;
    try {
        $rows = $pdo->query("SELECT action_key, admin_can, edit_can, read_can FROM permissions")->fetchAll(PDO::FETCH_ASSOC);
        $_permissionCache = [];
        foreach ($rows as $r) {
            $_permissionCache[$r['action_key']] = $r;
        }
    } catch (PDOException $e) {
        // Tabelle noch nicht vorhanden → leeres Array → Fallback greift
        $_permissionCache = [];
    }
    return $_permissionCache;
}

/**
 * hasPermission('items_delete') → true/false je nach Rolle der Session.
 * Fallback: wenn DB-Tabelle fehlt, gelten hardcodierte Defaults.
 */
function hasPermission(string $key): bool {
    if (isAdmin()) return true;

    $role  = $_SESSION['role'] ?? 'read';
    $perms = _loadPermissions();

    if (empty($perms)) {
        return _permissionFallback($key, $role);
    }

    if (!isset($perms[$key])) return false;

    $col = match(true) {
        in_array($role, ['editor', 'edit', 'editieren']) => 'edit_can',
        default                                           => 'read_can',
    };
    return (bool)($perms[$key][$col] ?? false);
}

function requirePermission(string $key): void {
    if (!hasPermission($key)) {
        http_response_code(403);
        $msg = 'Sie haben keine Berechtigung für diesen Bereich.';
        if (function_exists('showPermissionDenied')) {
            showPermissionDenied($msg);
        } else {
            echo '<div style="padding:40px; text-align:center; color:#dc2626;">🚫 ' . htmlspecialchars($msg) . '</div>';
        }
        exit;
    }
}

/** Fallback wenn DB-Tabelle noch nicht existiert */
function _permissionFallback(string $key, string $role): bool {
    $isEdit = in_array($role, ['editor', 'edit', 'editieren']);
    $defaults = [
        'items_view'        => ['edit' => true,  'read' => true],
        'items_search'      => ['edit' => true,  'read' => true],
        'items_add'         => ['edit' => true,  'read' => false],
        'items_edit'        => ['edit' => true,  'read' => false],
        'items_delete'      => ['edit' => false, 'read' => false],
        'items_hide'        => ['edit' => true,  'read' => false],
        'items_value'       => ['edit' => true,  'read' => false],
        'bulk_delete'       => ['edit' => false, 'read' => false],
        'bulk_hide'         => ['edit' => true,  'read' => false],
        'bulk_update'       => ['edit' => true,  'read' => false],
        'media_view'        => ['edit' => true,  'read' => true],
        'media_upload'      => ['edit' => true,  'read' => false],
        'media_delete'      => ['edit' => true,  'read' => false],
        'docs_view'         => ['edit' => true,  'read' => true],
        'docs_upload'       => ['edit' => true,  'read' => false],
        'docs_delete'       => ['edit' => true,  'read' => false],
        'export_pdf'        => ['edit' => true,  'read' => true],
        'export_csv'        => ['edit' => true,  'read' => true],
        'export_html'       => ['edit' => true,  'read' => true],
        'export_insurance'  => ['edit' => true,  'read' => true],
        'export_qr'         => ['edit' => true,  'read' => true],
        'settings_theme'    => ['edit' => true,  'read' => true],
        'settings_lang'     => ['edit' => true,  'read' => true],
        'settings_columns'  => ['edit' => true,  'read' => true],
        'settings_password' => ['edit' => true,  'read' => true],
    ];
    if (!isset($defaults[$key])) return false;
    return $isEdit ? $defaults[$key]['edit'] : $defaults[$key]['read'];
}

/**
 * Prüft ob aktueller User bearbeiten darf (Admin oder Editor)
 */
function canEdit(): bool {
    if (isAdmin()) return true;
    return hasPermission('items_edit');
}

/**
 * Prüft ob aktueller User löschen darf
 */
function canDelete(): bool {
    if (isAdmin()) return true;
    return hasPermission('items_delete');
}

/**
 * Fordert Admin-Berechtigung
 */
function requireAdmin() {
    requireLogin();
    if (!isAdmin()) {
        die('Zugriff verweigert. Admin-Berechtigung erforderlich.');
    }
}

/**
 * Alias für Rückwärtskompatibilität — entspricht canEdit()-Prüfung
 */
function requireEditPermission() {
    requireLogin();
    if (!function_exists('canEdit') || !canEdit()) {
        header('Location: index.php');
        exit;
    }
}

function validateRequest() {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $token = $_POST['csrf_token'] ?? '';
        if (!Security::validateCSRFToken($token)) {
            die('Ungültiges Sicherheits-Token.');
        }
    }
}

if (file_exists(__DIR__ . '/lang/language.php')) {
    require_once __DIR__ . '/lang/language.php';
}

if (!function_exists('loadLanguage')) {
    function loadLanguage() {
        global $translations;
        
        if (!isset($_SESSION['lang'])) {
            $_SESSION['lang'] = 'de';
        }
        
        $currentLang = $_SESSION['lang'];
        $langFile = __DIR__ . '/lang/' . $currentLang . '.php';
        
        if (file_exists($langFile)) {
            $translations = require $langFile;
        }
        
        return $currentLang;
    }
}

if (!function_exists('t')) {
    function t($key) {
        global $translations;
        return $translations[$key] ?? $key;
    }
}

$currentLang = loadLanguage();

function getLanguageFlags() {
    return ['de' => '🇩🇪', 'en' => '🇬🇧'];
}

function getLanguageNames() {
    return ['de' => 'Deutsch', 'en' => 'English'];
}

// FIXED: Verwende 'role' statt 'berechtigung'

function getUserRole() {
    return $_SESSION['role'] ?? 'read';
}

function getRoleBadge($role) {
    $badges = [
        'admin' => '<span class="role-badge role-admin">🔥 Admin</span>',
        'edit' => '<span class="role-badge role-editor">✏️ Editor</span>',
        'read' => '<span class="role-badge role-readonly">👁️ Viewer</span>'
    ];
    return $badges[$role] ?? '';
}

// ============================================================================
// DATABASE KLASSE - WICHTIG!
// ============================================================================

class Database {
    private $pdo;
    
    public function __construct($pdo) {
        $this->pdo = $pdo;
    }
    
    public function select($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt->fetchAll();
        } catch (PDOException $e) {
            error_log("Database select error: " . $e->getMessage());
            return [];
        }
    }
    
    public function selectOne($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt->fetch();
        } catch (PDOException $e) {
            error_log("Database selectOne error: " . $e->getMessage());
            return false;
        }
    }
    
    public function insert($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($params);
            return $this->pdo->lastInsertId();
        } catch (PDOException $e) {
            error_log("Database insert error: " . $e->getMessage());
            return false;
        }
    }
    
    public function update($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            return $stmt->execute($params);
        } catch (PDOException $e) {
            error_log("Database update error: " . $e->getMessage());
            return false;
        }
    }
    
    public function delete($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            return $stmt->execute($params);
        } catch (PDOException $e) {
            error_log("Database delete error: " . $e->getMessage());
            return false;
        }
    }
    
    public function execute($sql, $params = []) {
        try {
            $stmt = $this->pdo->prepare($sql);
            return $stmt->execute($params);
        } catch (PDOException $e) {
            error_log("Database execute error: " . $e->getMessage());
            return false;
        }
    }
    
    public function beginTransaction() {
        return $this->pdo->beginTransaction();
    }
    
    public function commit() {
        return $this->pdo->commit();
    }
    
    public function rollback() {
        return $this->pdo->rollBack();
    }
}

// WICHTIG: $db initialisieren!
$db = new Database($pdo);

// Activity-Tracking → siehe user_activity.php (separates Modul)
?>
