<?php

declare(strict_types=1);

namespace App\Services;

use App\Core\Database;
use PDO;

/**
 * NotificationService
 *
 * Foundation for the Notification Center + notification bell badge.
 * Deliberately scoped to Phase 1: creating/reading/marking-read
 * in-app notifications and checking a user's channel preferences.
 * Actually SENDING an email/SMS notification (as opposed to writing
 * the in-app row) is left to MailService + a future queue worker —
 * this class only decides WHETHER a channel is enabled for a user, it
 * doesn't perform delivery itself.
 */
final class NotificationService
{
    public static function notify(
        int $userId,
        string $type,
        string $title,
        string $message,
        ?string $relatedEntityType = null,
        ?int $relatedEntityId = null
    ): int {
        if (!self::channelEnabled($userId, $type, 'in_app')) {
            return 0;
        }

        $stmt = Database::connection()->prepare(
            'INSERT INTO notifications (user_id, type, title, message, related_entity_type, related_entity_id, is_read, created_at)
             VALUES (:user_id, :type, :title, :message, :entity_type, :entity_id, 0, NOW())'
        );

        $stmt->execute([
            'user_id' => $userId,
            'type' => $type,
            'title' => $title,
            'message' => $message,
            'entity_type' => $relatedEntityType,
            'entity_id' => $relatedEntityId,
        ]);

        return (int) Database::connection()->lastInsertId();
    }

    /** Notify every user who can see a given business line — e.g. "new lead" fan-out. */
    public static function notifyBusinessLine(int $businessLineId, string $type, string $title, string $message): void
    {
        $stmt = Database::connection()->prepare(
            'SELECT user_id FROM user_business_lines WHERE business_line_id = :bl'
        );
        $stmt->execute(['bl' => $businessLineId]);

        foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $userId) {
            self::notify((int) $userId, $type, $title, $message);
        }
    }

    public static function unreadCount(int $userId): int
    {
        $stmt = Database::connection()->prepare(
            'SELECT COUNT(*) FROM notifications WHERE user_id = :id AND is_read = 0'
        );
        $stmt->execute(['id' => $userId]);

        return (int) $stmt->fetchColumn();
    }

    public static function recentFor(int $userId, int $limit = 20): array
    {
        $stmt = Database::connection()->prepare(
            'SELECT * FROM notifications WHERE user_id = :id ORDER BY created_at DESC LIMIT :limit'
        );
        $stmt->bindValue('id', $userId, PDO::PARAM_INT);
        $stmt->bindValue('limit', $limit, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll();
    }

    public static function markRead(int $userId, int $notificationId): bool
    {
        $stmt = Database::connection()->prepare(
            'UPDATE notifications SET is_read = 1, read_at = NOW() WHERE id = :id AND user_id = :user_id'
        );

        return $stmt->execute(['id' => $notificationId, 'user_id' => $userId]);
    }

    public static function markAllRead(int $userId): bool
    {
        $stmt = Database::connection()->prepare(
            'UPDATE notifications SET is_read = 1, read_at = NOW() WHERE user_id = :id AND is_read = 0'
        );

        return $stmt->execute(['id' => $userId]);
    }

    public static function channelEnabled(int $userId, string $type, string $channel): bool
    {
        $stmt = Database::connection()->prepare(
            'SELECT is_enabled FROM notification_preferences WHERE user_id = :id AND type = :type AND channel = :channel'
        );
        $stmt->execute(['id' => $userId, 'type' => $type, 'channel' => $channel]);

        $value = $stmt->fetchColumn();

        // No explicit preference row yet = default to enabled (opt-out
        // model), matching the Notifications page where every toggle
        // starts "on" until the user turns it off.
        return $value === false ? true : (bool) $value;
    }
}
