<?php
namespace App\Services;

use App\Core\Database;
use PDO;

final class ReminderService
{
    public function sendDueWalkReminders(): int
    {
        $pdo = Database::connection();
        $hours = (int)($GLOBALS['config']['reminders']['hours_before_walk'] ?? 24);
        $channels = $GLOBALS['config']['reminders']['channels'] ?? ['email'];
        $stmt = $pdo->prepare('SELECT w.*, r.route_name, r.start_address, r.end_address, r.total_km FROM walks w JOIN routes r ON r.id = w.route_id WHERE w.status = "open" AND TIMESTAMP(w.walk_date, w.start_time) BETWEEN DATE_ADD(NOW(), INTERVAL ? HOUR) AND DATE_ADD(NOW(), INTERVAL ? HOUR)');
        $stmt->execute([$hours - 1, $hours + 1]);
        $walks = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $sent = 0;
        $notifier = new NotificationService();
        foreach ($walks as $walk) {
            $people = $pdo->prepare('SELECT u.id, u.full_name, u.email, u.mobile FROM walk_registrations wr JOIN users u ON u.id = wr.user_id WHERE wr.walk_id = ? AND wr.registration_status IN ("registered", "approved")');
            $people->execute([(int)$walk['id']]);
            foreach ($people->fetchAll(PDO::FETCH_ASSOC) as $user) {
                foreach ($channels as $channel) {
                    if ($this->alreadySent((int)$user['id'], (int)$walk['id'], $channel)) continue;
                    $subject = 'Walk reminder: ' . $walk['title'];
                    $plain = $this->buildPlainReminder($user, $walk);
                    $html = nl2br(htmlspecialchars($plain, ENT_QUOTES, 'UTF-8'));
                    if ($channel === 'email' && !empty($user['email'])) {
                        $rendered = $notifier->renderWalkEmailContent((int)$walk['id'], 'walk_reminder', $user, $walk);
                        $notifier->sendEmail((int)$user['id'], (int)$walk['id'], $user['email'], $user['full_name'], $rendered['subject'], $rendered['html'], $rendered['text']);
                        $sent++;
                    } elseif ($channel === 'whatsapp' && !empty($user['mobile'])) {
                        $notifier->sendWhatsApp((int)$user['id'], (int)$walk['id'], $user['mobile'], $plain);
                        $sent++;
                    } elseif ($channel === 'in_app') {
                        $notifier->createInApp((int)$user['id'], (int)$walk['id'], $subject, $plain);
                        $sent++;
                    }
                }
            }
        }
        return $sent;
    }

    private function alreadySent(int $userId, int $walkId, string $channel): bool
    {
        $pdo = Database::connection();
        $stmt = $pdo->prepare('SELECT COUNT(*) FROM notifications WHERE user_id = ? AND walk_id = ? AND channel = ? AND status IN ("sent", "logged") AND subject LIKE "Walk reminder:%"');
        $stmt->execute([$userId, $walkId, $channel]);
        return (int)$stmt->fetchColumn() > 0;
    }

    private function buildPlainReminder(array $user, array $walk): string
    {
        $baseUrl = rtrim((string)($GLOBALS['config']['base_url'] ?? ''), '/');
        $link = $baseUrl ? $baseUrl . '/walk.php?id=' . (int)$walk['id'] : '';
        return "Hi {$user['full_name']},\n\nReminder: your Pyrk walk is tomorrow.\n\nWalk: {$walk['title']}\nRoute: {$walk['route_name']}\nDate: {$walk['walk_date']}\nStart: " . substr($walk['start_time'], 0, 5) . "\nExpected finish: " . substr($walk['expected_finish_time'], 0, 5) . "\nDistance: {$walk['total_km']} KM\nStart point: {$walk['start_address']}\n\nPlease arrive 15 minutes early and bring water.\n{$link}";
    }
}
