<?php

declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';

function saas_mail_transport(): string
{
    $default = app_is_dev() ? 'log' : 'mail';

    return strtolower((string)app_env('APP_MAIL_TRANSPORT', $default));
}

function saas_mail_from(): string
{
    return (string)app_env('APP_MAIL_FROM', 'noreply@kaffeeliste.local');
}

function saas_mail_from_name(): string
{
    return (string)app_env('APP_MAIL_FROM_NAME', 'Kaffeeliste');
}

function saas_app_base_url(): string
{
    $configured = app_env('APP_BASE_URL');
    if ($configured !== null) {
        return rtrim($configured, '/');
    }

    if (PHP_SAPI !== 'cli' && !empty($_SERVER['HTTP_HOST'])) {
        $scheme = app_is_https() ? 'https' : 'http';

        return $scheme . '://' . rtrim((string)$_SERVER['HTTP_HOST'], '/');
    }

    return 'http://localhost';
}

function saas_app_url(string $path): string
{
    return saas_app_base_url() . '/' . ltrim($path, '/');
}

function saas_mail_headers(): string
{
    $fromName = str_replace(["\r", "\n"], '', saas_mail_from_name());
    $from = str_replace(["\r", "\n"], '', saas_mail_from());

    return implode("\r\n", [
        "From: {$fromName} <{$from}>",
        "Reply-To: {$from}",
        'Content-Type: text/plain; charset=UTF-8',
    ]);
}

function saas_log_mail(string $to, string $subject, string $body): array
{
    $logDir = (string)app_env('APP_MAIL_LOG_DIR', APP_ROOT . '/var/mail');
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0700, true);
    }

    if (!is_dir($logDir) || !is_writable($logDir)) {
        return [
            'ok' => false,
            'transport' => 'log',
            'error' => 'mail log directory is not writable',
        ];
    }

    $file = rtrim($logDir, '/') . '/mail_' . date('Ymd_His') . '_' . bin2hex(random_bytes(6)) . '.txt';
    $content = "To: {$to}\nSubject: {$subject}\n\n{$body}\n";

    if (file_put_contents($file, $content) === false) {
        return [
            'ok' => false,
            'transport' => 'log',
            'error' => 'mail log write failed',
        ];
    }

    return [
        'ok' => true,
        'transport' => 'log',
        'path' => $file,
    ];
}

function saas_send_mail(string $to, string $subject, string $body): array
{
    $to = trim($to);
    if (!filter_var($to, FILTER_VALIDATE_EMAIL)) {
        return [
            'ok' => false,
            'transport' => saas_mail_transport(),
            'error' => 'invalid recipient',
        ];
    }

    if (saas_mail_transport() === 'log') {
        return saas_log_mail($to, $subject, $body);
    }

    $sent = mail($to, $subject, $body, saas_mail_headers());

    return [
        'ok' => $sent,
        'transport' => 'mail',
        'error' => $sent ? null : 'mail transport failed',
    ];
}

function saas_send_password_reset_mail(string $to, string $token): array
{
    $link = saas_app_url('passwort-zuruecksetzen.php?token=' . urlencode($token));
    $body = implode("\n", [
        'Hallo,',
        '',
        'für dein Kaffeeliste-Konto wurde ein Passwort-Reset angefordert.',
        'Öffne diesen Link, um ein neues Passwort zu setzen:',
        '',
        $link,
        '',
        'Der Link ist zeitlich begrenzt und kann nur einmal verwendet werden.',
        'Falls du den Reset nicht angefordert hast, kannst du diese Nachricht ignorieren.',
        '',
        'Deine Kaffeeliste',
    ]);

    return saas_send_mail($to, 'Kaffeeliste Passwort zurücksetzen', $body);
}

/**
 * Renders the tenant-generic balance notification body. Replaces the old
 * mailversenden.php text, which hardcoded one customer's SMTP host,
 * PayPal link and FAQ URL and therefore only ever worked for that one
 * tenant.
 */
function saas_render_balance_mail_body(string $displayName, int $balanceCents, array $tenantSettings, string $dashboardUrl): string
{
    $amount = saas_format_money_cents(abs($balanceCents)) . ' €';
    $lines = ["Hallo {$displayName},", ''];

    if ($balanceCents < 0) {
        $lines[] = "dein aktueller Kaffeelisten-Stand ist im Minus: {$amount}.";
        $lines[] = "Bitte gleiche den Betrag bei Gelegenheit aus.";
        if ((int)($tenantSettings['paypal_enabled'] ?? 0) === 1 && trim((string)($tenantSettings['paypal_url_template'] ?? '')) !== '') {
            $paypalLink = trim((string)$tenantSettings['paypal_url_template']) . number_format(abs($balanceCents) / 100, 2, '.', '');
            $lines[] = '';
            $lines[] = "Direkt bezahlen: {$paypalLink}";
        }
    } else {
        $lines[] = "dein aktuelles Guthaben in der Kaffeeliste beträgt {$amount}.";
    }

    $lines[] = '';
    $lines[] = "Deinen aktuellen Stand findest du hier: {$dashboardUrl}";
    $lines[] = '';
    $lines[] = 'Deine Kaffeeliste';

    return implode("\n", $lines);
}

function saas_log_outbound_email(
    PDO $pdo,
    int $tenantId,
    ?int $participantId,
    string $template,
    string $subject,
    string $status,
    ?string $error,
    ?int $createdByUserId
): int {
    $stmt = $pdo->prepare(
        'INSERT INTO outbound_emails
           (tenant_id, participant_id, template, subject, status, sent_at, error, created_by_user_id)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
    );
    $stmt->execute([
        $tenantId,
        $participantId,
        $template,
        $subject,
        $status,
        in_array($status, ['sent', 'failed'], true) ? date('Y-m-d H:i:s') : null,
        $error,
        $createdByUserId,
    ]);

    return (int)$pdo->lastInsertId();
}

/**
 * @return list<array{id: int, participant_id: ?int, display_name: ?string, template: string, subject: string, status: string, sent_at: ?string, error: ?string, created_at: string}>
 */
function saas_fetch_outbound_email_log(PDO $pdo, int $tenantId, int $limit = 50): array
{
    $limit = max(1, min($limit, 200));
    $stmt = $pdo->prepare(
        "SELECT o.id, o.participant_id, p.display_name, o.template, o.subject, o.status, o.sent_at, o.error, o.created_at
         FROM outbound_emails o
         LEFT JOIN participants p ON p.id = o.participant_id
         WHERE o.tenant_id = ?
         ORDER BY o.created_at DESC, o.id DESC
         LIMIT {$limit}"
    );
    $stmt->execute([$tenantId]);

    return $stmt->fetchAll();
}

function saas_render_year_end_bonus_mail_body(string $displayName, int $yearMarks, int $bonusCents, string $dashboardUrl): string
{
    $bonus = saas_format_money_cents($bonusCents) . ' €';
    $lines = [
        "Hallo {$displayName},",
        '',
        "vielen Dank für deine Nutzung der Kaffeeliste in diesem Jahr!",
        "Du hast dieses Jahr {$yearMarks} Striche gemacht.",
        "Dafür wurden dir {$bonus} auf deinem Kaffeelisten-Konto gutgeschrieben.",
        '',
        "Deinen aktuellen Stand findest du hier: {$dashboardUrl}",
        '',
        'Deine Kaffeeliste',
    ];

    return implode("\n", $lines);
}

function saas_send_invite_mail(string $to, string $tenantName, string $role, string $token): array
{
    $link = saas_app_url('passwort-zuruecksetzen.php?token=' . urlencode($token));
    $body = implode("\n", [
        'Hallo,',
        '',
        "du wurdest für \"{$tenantName}\" in der Kaffeeliste als {$role} eingeladen.",
        'Öffne diesen Link, um ein Passwort zu setzen und dich anzumelden:',
        '',
        $link,
        '',
        'Der Link ist zeitlich begrenzt und kann nur einmal verwendet werden.',
        'Falls du diese Einladung nicht erwartet hast, kannst du diese Nachricht ignorieren.',
        '',
        'Deine Kaffeeliste',
    ]);

    return saas_send_mail($to, 'Einladung zur Kaffeeliste', $body);
}

function saas_send_email_verification_mail(string $to, string $token): array
{
    $link = saas_app_url('email-verifizieren.php?token=' . urlencode($token));
    $body = implode("\n", [
        'Hallo,',
        '',
        'bitte bestätige deine E-Mail-Adresse für Kaffeeliste.',
        'Öffne dazu diesen Link:',
        '',
        $link,
        '',
        'Der Link ist zeitlich begrenzt und kann nur einmal verwendet werden.',
        '',
        'Deine Kaffeeliste',
    ]);

    return saas_send_mail($to, 'Kaffeeliste E-Mail bestätigen', $body);
}
