<?php
/**
 * Notification Model
 * Maps to `notifications` table
 * Handles fetching, counting, unread tracking, and status transitions for user notifications
 */

require_once __DIR__ . '/../Core/Model.php';

class Notification extends Model {
    protected string $table = 'notifications';

    /**
     * Get Paginated Notifications for a User
     */
    public function getNotificationsByUser(int $userId, array $filters = [], int $limit = 20, int $offset = 0): array {
        [$whereSql, $params] = $this->buildConditions($userId, $filters);

        $sql = "SELECT * FROM `notifications`
                WHERE {$whereSql}
                ORDER BY `created_at` DESC
                LIMIT :limit OFFSET :offset";

        $stmt = $this->db->prepare($sql);
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v);
        }
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll();
    }

    public function countNotificationsByUser(int $userId, array $filters = []): int {
        [$whereSql, $params] = $this->buildConditions($userId, $filters);
        $sql = "SELECT COUNT(*) FROM `notifications` WHERE {$whereSql}";
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return (int)$stmt->fetchColumn();
    }

    /**
     * Get Unread Notifications Count for quick Navbar Badge
     */
    public function getUnreadCount(int $userId, ?string $roleTarget = null): int {
        $sql = "SELECT COUNT(*) FROM `notifications` WHERE `user_id` = :user_id AND `is_read` = 0";
        $params = [':user_id' => $userId];

        if ($roleTarget !== null && $roleTarget !== 'all') {
            $sql .= " AND `role_target` = :role";
            $params[':role'] = $roleTarget;
        }

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return (int)$stmt->fetchColumn();
    }

    /**
     * Get Latest N Notifications (for Navbar Dropdown Preview)
     */
    public function getLatestNotifications(int $userId, int $limit = 5, ?string $roleTarget = null): array {
        $sql = "SELECT * FROM `notifications` WHERE `user_id` = :user_id";
        $params = [':user_id' => $userId];

        if ($roleTarget !== null && $roleTarget !== 'all') {
            $sql .= " AND `role_target` = :role";
            $params[':role'] = $roleTarget;
        }

        $sql .= " ORDER BY `created_at` DESC LIMIT :limit";

        $stmt = $this->db->prepare($sql);
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v);
        }
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll();
    }

    /**
     * Mark a single notification as read
     */
    public function markAsRead(int $notificationId, int $userId): bool {
        $sql = "UPDATE `notifications`
                SET `is_read` = 1, `read_at` = COALESCE(`read_at`, NOW())
                WHERE `id` = :id AND `user_id` = :user_id";
        $stmt = $this->query($sql, [
            ':id'      => $notificationId,
            ':user_id' => $userId
        ]);
        return $stmt->rowCount() > 0;
    }

    /**
     * Mark all notifications as read for a user
     */
    public function markAllAsRead(int $userId, ?string $roleTarget = null): bool {
        $sql = "UPDATE `notifications`
                SET `is_read` = 1, `read_at` = NOW()
                WHERE `user_id` = :user_id AND `is_read` = 0";
        $params = [':user_id' => $userId];

        if ($roleTarget !== null && $roleTarget !== 'all') {
            $sql .= " AND `role_target` = :role";
            $params[':role'] = $roleTarget;
        }

        $this->query($sql, $params);
        return true;
    }

    /**
     * Delete notification securely
     */
    public function deleteNotification(int $notificationId, int $userId): bool {
        $sql = "DELETE FROM `notifications` WHERE `id` = :id AND `user_id` = :user_id";
        $stmt = $this->query($sql, [
            ':id'      => $notificationId,
            ':user_id' => $userId
        ]);
        return $stmt->rowCount() > 0;
    }

    /**
     * Insert Notification Record
     */
    public function createNotification(array $data): int {
        return $this->insert([
            'user_id'     => $data['user_id'],
            'role_target' => $data['role_target'] ?? 'customer',
            'type'        => $data['type'],
            'title'       => $data['title'],
            'message'     => $data['message'],
            'target_type' => $data['target_type'] ?? null,
            'target_id'   => $data['target_id'] ?? null,
            'action_url'  => $data['action_url'] ?? null,
            'is_read'     => 0,
            'read_at'     => null,
            'created_at'  => date('Y-m-d H:i:s')
        ]);
    }

    private function buildConditions(int $userId, array $filters): array {
        $conditions = ["`user_id` = :user_id"];
        $params = [':user_id' => $userId];

        if (isset($filters['is_read']) && $filters['is_read'] !== 'all' && $filters['is_read'] !== '') {
            $conditions[] = "`is_read` = :is_read";
            $params[':is_read'] = (int)$filters['is_read'];
        }

        if (!empty($filters['role_target']) && $filters['role_target'] !== 'all') {
            $conditions[] = "`role_target` = :role_target";
            $params[':role_target'] = $filters['role_target'];
        }

        if (!empty($filters['type']) && $filters['type'] !== 'all') {
            $conditions[] = "`type` = :type";
            $params[':type'] = $filters['type'];
        }

        return [implode(' AND ', $conditions), $params];
    }
}
