<?php
namespace App\Core;

use App\Core\Database;

class NotificationService
{
    private \PDO $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    public function preferenceAllowsInApp(
        int $userId,
        ?int $conferenceId,
        string $notificationType
    ): bool {
        $stmt = $this->db->prepare("
            SELECT in_app_enabled, muted_until
            FROM user_notification_preferences
            WHERE user_id=?
              AND notification_type=?
              AND (
                    conference_id=?
                    OR conference_id IS NULL
              )
            ORDER BY conference_id DESC
            LIMIT 1
        ");
        $stmt->execute([$userId, $notificationType, $conferenceId]);
        $pref = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$pref) {
            return true;
        }

        if ((int)$pref['in_app_enabled'] !== 1) {
            return false;
        }

        if (!empty($pref['muted_until']) && strtotime((string)$pref['muted_until']) > time()) {
            return false;
        }

        return true;
    }

    public function preferenceAllowsEmail(
        int $userId,
        ?int $conferenceId,
        string $notificationType
    ): bool {
        $stmt = $this->db->prepare("
            SELECT email_enabled, muted_until
            FROM user_notification_preferences
            WHERE user_id=?
              AND notification_type=?
              AND (
                    conference_id=?
                    OR conference_id IS NULL
              )
            ORDER BY conference_id DESC
            LIMIT 1
        ");
        $stmt->execute([$userId, $notificationType, $conferenceId]);
        $pref = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$pref) {
            return true;
        }

        if ((int)$pref['email_enabled'] !== 1) {
            return false;
        }

        if (!empty($pref['muted_until']) && strtotime((string)$pref['muted_until']) > time()) {
            return false;
        }

        return true;
    }

    public function create(array $data): int
    {
        $userId = (int)($data['user_id'] ?? 0);
        $conferenceId = !empty($data['conference_id']) ? (int)$data['conference_id'] : null;
        $type = (string)($data['notification_type'] ?? 'system');

        if ($userId <= 0) {
            return 0;
        }

        if (!$this->preferenceAllowsInApp($userId, $conferenceId, $type)) {
            return 0;
        }

        $stmt = $this->db->prepare("
            INSERT INTO user_notifications
            (org_id, conference_id, user_id, submission_id, notification_type, event_key,
             title, body, link_url, created_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");

        $stmt->execute([
            $data['org_id'] ?? null,
            $data['conference_id'] ?? null,
            $userId,
            $data['submission_id'] ?? null,
            $type,
            $data['event_key'] ?? null,
            $data['title'],
            $data['body'] ?? null,
            $data['link_url'] ?? null,
            $data['created_by'] ?? null,
        ]);

        return (int)$this->db->lastInsertId();
    }

    public function notifyAuthorWorkflow(array $submission, string $eventKey, string $title, string $body = ''): ?int
    {
        if (empty($submission['author_id'])) {
            return null;
        }

        return $this->create([
            'org_id' => (int)$submission['org_id'],
            'conference_id' => (int)$submission['conference_id'],
            'user_id' => (int)$submission['author_id'],
            'submission_id' => (int)$submission['id'],
            'notification_type' => 'workflow',
            'event_key' => $eventKey,
            'title' => $title,
            'body' => $body,
            'link_url' => '/easychair/author/workflow?submission_id=' . (int)$submission['id'],
            'created_by' => $_SESSION['user_id'] ?? null,
        ]);
    }

    public function unreadCount(int $userId, ?int $conferenceId = null): int
    {
        $where = "WHERE user_id=? AND is_read=0";
        $params = [$userId];

        if ($conferenceId !== null && $conferenceId > 0) {
            $where .= " AND (conference_id=? OR conference_id IS NULL)";
            $params[] = $conferenceId;
        }

        $stmt = $this->db->prepare("
            SELECT COUNT(*)
            FROM user_notifications
            {$where}
        ");
        $stmt->execute($params);

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

    public function latestForUser(int $userId, ?int $conferenceId = null, int $limit = 5): array
    {
        if ($limit <= 0 || $limit > 20) {
            $limit = 5;
        }

        $where = "WHERE n.user_id=?";
        $params = [$userId];

        if ($conferenceId !== null && $conferenceId > 0) {
            $where .= " AND (n.conference_id=? OR n.conference_id IS NULL)";
            $params[] = $conferenceId;
        }

        $stmt = $this->db->prepare("
            SELECT 
                n.*,
                s.submission_no,
                COALESCE(s.title,s.title_en,s.title_ar) AS submission_title,
                c.short_name AS conference_short_name
            FROM user_notifications n
            LEFT JOIN submissions s ON s.id=n.submission_id
            LEFT JOIN conferences c ON c.id=n.conference_id
            {$where}
            ORDER BY n.id DESC
            LIMIT {$limit}
        ");
        $stmt->execute($params);

        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
}
