<?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 SMS (bramki SMS)
 */

if (!defined('IBOK_CFG_DIR')) {
    define('IBOK_CFG_DIR', IBOK_ROOT . '/cfg');
}

define('IBOK_SMS_CONFIG_FILE', IBOK_CFG_DIR . '/sms.cfg');
define('IBOK_SMS_KEY_FILE', IBOK_CFG_DIR . '/.sms_key');

// =============================================
// Szyfrowanie tokenów/haseł
// =============================================

/**
 * Upewnij się, że klucz szyfrowania istnieje
 */
function sms_ensure_key() {
    if (file_exists(IBOK_SMS_KEY_FILE)) {
        return true;
    }
    if (!is_dir(IBOK_CFG_DIR)) {
        @mkdir(IBOK_CFG_DIR, 0750, true);
    }
    $key = bin2hex(random_bytes(32));
    return file_put_contents(IBOK_SMS_KEY_FILE, $key, LOCK_EX) !== false;
}

/**
 * Pobierz klucz szyfrowania
 */
function sms_get_key() {
    if (!file_exists(IBOK_SMS_KEY_FILE)) {
        sms_ensure_key();
    }
    $key = @file_get_contents(IBOK_SMS_KEY_FILE);
    if (empty($key)) {
        return false;
    }
    return hex2bin(trim($key));
}

/**
 * Szyfruj dane (AES-256-CBC)
 */
function sms_encrypt($data) {
    if (empty($data)) return '';
    $key = sms_get_key();
    if (!$key) return '';

    $iv = random_bytes(16);
    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    if ($encrypted === false) return '';

    return base64_encode($iv . $encrypted);
}

/**
 * Odszyfruj dane (AES-256-CBC)
 */
function sms_decrypt($data) {
    if (empty($data)) return '';
    $key = sms_get_key();
    if (!$key) return '';

    $raw = base64_decode($data, true);
    if ($raw === false || strlen($raw) < 17) return '';

    $iv = substr($raw, 0, 16);
    $encrypted = substr($raw, 16);

    $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return $decrypted !== false ? $decrypted : '';
}

// =============================================
// Konfiguracja
// =============================================

/**
 * Domyślna konfiguracja SMS
 */
function sms_default_config() {
    return [
        'active_gateway' => '',
        'test_mode'      => false,
        'default_prefix' => '48',
        'smsapi' => [
            'token'  => '',
            'sender' => '',
        ],
        'serwersms' => [
            'username' => '',
            'password' => '',
            'sender'   => '',
        ],
        'smsplanet' => [
            'token'  => '',
            'sender' => '',
        ],
    ];
}

/**
 * Wczytaj konfigurację SMS
 */
function sms_load_config() {
    if (!file_exists(IBOK_SMS_CONFIG_FILE)) {
        return sms_default_config();
    }

    $data = json_decode(file_get_contents(IBOK_SMS_CONFIG_FILE), true);
    if (!is_array($data)) {
        return sms_default_config();
    }

    $defaults = sms_default_config();
    $config = array_merge($defaults, $data);

    // Merge sub-arrays
    foreach (['smsapi', 'serwersms', 'smsplanet'] as $gw) {
        if (isset($data[$gw]) && is_array($data[$gw])) {
            $config[$gw] = array_merge($defaults[$gw], $data[$gw]);
        } else {
            $config[$gw] = $defaults[$gw];
        }
    }

    return $config;
}

/**
 * Zapisz konfigurację SMS
 */
function sms_save_config($config) {
    $defaults = sms_default_config();
    $save = [];

    $save['active_gateway'] = in_array($config['active_gateway'] ?? '', ['smsapi', 'serwersms', 'smsplanet', ''])
        ? ($config['active_gateway'] ?? '') : '';
    $save['test_mode'] = !empty($config['test_mode']);
    $save['default_prefix'] = preg_replace('/[^0-9]/', '', $config['default_prefix'] ?? '48') ?: '48';

    // Sub-arrays
    foreach (['smsapi', 'serwersms', 'smsplanet'] as $gw) {
        $save[$gw] = [];
        $gwData = $config[$gw] ?? [];
        foreach ($defaults[$gw] as $key => $default) {
            $save[$gw][$key] = isset($gwData[$key]) ? $gwData[$key] : $default;
        }
    }

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

    sms_ensure_key();

    return file_put_contents(
        IBOK_SMS_CONFIG_FILE,
        json_encode($save, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
        LOCK_EX
    ) !== false;
}

// =============================================
// Wysyłka SMS
// =============================================

/**
 * Wyślij SMS przez aktywną bramkę
 *
 * @param string $phone Numer telefonu
 * @param string $message Treść SMS
 * @return array ['success'=>bool, 'error'=>string, 'id'=>string]
 */
function sms_send($phone, $message) {
    $config = sms_load_config();
    $gateway = $config['active_gateway'];

    if (empty($gateway)) {
        return ['success' => false, 'error' => 'No active gateway', 'id' => ''];
    }

    // Tryb testowy
    if (!empty($config['test_mode'])) {
        if (function_exists('ibok_log')) {
            ibok_log("SMS test mode: to={$phone}, gateway={$gateway}, msg=" . mb_substr($message, 0, 50), 'info');
        }
        return ['success' => true, 'error' => '', 'id' => 'test_' . time()];
    }

    switch ($gateway) {
        case 'smsapi':
            return sms_send_smsapi($phone, $message, $config['smsapi']);
        case 'serwersms':
            return sms_send_serwersms($phone, $message, $config['serwersms']);
        case 'smsplanet':
            return sms_send_smsplanet($phone, $message, $config['smsplanet']);
        default:
            return ['success' => false, 'error' => 'Unknown gateway: ' . $gateway, 'id' => ''];
    }
}

/**
 * SMSAPI.pl - wyślij SMS
 */
function sms_send_smsapi($phone, $message, $gwConfig) {
    $token = sms_decrypt($gwConfig['token'] ?? '');
    if (empty($token)) {
        return ['success' => false, 'error' => 'No API token', 'id' => ''];
    }

    $params = [
        'to'      => $phone,
        'message' => $message,
        'format'  => 'json',
    ];
    if (!empty($gwConfig['sender'])) {
        $params['from'] = $gwConfig['sender'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api.smsapi.pl/sms.do',
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query($params),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $token,
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'error' => 'cURL: ' . $curlError, 'id' => ''];
    }

    $data = json_decode($response, true);

    if ($httpCode >= 200 && $httpCode < 300 && !isset($data['error'])) {
        $id = $data['list'][0]['id'] ?? ($data['id'] ?? '');
        return ['success' => true, 'error' => '', 'id' => (string)$id];
    }

    $error = $data['error'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'error' => (string)$error, 'id' => ''];
}

/**
 * SerwerSMS.pl - wyślij SMS
 */
function sms_send_serwersms($phone, $message, $gwConfig) {
    $username = $gwConfig['username'] ?? '';
    $password = sms_decrypt($gwConfig['password'] ?? '');
    if (empty($username) || empty($password)) {
        return ['success' => false, 'error' => 'No credentials', 'id' => ''];
    }

    $payload = [
        'username' => $username,
        'password' => $password,
        'phone'    => $phone,
        'text'     => $message,
    ];
    if (!empty($gwConfig['sender'])) {
        $payload['sender'] = $gwConfig['sender'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api2.serwersms.pl/messages/send_sms',
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($payload),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'error' => 'cURL: ' . $curlError, 'id' => ''];
    }

    $data = json_decode($response, true);

    if (isset($data['success']) && $data['success'] === true) {
        $id = $data['items'][0]['id'] ?? '';
        return ['success' => true, 'error' => '', 'id' => (string)$id];
    }

    $error = $data['error']['message'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'error' => (string)$error, 'id' => ''];
}

/**
 * SMSPlanet.pl - wyślij SMS
 */
function sms_send_smsplanet($phone, $message, $gwConfig) {
    $token = sms_decrypt($gwConfig['token'] ?? '');
    if (empty($token)) {
        return ['success' => false, 'error' => 'No API token', 'id' => ''];
    }

    $payload = [
        'to'  => $phone,
        'msg' => $message,
    ];
    if (!empty($gwConfig['sender'])) {
        $payload['from'] = $gwConfig['sender'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api.smsplanet.pl/sms',
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($payload),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $token,
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'error' => 'cURL: ' . $curlError, 'id' => ''];
    }

    $data = json_decode($response, true);

    if ($httpCode >= 200 && $httpCode < 300 && !empty($data['messageId'])) {
        return ['success' => true, 'error' => '', 'id' => (string)$data['messageId']];
    }

    $error = $data['error'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'error' => (string)$error, 'id' => ''];
}

// =============================================
// Sprawdzanie salda
// =============================================

/**
 * Sprawdź saldo bramki SMS
 *
 * @param string $gateway Nazwa bramki (smsapi, serwersms, smsplanet)
 * @return array ['success'=>bool, 'balance'=>string, 'error'=>string]
 */
function sms_check_balance($gateway) {
    $config = sms_load_config();

    switch ($gateway) {
        case 'smsapi':
            return sms_balance_smsapi($config['smsapi']);
        case 'serwersms':
            return sms_balance_serwersms($config['serwersms']);
        case 'smsplanet':
            return sms_balance_smsplanet($config['smsplanet']);
        default:
            return ['success' => false, 'balance' => '', 'error' => 'Unknown gateway'];
    }
}

/**
 * SMSAPI.pl - sprawdź saldo (punkty)
 */
function sms_balance_smsapi($gwConfig) {
    $token = sms_decrypt($gwConfig['token'] ?? '');
    if (empty($token)) {
        return ['success' => false, 'balance' => '', 'error' => 'No API token'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api.smsapi.pl/profile',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $token,
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'balance' => '', 'error' => 'cURL: ' . $curlError];
    }

    $data = json_decode($response, true);

    if ($httpCode === 200 && isset($data['points'])) {
        return ['success' => true, 'balance' => (string)$data['points'], 'error' => ''];
    }

    $error = $data['error'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'balance' => '', 'error' => (string)$error];
}

/**
 * SerwerSMS.pl - sprawdź saldo
 */
function sms_balance_serwersms($gwConfig) {
    $username = $gwConfig['username'] ?? '';
    $password = sms_decrypt($gwConfig['password'] ?? '');
    if (empty($username) || empty($password)) {
        return ['success' => false, 'balance' => '', 'error' => 'No credentials'];
    }

    $payload = [
        'username' => $username,
        'password' => $password,
    ];

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api2.serwersms.pl/account/info',
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($payload),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'balance' => '', 'error' => 'cURL: ' . $curlError];
    }

    $data = json_decode($response, true);

    if (isset($data['balance'])) {
        return ['success' => true, 'balance' => (string)$data['balance'], 'error' => ''];
    }

    $error = $data['error']['message'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'balance' => '', 'error' => (string)$error];
}

/**
 * SMSPlanet.pl - sprawdź saldo
 */
function sms_balance_smsplanet($gwConfig) {
    $token = sms_decrypt($gwConfig['token'] ?? '');
    if (empty($token)) {
        return ['success' => false, 'balance' => '', 'error' => 'No API token'];
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => 'https://api.smsplanet.pl/balance',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $token,
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'balance' => '', 'error' => 'cURL: ' . $curlError];
    }

    $data = json_decode($response, true);

    if ($httpCode === 200 && isset($data['balance'])) {
        return ['success' => true, 'balance' => (string)$data['balance'], 'error' => ''];
    }

    $error = $data['error'] ?? ($data['message'] ?? "HTTP {$httpCode}");
    return ['success' => false, 'balance' => '', 'error' => (string)$error];
}
