<?php
declare(strict_types=1);

require_once __DIR__ . '/db.php';

/**
 * Minimal SMTP sender (LOGIN). Used when REMINDER_MAIL_DRIVER=smtp.
 */
function mail_send(string $to, string $subject, string $body, ?string $fromAddress = null, ?string $fromName = null): void
{
    $fromAddress = $fromAddress ?: (defined('REMINDER_EMAIL_FROM') ? REMINDER_EMAIL_FROM : 'noreply@localhost');
    $fromName = $fromName ?: 'BarberShop';
    $driver = defined('REMINDER_MAIL_DRIVER') ? REMINDER_MAIL_DRIVER : 'log';

    $logDir = APP_ROOT . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'reminders';
    if (!is_dir($logDir)) {
        mkdir($logDir, 0775, true);
    }
    file_put_contents(
        $logDir . DIRECTORY_SEPARATOR . 'email.log',
        sprintf("[%s] driver=%s TO=%s SUBJECT=%s\n%s\n----\n", date('c'), $driver, $to, $subject, $body),
        FILE_APPEND
    );

    if ($driver === 'log') {
        return;
    }

    if ($driver === 'smtp') {
        mail_smtp_send($to, $subject, $body, $fromAddress, $fromName);
        return;
    }

    $headers = [
        'MIME-Version: 1.0',
        'Content-type: text/plain; charset=utf-8',
        'From: ' . sprintf('"%s" <%s>', addslashes($fromName), $fromAddress),
    ];
    $ok = @mail($to, '=?UTF-8?B?' . base64_encode($subject) . '?=', $body, implode("\r\n", $headers));
    if (!$ok) {
        throw new RuntimeException('PHP mail() failed. Set REMINDER_MAIL_DRIVER=smtp with SMTP_* settings, or fix php.ini SMTP.');
    }
}

function mail_smtp_send(string $to, string $subject, string $body, string $fromAddress, string $fromName): void
{
    $host = defined('SMTP_HOST') ? SMTP_HOST : '';
    $port = (int) (defined('SMTP_PORT') ? SMTP_PORT : 587);
    $user = defined('SMTP_USER') ? SMTP_USER : '';
    $pass = defined('SMTP_PASS') ? SMTP_PASS : '';
    $enc = strtolower((string) (defined('SMTP_ENCRYPTION') ? SMTP_ENCRYPTION : 'tls'));

    if ($host === '') {
        throw new RuntimeException('SMTP_HOST is not configured in config/db.local.php');
    }

    $remote = ($enc === 'ssl' ? 'ssl://' : '') . $host;
    $fp = @fsockopen($remote, $port, $errno, $errstr, 20);
    if (!$fp) {
        throw new RuntimeException("SMTP connect failed: {$errstr} ({$errno})");
    }
    stream_set_timeout($fp, 20);

    $read = static function () use ($fp): string {
        $data = '';
        while ($line = fgets($fp, 515)) {
            $data .= $line;
            if (isset($line[3]) && $line[3] === ' ') {
                break;
            }
        }
        return $data;
    };
    $write = static function (string $cmd) use ($fp): void {
        fwrite($fp, $cmd . "\r\n");
    };
    $expect = static function (string $resp, string $code): void {
        if (!str_starts_with($resp, $code)) {
            throw new RuntimeException('SMTP error expecting ' . $code . ': ' . trim($resp));
        }
    };

    $expect($read(), '220');
    $write('EHLO localhost');
    $expect($read(), '250');

    if ($enc === 'tls') {
        $write('STARTTLS');
        $expect($read(), '220');
        if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
            throw new RuntimeException('SMTP STARTTLS failed');
        }
        $write('EHLO localhost');
        $expect($read(), '250');
    }

    if ($user !== '') {
        $write('AUTH LOGIN');
        $expect($read(), '334');
        $write(base64_encode($user));
        $expect($read(), '334');
        $write(base64_encode($pass));
        $expect($read(), '235');
    }

    $write('MAIL FROM:<' . $fromAddress . '>');
    $expect($read(), '250');
    $write('RCPT TO:<' . $to . '>');
    $rcpt = $read();
    if (!str_starts_with($rcpt, '250') && !str_starts_with($rcpt, '251')) {
        throw new RuntimeException('SMTP RCPT failed: ' . trim($rcpt));
    }
    $write('DATA');
    $expect($read(), '354');

    $encodedSubject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
    $payload = [
        'Date: ' . date('r'),
        'From: "' . addslashes($fromName) . '" <' . $fromAddress . '>',
        'To: <' . $to . '>',
        'Subject: ' . $encodedSubject,
        'MIME-Version: 1.0',
        'Content-Type: text/plain; charset=utf-8',
        'Content-Transfer-Encoding: 8bit',
        '',
        str_replace(["\r\n.", "\n."], ["\r\n..", "\n.."], $body),
        '.',
    ];
    fwrite($fp, implode("\r\n", $payload) . "\r\n");
    $expect($read(), '250');
    $write('QUIT');
    fclose($fp);
}

/**
 * Build email-to-SMS address: 5551234567@vtext.com
 */
function sms_gateway_address(?string $phoneDigits, ?string $domain): ?string
{
    $phone = preg_replace('/\D+/', '', (string) $phoneDigits) ?? '';
    $domain = strtolower(trim((string) $domain));
    if ($phone === '' || $domain === '' || $domain === 'custom') {
        return null;
    }
    // US: use last 10 digits
    if (strlen($phone) === 11 && str_starts_with($phone, '1')) {
        $phone = substr($phone, 1);
    }
    if (strlen($phone) < 10) {
        return null;
    }
    if (strlen($phone) > 10) {
        $phone = substr($phone, -10);
    }
    return $phone . '@' . $domain;
}

/**
 * @return list<array>
 */
function sms_carriers_list(bool $onlySelectable = true): array
{
    $sql = 'SELECT * FROM sms_carriers';
    if ($onlySelectable) {
        $sql .= ' WHERE is_active = 1';
    }
    $sql .= ' ORDER BY name';
    return db()->query($sql)->fetchAll();
}

function sms_carrier_by_id(?int $id): ?array
{
    if (!$id) {
        return null;
    }
    $stmt = db()->prepare('SELECT * FROM sms_carriers WHERE id = ?');
    $stmt->execute([$id]);
    $row = $stmt->fetch();
    return $row ?: null;
}
