<?php
/**
 * Univerzální třída pro práci s JSON databází
 */
class JsonDB {
    private $filePath;

    public function __construct($tableName) {
        // Maximálně spolehlivé sestavení cesty k databázi (sjednocení lomítek)
        $baseDir = rtrim(str_replace('\\', '/', __DIR__), '/');
        $this->filePath = $baseDir . '/data/' . $tableName . '.json';
        
        $dir = dirname($this->filePath);
        if (!is_dir($dir)) {
            @mkdir($dir, 0777, true);
        }
        if (!file_exists($this->filePath)) {
            @file_put_contents($this->filePath, json_encode([]));
        }
    }

    public function getAll() {
        clearstatcache(true, $this->filePath);
        if (!file_exists($this->filePath)) return [];
        
        $content = @file_get_contents($this->filePath);
        if ($content === false || trim($content) === '') return [];

        // 1. Tvrdý ořez na JSON hranice { } nebo [ ] čímž se ihned zbavíme případného UTF-8 BOM nebo balastu z FTP
        $firstBracket = strpos($content, '{');
        $firstSquare = strpos($content, '[');
        $start = ($firstBracket !== false && $firstSquare !== false) ? min($firstBracket, $firstSquare) : ($firstBracket !== false ? $firstBracket : $firstSquare);
            
        $lastBracket = strrpos($content, '}');
        $lastSquare = strrpos($content, ']');
        $end = ($lastBracket !== false && $lastSquare !== false) ? max($lastBracket, $lastSquare) : ($lastBracket !== false ? $lastBracket : $lastSquare);
                
        if ($start !== false && $end !== false && $end >= $start) {
            $content = substr($content, $start, $end - $start + 1);
        }

        $decoded = json_decode($content, true);
        
        // 2. Poslední záchrana, pokud parsování selže na řídících znacích
        if (json_last_error() !== JSON_ERROR_NONE) {
            // Smažeme všechny neviditelné znaky kromě mezer a zalomení řádků a opravíme trailing commas
            $content = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $content);
            $content = preg_replace('/,\s*([\]}])/m', '$1', $content);
            $decoded = json_decode($content, true);
        }

        // Zajištění, že metoda VŽDY vrátí pole a odfiltruje poškozené řádky
        if (is_array($decoded)) {
            $safeData = [];
            foreach ($decoded as $k => $v) {
                if (is_array($v)) {
                    $safeData[$k] = $v;
                }
            }
            return $safeData;
        }
        
        return [];
    }

    private function save($data) {
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        if ($json === false) {
            $json = json_encode($data, JSON_PRETTY_PRINT | JSON_INVALID_UTF8_SUBSTITUTE);
            if ($json === false) return false;
        }
        
        $tempFile = $this->filePath . '.tmp.' . uniqid();
        $bytes = @file_put_contents($tempFile, $json);
        
        if ($bytes !== false && $bytes === strlen($json)) {
            @chmod($tempFile, 0666);
            if (@rename($tempFile, $this->filePath)) {
                @chmod($this->filePath, 0666);
                $this->cleanupTempFiles();
                return true;
            } else {
                @unlink($tempFile);
            }
        } else {
            if (file_exists($tempFile)) @unlink($tempFile);
        }
        
        // Fallback pro případné restrikce oprávnění u přejmenování
        $resBytes = @file_put_contents($this->filePath, $json);
        if ($resBytes !== false && $resBytes === strlen($json)) {
            @chmod($this->filePath, 0666);
            $this->cleanupTempFiles();
            return true;
        }
        return false;
    }

    private function cleanupTempFiles() {
        $dir = dirname($this->filePath);
        $files = glob($dir . '/*.tmp.*');
        if (is_array($files)) {
            foreach ($files as $f) {
                if (file_exists($f) && time() - filemtime($f) > 3600) @unlink($f);
            }
        }
    }

    public function insert($data) {
        if (!is_array($data)) $data = [];
        $records = $this->getAll();
        $id = uniqid(); // Generování unikátního ID (např. 60f3d9b... )
        $data['id'] = $id;
        $data['created_at'] = date('Y-m-d H:i:s');
        $records[$id] = $data;
        $this->save($records);
        return $id;
    }

    public function getById($id) {
        $records = $this->getAll();
        return isset($records[$id]) && is_array($records[$id]) ? $records[$id] : null;
    }

    public function update($id, $data) {
        if (!is_array($data)) return false;
        $records = $this->getAll();
        if (isset($records[$id]) && is_array($records[$id])) {
            // Zachování původního ID a času vytvoření
            $data['id'] = $id;
            $data['created_at'] = $records[$id]['created_at'] ?? date('Y-m-d H:i:s');
            $data['updated_at'] = date('Y-m-d H:i:s');
            
            $records[$id] = array_merge($records[$id], $data);
            $this->save($records);
            return true;
        }
        return false;
    }

    public function delete($id) {
        $records = $this->getAll();
        if (isset($records[$id])) {
            unset($records[$id]);
            $this->save($records);
            return true;
        }
        return false;
    }
}