<?php
/**
 * (c) ININOUT & PYXIS. All Rights Reserved.
 * Wszelkie modyfikacje tego pliku wymagaja zgloszenia oraz zgody autorow.
 * Any modifications to this file require notification and consent of the authors.
 */
/**
 * i-BOK 5 - Konfiguracja bazy MySQL/MariaDB
 *
 * - db_load_config() / db_save_config() — JSON w cfg/database.cfg
 * - db_get_pdo() — singleton PDO
 * - db_is_mysql_mode() — sprawdź czy tryb MySQL jest włączony
 * - db_test_connection() — test połączenia + wersja serwera
 */

/**
 * Załaduj konfigurację bazy danych z pliku JSON
 *
 * @return array Konfiguracja bazy danych
 */
function db_load_config() {
    $file = defined('IBOK_CFG_DIR') ? IBOK_CFG_DIR . '/database.cfg' : IBOK_ROOT . '/cfg/database.cfg';

    $defaults = [
        'enabled'  => false,
        'host'     => 'localhost',
        'port'     => 3306,
        'database' => 'ibok5',
        'username' => '',
        'password' => '',
        'charset'  => 'utf8mb4',
    ];

    if (!file_exists($file)) {
        return $defaults;
    }

    $content = file_get_contents($file);
    if ($content === false) {
        return $defaults;
    }

    $config = json_decode($content, true);
    if (!is_array($config)) {
        return $defaults;
    }

    return array_merge($defaults, $config);
}

/**
 * Zapisz konfigurację bazy danych do pliku JSON
 *
 * @param array $config Konfiguracja do zapisania
 * @return bool Sukces
 */
function db_save_config($config) {
    $dir = defined('IBOK_CFG_DIR') ? IBOK_CFG_DIR : IBOK_ROOT . '/cfg';

    if (!is_dir($dir)) {
        if (!@mkdir($dir, 0775, true)) {
            ibok_log("db_save_config: nie można utworzyć katalogu: $dir", 'error');
            return false;
        }
    }

    $file = $dir . '/database.cfg';
    $json = json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

    $result = @file_put_contents($file, $json, LOCK_EX);
    if ($result === false) {
        ibok_log("db_save_config: nie można zapisać pliku: $file (is_writable dir: " . (is_writable($dir) ? 'yes' : 'no') . ")", 'error');
        return false;
    }

    @chmod($file, 0660);
    return true;
}

/**
 * Tryb MySQL jest zawsze włączony (ibok5 działa tylko na bazie danych)
 *
 * @return bool
 */
function db_is_mysql_mode() {
    return true;
}

/**
 * Wymuś odświeżenie cache trybu MySQL (po zmianie konfiguracji)
 */
function db_reset_mode_cache() {
    // Wymuszamy ponowne sprawdzenie przy następnym wywołaniu db_is_mysql_mode()
    // Realizowane przez zmienną statyczną w db_is_mysql_mode — musimy użyć triku
    // Zamiast tego db_is_mysql_mode sprawdza plik za każdym requestem (static per-request)
    // Więc nic tu nie trzeba robić — cache jest per-request
}

/**
 * Pobierz singleton PDO
 *
 * @return PDO|null Połączenie PDO lub null przy błędzie
 */
function db_get_pdo() {
    static $pdo = null;

    if ($pdo !== null) {
        return $pdo;
    }

    $config = db_load_config();

    if (empty($config['host']) || empty($config['database']) || empty($config['username'])) {
        return null;
    }

    try {
        $dsn = sprintf(
            'mysql:host=%s;port=%d;dbname=%s;charset=%s',
            $config['host'],
            (int)$config['port'],
            $config['database'],
            $config['charset'] ?? 'utf8mb4'
        );

        $pdo = new PDO($dsn, $config['username'], $config['password'], [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ]);

        return $pdo;
    } catch (PDOException $e) {
        ibok_log("Błąd PDO: " . $e->getMessage(), 'error');
        $pdo = null;
        return null;
    }
}

/**
 * Testuj połączenie z bazą danych
 *
 * @param array $config Konfiguracja do przetestowania
 * @return array ['success' => bool, 'message' => string, 'version' => string]
 */
function db_test_connection($config) {
    if (empty($config['host']) || empty($config['database']) || empty($config['username'])) {
        return [
            'success' => false,
            'message' => 'Niekompletna konfiguracja.',
            'version' => '',
        ];
    }

    try {
        $dsn = sprintf(
            'mysql:host=%s;port=%d;dbname=%s;charset=%s',
            $config['host'],
            (int)($config['port'] ?? 3306),
            $config['database'],
            $config['charset'] ?? 'utf8mb4'
        );

        $pdo = new PDO($dsn, $config['username'], $config['password'], [
            PDO::ATTR_ERRMODE  => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_TIMEOUT  => 5,
        ]);

        $version = $pdo->query('SELECT VERSION()')->fetchColumn();

        return [
            'success' => true,
            'message' => 'OK',
            'version' => $version,
        ];
    } catch (PDOException $e) {
        return [
            'success' => false,
            'message' => $e->getMessage(),
            'version' => '',
        ];
    }
}

/**
 * Pobierz statystyki głównych tabel PYXIS
 *
 * @return array ['table_name' => row_count, ...]
 */
function db_table_stats() {
    $pdo = db_get_pdo();
    if (!$pdo) return [];

    // Tabele PYXIS które nas interesują
    $tables = [
        'Userdb', 'Fv', 'Fvk', 'Oplaty', 'Mac',
        'Infrastruktura', 'ZleceniaSerwisowe', 'Operator', 'Podmioty',
    ];

    try {
        $config = db_load_config();
        $placeholders = implode(',', array_fill(0, count($tables), '?'));
        $stmt = $pdo->prepare(
            "SELECT TABLE_NAME, TABLE_ROWS
             FROM information_schema.TABLES
             WHERE TABLE_SCHEMA = ? AND TABLE_NAME IN ({$placeholders})"
        );
        $params = array_merge([$config['database']], $tables);
        $stmt->execute($params);
        $rows = $stmt->fetchAll();

        $stats = [];
        foreach ($rows as $row) {
            $stats[$row['TABLE_NAME']] = (int)$row['TABLE_ROWS'];
        }
        return $stats;
    } catch (PDOException $e) {
        return [];
    }
}
