<?php

require_once BASE_PATH . '/config/database.php';

class Notification
{
    private PDO $db;

    public function __construct()
    {
        $this->db = (new Database())->connect();
    }

    public function create(
        int $userId,
        string $type,
        string $title,
        string $message,
        ?string $link = null
    ): void {
        $stmt = $this->db->prepare(
            'INSERT INTO notifications (
                user_id, type, title, message, link, is_read
             ) VALUES (
                :user_id, :type, :title, :message, :link, 0
             )'
        );
        $stmt->execute([
            'user_id' => $userId,
            'type' => $type,
            'title' => $title,
            'message' => $message,
            'link' => $link
        ]);
    }

    public function countUnreadByUser(int $userId): int
    {
        $stmt = $this->db->prepare(
            'SELECT COUNT(*) FROM notifications
             WHERE user_id = :user_id AND is_read = 0'
        );
        $stmt->execute(['user_id' => $userId]);

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

    public function countForUser(int $userId, string $state = ''): int
    {
        [$where, $params] = $this->buildStateFilter($userId, $state);
        $stmt = $this->db->prepare(
            "SELECT COUNT(*) FROM notifications WHERE {$where}"
        );
        $stmt->execute($params);

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

    public function getForUser(
        int $userId,
        string $state = '',
        int $limit = 20,
        int $offset = 0
    ): array {
        [$where, $params] = $this->buildStateFilter($userId, $state);
        $limit = max(1, $limit);
        $offset = max(0, $offset);

        $stmt = $this->db->prepare(
            "SELECT * FROM notifications
             WHERE {$where}
             ORDER BY created_at DESC, id DESC
             LIMIT {$limit} OFFSET {$offset}"
        );
        $stmt->execute($params);

        return $stmt->fetchAll();
    }

    public function findOwnedByUser(int $notificationId, int $userId): ?array
    {
        $stmt = $this->db->prepare(
            'SELECT * FROM notifications
             WHERE id = :id AND user_id = :user_id
             LIMIT 1'
        );
        $stmt->execute([
            'id' => $notificationId,
            'user_id' => $userId
        ]);

        $notification = $stmt->fetch();
        return $notification ?: null;
    }

    public function markRead(int $notificationId, int $userId): void
    {
        $stmt = $this->db->prepare(
            'UPDATE notifications
             SET is_read = 1, read_at = COALESCE(read_at, NOW())
             WHERE id = :id AND user_id = :user_id AND is_read = 0'
        );
        $stmt->execute([
            'id' => $notificationId,
            'user_id' => $userId
        ]);
    }

    public function markAllRead(int $userId): void
    {
        $stmt = $this->db->prepare(
            'UPDATE notifications
             SET is_read = 1, read_at = COALESCE(read_at, NOW())
             WHERE user_id = :user_id AND is_read = 0'
        );
        $stmt->execute(['user_id' => $userId]);
    }

    private function buildStateFilter(int $userId, string $state): array
    {
        $where = 'user_id = :user_id';
        $params = ['user_id' => $userId];

        if ($state === 'unread') {
            $where .= ' AND is_read = 0';
        }

        if ($state === 'read') {
            $where .= ' AND is_read = 1';
        }

        return [$where, $params];
    }
}
