<?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 SMTP (PHPMailer)
 */

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

define('IBOK_SMTP_CONFIG_FILE', IBOK_CFG_DIR . '/smtp.cfg');

// Autoload PHPMailer (bez Composera)
require_once __DIR__ . '/mailer/src/Exception.php';
require_once __DIR__ . '/mailer/src/PHPMailer.php';
require_once __DIR__ . '/mailer/src/SMTP.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;

/**
 * Domyslna konfiguracja SMTP
 */
function smtp_default_config() {
    return [
        'enabled'    => false,
        'host'       => '',
        'port'       => 587,
        'encryption' => 'tls',    // none, tls, ssl
        'auth'       => true,
        'username'   => '',
        'password'   => '',
        'from_email' => '',
        'from_name'  => 'i-BOK',
    ];
}

/**
 * Wczytaj konfigurację SMTP
 */
function smtp_load_config() {
    if (!file_exists(IBOK_SMTP_CONFIG_FILE)) {
        return smtp_default_config();
    }

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

    return array_merge(smtp_default_config(), $data);
}

/**
 * Zapisz konfigurację SMTP
 */
function smtp_save_config($config) {
    $defaults = smtp_default_config();
    $save = [];
    foreach ($defaults as $key => $default) {
        $save[$key] = isset($config[$key]) ? $config[$key] : $default;
    }

    // Typy
    $save['enabled'] = (bool)$save['enabled'];
    $save['port'] = (int)$save['port'];
    $save['auth'] = (bool)$save['auth'];

    // Walidacja encryption
    if (!in_array($save['encryption'], ['none', 'tls', 'ssl'])) {
        $save['encryption'] = 'tls';
    }

    // Walidacja port
    if ($save['port'] < 1 || $save['port'] > 65535) {
        $save['port'] = 587;
    }

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

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

/**
 * Utwórz skonfigurowaną instancję PHPMailer
 */
function smtp_create_mailer() {
    $config = smtp_load_config();
    $mail = new PHPMailer(true);

    // Język polski dla komunikatów błędów
    $langFile = __DIR__ . '/mailer/language/phpmailer.lang-pl.php';
    if (file_exists($langFile)) {
        $mail->setLanguage('pl', __DIR__ . '/mailer/language/');
    }

    if (!empty($config['host'])) {
        $mail->isSMTP();
        $mail->Host = $config['host'];
        $mail->Port = $config['port'];
        $mail->SMTPAuth = $config['auth'];

        if ($config['auth']) {
            $mail->Username = $config['username'];
            $mail->Password = $config['password'];
        }

        switch ($config['encryption']) {
            case 'tls':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                break;
            case 'ssl':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
                break;
            default:
                $mail->SMTPSecure = '';
                $mail->SMTPAutoTLS = false;
                break;
        }
    } else {
        // Fallback na mail() — tylko gdy brak hosta SMTP
        $mail->isMail();
    }

    $mail->CharSet = 'UTF-8';
    $mail->Encoding = 'base64';

    // From
    $fromEmail = !empty($config['from_email']) ? $config['from_email'] : ($config['username'] ?: 'noreply@localhost');
    $fromName = !empty($config['from_name']) ? $config['from_name'] : 'i-BOK';
    $mail->setFrom($fromEmail, $fromName);

    return $mail;
}

/**
 * Wyślij email
 *
 * @param string $to Adres odbiorcy
 * @param string $subject Temat
 * @param string $body Treść (plain text)
 * @param string $replyTo Opcjonalny adres Reply-To
 * @param string $replyToName Opcjonalna nazwa Reply-To
 * @return array ['success' => bool, 'error' => string]
 */
function smtp_send_mail($to, $subject, $body, $replyTo = '', $replyToName = '') {
    try {
        $mail = smtp_create_mailer();

        $mail->addAddress($to);

        if (!empty($replyTo)) {
            $mail->addReplyTo($replyTo, $replyToName);
        }

        $mail->isHTML(false);
        $mail->Subject = $subject;
        $mail->Body = $body;

        $mail->send();
        return ['success' => true, 'error' => ''];
    } catch (PHPMailerException $e) {
        return ['success' => false, 'error' => $e->getMessage()];
    } catch (\Exception $e) {
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

/**
 * Testuj połączenie SMTP
 *
 * @param array $config Konfiguracja do przetestowania
 * @return array ['success' => bool, 'error' => string, 'debug' => string]
 */
function smtp_test_connection($config) {
    $debug_output = '';

    try {
        $mail = new PHPMailer(true);
        $mail->isSMTP();
        $mail->Host = $config['host'] ?? '';
        $mail->Port = (int)($config['port'] ?? 587);
        $mail->SMTPAuth = (bool)($config['auth'] ?? true);

        if ($mail->SMTPAuth) {
            $mail->Username = $config['username'] ?? '';
            $mail->Password = $config['password'] ?? '';
        }

        $encryption = $config['encryption'] ?? 'tls';
        switch ($encryption) {
            case 'tls':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                break;
            case 'ssl':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
                break;
            default:
                $mail->SMTPSecure = '';
                $mail->SMTPAutoTLS = false;
                break;
        }

        $mail->SMTPDebug = 2;
        $mail->Debugoutput = function($str, $level) use (&$debug_output) {
            $debug_output .= trim($str) . "\n";
        };

        $mail->Timeout = 10;

        $smtp = $mail->getSMTPInstance();

        // Dla SSL trzeba użyć prefixu ssl://
        $connectHost = $mail->Host;
        if ($encryption === 'ssl') {
            $connectHost = 'ssl://' . $mail->Host;
        }

        $connected = $smtp->connect($connectHost, $mail->Port, $mail->Timeout);

        if (!$connected) {
            return [
                'success' => false,
                'error' => 'Connection failed',
                'debug' => $debug_output,
            ];
        }

        // EHLO przed STARTTLS
        $smtp->hello(gethostname() ?: 'localhost');

        if ($encryption === 'tls') {
            if (!$smtp->startTLS()) {
                $smtp->quit();
                return [
                    'success' => false,
                    'error' => 'STARTTLS failed',
                    'debug' => $debug_output,
                ];
            }
            // Po STARTTLS wymagany ponowny EHLO (RFC 3207)
            $smtp->hello(gethostname() ?: 'localhost');
        }

        if ($mail->SMTPAuth) {
            $auth = $smtp->authenticate($mail->Username, $mail->Password);
            if (!$auth) {
                $smtp->quit();
                return [
                    'success' => false,
                    'error' => 'Authentication failed',
                    'debug' => $debug_output,
                ];
            }
        }

        $smtp->quit();
        return [
            'success' => true,
            'error' => '',
            'debug' => $debug_output,
        ];
    } catch (PHPMailerException $e) {
        return [
            'success' => false,
            'error' => $e->getMessage(),
            'debug' => $debug_output,
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'error' => $e->getMessage(),
            'debug' => $debug_output,
        ];
    }
}

/**
 * Testuj wysyłkę emaila
 *
 * @param array $config Konfiguracja SMTP
 * @param string $testTo Adres testowy
 * @return array ['success' => bool, 'error' => string]
 */
function smtp_test_send($config, $testTo) {
    $debug_output = '';

    try {
        $mail = new PHPMailer(true);

        $langFile = __DIR__ . '/mailer/language/phpmailer.lang-pl.php';
        if (file_exists($langFile)) {
            $mail->setLanguage('pl', __DIR__ . '/mailer/language/');
        }

        $mail->isSMTP();
        $mail->Host = $config['host'] ?? '';
        $mail->Port = (int)($config['port'] ?? 587);
        $mail->SMTPAuth = (bool)($config['auth'] ?? true);

        if ($mail->SMTPAuth) {
            $mail->Username = $config['username'] ?? '';
            $mail->Password = $config['password'] ?? '';
        }

        $encryption = $config['encryption'] ?? 'tls';
        switch ($encryption) {
            case 'tls':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                break;
            case 'ssl':
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
                break;
            default:
                $mail->SMTPSecure = '';
                $mail->SMTPAutoTLS = false;
                break;
        }

        $mail->CharSet = 'UTF-8';
        $mail->Encoding = 'base64';
        $mail->Timeout = 15;

        // Debug do diagnostyki
        $mail->SMTPDebug = 2;
        $mail->Debugoutput = function($str, $level) use (&$debug_output) {
            $debug_output .= trim($str) . "\n";
        };

        $fromEmail = !empty($config['from_email']) ? $config['from_email'] : ($config['username'] ?: 'noreply@localhost');
        $fromName = !empty($config['from_name']) ? $config['from_name'] : 'i-BOK';
        $mail->setFrom($fromEmail, $fromName);
        $mail->addAddress($testTo);

        $mail->isHTML(false);
        $mail->Subject = 'i-BOK - Test SMTP';
        $mail->Body = "To jest wiadomosc testowa z panelu i-BOK.\n\nJesli ja widzisz, konfiguracja SMTP dziala prawidlowo.\n\nData: " . date('Y-m-d H:i:s');

        $result = $mail->send();
        if ($result) {
            return ['success' => true, 'error' => '', 'debug' => $debug_output];
        }
        return ['success' => false, 'error' => $mail->ErrorInfo, 'debug' => $debug_output];
    } catch (PHPMailerException $e) {
        return ['success' => false, 'error' => $e->getMessage(), 'debug' => $debug_output];
    } catch (\Exception $e) {
        return ['success' => false, 'error' => $e->getMessage(), 'debug' => $debug_output];
    }
}
