<?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 - Funkcje pomocnicze płatności online (Tpay, Przelewy24, PayU)
 */

if (!defined('IBOK_CFG_DIR')) {
    define('IBOK_CFG_DIR', IBOK_ROOT . '/cfg');
}
if (!defined('IBOK_PAYMENTS_DIR')) {
    define('IBOK_PAYMENTS_DIR', IBOK_ROOT . '/db/payments');
}
if (!defined('IBOK_PAYMENTS_SESSIONS_DIR')) {
    define('IBOK_PAYMENTS_SESSIONS_DIR', IBOK_PAYMENTS_DIR . '/sessions');
}

/**
 * Wczytaj konfigurację bramki płatności
 */
function payment_load_config($gateway) {
    $allowed = ['tpay', 'p24', 'payu'];
    if (!in_array($gateway, $allowed)) return null;

    $file = IBOK_CFG_DIR . '/' . $gateway . '.cfg';
    if (!file_exists($file)) {
        return payment_default_config($gateway);
    }

    $data = json_decode(file_get_contents($file), true);
    if (!is_array($data)) {
        return payment_default_config($gateway);
    }

    return array_merge(payment_default_config($gateway), $data);
}

/**
 * Domyślna konfiguracja bramki
 */
function payment_default_config($gateway) {
    $common = [
        'enabled' => false,
        'test_mode' => true,
        'notification_url' => '',
        'return_url' => '',
        'description_template' => 'Faktura {NR_FAKTURY} - klient {CLIENT_ID}',
        'terms_url' => '',
    ];

    switch ($gateway) {
        case 'tpay':
            return array_merge($common, [
                'merchant_id' => '',
                'security_code' => '',
            ]);
        case 'p24':
            return array_merge($common, [
                'merchant_id' => '',
                'pos_id' => '',
                'crc_key' => '',
                'api_key' => '',
            ]);
        case 'payu':
            return array_merge($common, [
                'pos_id' => '',
                'md5_key' => '',
                'client_id' => '',
                'client_secret' => '',
            ]);
        default:
            return $common;
    }
}

/**
 * Zapisz konfigurację bramki
 */
function payment_save_config($gateway, $config) {
    $allowed = ['tpay', 'p24', 'payu'];
    if (!in_array($gateway, $allowed)) return false;

    if (!is_dir(IBOK_CFG_DIR)) {
        @mkdir(IBOK_CFG_DIR, 0750, true);
    }

    $file = IBOK_CFG_DIR . '/' . $gateway . '.cfg';
    return file_put_contents($file, json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX) !== false;
}

/**
 * Pobierz listę włączonych bramek
 */
function payment_get_enabled_gateways() {
    $gateways = [];
    foreach (['tpay', 'p24', 'payu'] as $gw) {
        $cfg = payment_load_config($gw);
        if (!empty($cfg['enabled'])) {
            $gateways[] = $gw;
        }
    }
    return $gateways;
}

/**
 * Utwórz sesję płatności
 */
function payment_create_session($gateway, $client_id, $invoice_nr, $amount, $description = '') {
    // Demo: nie tworzymy sesji płatności (caller wykrywa brak tokenu przez if(!$token))
    if (function_exists('ibok_is_demo') && ibok_is_demo()) {
        return null;
    }
    if (!is_dir(IBOK_PAYMENTS_SESSIONS_DIR)) {
        @mkdir(IBOK_PAYMENTS_SESSIONS_DIR, 0750, true);
    }

    $token = bin2hex(random_bytes(16));

    $session = [
        'token' => $token,
        'gateway' => $gateway,
        'client_id' => $client_id,
        'invoice_nr' => $invoice_nr,
        'amount' => (float)$amount,
        'description' => $description,
        'created' => time(),
        'status' => 'pending',
    ];

    $file = IBOK_PAYMENTS_SESSIONS_DIR . '/' . $token . '.json';
    if (file_put_contents($file, json_encode($session, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX) === false) {
        return null;
    }

    return $token;
}

/**
 * Wczytaj sesję płatności po tokenie
 */
/**
 * @param bool $check_expiry Czy sprawdzać TTL (24h) - false dla odczytu historii/statusu
 */
function payment_load_session($token, $check_expiry = false) {
    if (!preg_match('/^[a-f0-9]{32}$/', $token)) return null;

    $file = IBOK_PAYMENTS_SESSIONS_DIR . '/' . $token . '.json';
    if (!file_exists($file)) return null;

    $data = json_decode(file_get_contents($file), true);
    if (!is_array($data)) return null;

    // Sesja ważna 24h (dla init/callback), nie dla odczytu statusu
    if ($check_expiry && isset($data['created'])) {
        if ((time() - $data['created']) > 86400) {
            return null;
        }
    }

    return $data;
}

/**
 * Oznacz sesję jako zrealizowaną
 */
function payment_complete_session($token, $gateway_tx_id = '', $extra = []) {
    $session = payment_load_session($token);
    if (!$session) return false;

    // Ochrona przed replay - nie nadpisuj zakończonej sesji
    if ($session['status'] === 'completed' || $session['status'] === 'failed') {
        return false;
    }

    $session['status'] = 'completed';
    $session['completed'] = time();
    $session['gateway_tx_id'] = $gateway_tx_id;
    if (!empty($extra)) {
        $session['extra'] = $extra;
    }

    $file = IBOK_PAYMENTS_SESSIONS_DIR . '/' . $token . '.json';
    return file_put_contents($file, json_encode($session, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX) !== false;
}

/**
 * Oznacz sesję jako nieudaną
 */
function payment_fail_session($token, $reason = '') {
    $session = payment_load_session($token);
    if (!$session) return false;

    // Nie nadpisuj zakończonej sesji
    if ($session['status'] === 'completed') {
        return false;
    }

    $session['status'] = 'failed';
    $session['failed'] = time();
    $session['fail_reason'] = $reason;

    $file = IBOK_PAYMENTS_SESSIONS_DIR . '/' . $token . '.json';
    return file_put_contents($file, json_encode($session, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX) !== false;
}

/**
 * Loguj zdarzenie płatności
 */
function payment_log($message) {
    if (!is_dir(IBOK_PAYMENTS_DIR)) {
        @mkdir(IBOK_PAYMENTS_DIR, 0750, true);
    }

    // Sanityzacja: usuń newline/CR z wiadomości (ochrona przed log injection)
    $message = str_replace(["\r", "\n", "\0"], ['', '', ''], $message);
    $ip = preg_replace('/[^0-9a-fA-F.:,]/', '', $_SERVER['REMOTE_ADDR'] ?? 'unknown');

    $file = IBOK_PAYMENTS_DIR . '/' . date('Y-m') . '.log';
    $line = date('Y-m-d H:i:s') . " [{$ip}] {$message}\n";
    @file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
}

/**
 * Zwróć etykietę bramki
 */
function payment_gateway_label($gw) {
    $labels = [
        'tpay' => 'Tpay',
        'p24' => 'Przelewy24',
        'payu' => 'PayU',
    ];
    return $labels[$gw] ?? $gw;
}

/**
 * URL regulaminu bramki — z konfiguracji (cfg['terms_url']) lub domyślny oficjalny.
 * Pokazywany klientowi do akceptacji przed płatnością (wymóg przy przerzuceniu prowizji).
 */
function payment_terms_url($gateway, $cfg = null) {
    if ($cfg === null) {
        $cfg = payment_load_config($gateway);
    }
    if (!empty($cfg['terms_url'])) {
        return $cfg['terms_url'];
    }
    $defaults = [
        'tpay' => 'https://tpay.com/regulaminy',
        'p24'  => 'https://www.przelewy24.pl/regulamin',
        'payu' => 'https://www.payu.pl/regulaminy',
    ];
    return $defaults[$gateway] ?? '';
}

/**
 * Wygeneruj opis płatności z szablonu
 */
function payment_build_description($template, $invoice_nr, $client_id) {
    return str_replace(
        ['{NR_FAKTURY}', '{CLIENT_ID}'],
        [$invoice_nr, $client_id],
        $template
    );
}

/**
 * Pobierz listę logów płatności (do historii admin)
 */
function payment_get_log_files() {
    $dir = IBOK_PAYMENTS_DIR;
    if (!is_dir($dir)) return [];

    $files = [];
    foreach (glob($dir . '/*.log') as $f) {
        $files[] = [
            'name' => basename($f),
            'size' => filesize($f),
            'modified' => filemtime($f),
        ];
    }

    usort($files, function($a, $b) {
        return strcmp($b['name'], $a['name']);
    });

    return $files;
}

/**
 * Wczytaj wpisy z logów płatności
 */
function payment_read_log($filename) {
    if (!preg_match('/^\d{4}-\d{2}\.log$/', $filename)) return [];

    $file = IBOK_PAYMENTS_DIR . '/' . $filename;
    if (!file_exists($file)) return [];

    $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (!$lines) return [];

    $entries = [];
    foreach (array_reverse($lines) as $line) {
        if (preg_match('/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[([^\]]*)\] (.+)$/', $line, $m)) {
            $entries[] = [
                'date' => $m[1],
                'ip' => $m[2],
                'message' => $m[3],
            ];
        }
    }

    return $entries;
}

/**
 * Pobierz zrealizowane sesje płatności (do historii admin)
 */
function payment_get_completed_sessions($limit = 100) {
    $dir = IBOK_PAYMENTS_SESSIONS_DIR;
    if (!is_dir($dir)) return [];

    $sessions = [];
    $files = glob($dir . '/*.json');
    if (!$files) return [];

    // Sort by modification time, newest first
    usort($files, function($a, $b) {
        return filemtime($b) - filemtime($a);
    });

    $count = 0;
    foreach ($files as $f) {
        if ($count >= $limit) break;
        $data = json_decode(file_get_contents($f), true);
        if (is_array($data)) {
            // Zwracaj tylko niezbędne pola (nie ujawniaj tokenów)
            $sessions[] = [
                'gateway' => $data['gateway'] ?? '',
                'client_id' => $data['client_id'] ?? '',
                'invoice_nr' => $data['invoice_nr'] ?? '',
                'amount' => $data['amount'] ?? 0,
                'created' => $data['created'] ?? 0,
                'status' => $data['status'] ?? 'pending',
                'gateway_tx_id' => $data['gateway_tx_id'] ?? '',
            ];
            $count++;
        }
    }

    return $sessions;
}
