<?php

namespace App\Models;

use App\Core\Database;

/**
 * Push-based notifications stored in the `notifications` table.
 *
 * These are distinct from the header notification chips, which are
 * computed live from KPI status counts. These are discrete events
 * ("Sara reviewed your KPI and gave it 8/10") that survive across
 * page loads and show up in the recipient's Recent Activity / header.
 */
class Notification
{
    /**
     * Push a notification to a specific user.
     *
     * @param string $userType  'manager' | 'superadmin' | 'employee'
     * @param int    $userId
     * @param string $title     Short headline (shown in chips / activity)
     * @param string $message   Full detail text
     * @param string $link      Where to navigate on click
     */
    public static function push(string $userType, int $userId, string $title, string $message = '', string $link = ''): void
    {
        try {
            Database::connection()->prepare(
                "INSERT INTO notifications (user_type, user_id, title, message, link)
                 VALUES (:t, :id, :title, :msg, :link)"
            )->execute([
                't'     => $userType,
                'id'    => $userId,
                'title' => mb_substr($title, 0, 200),
                'msg'   => mb_substr($message, 0, 500),
                'link'  => $link,
            ]);
        } catch (\Throwable $e) {
            // Never let a notification failure break the main action.
        }
    }

    /**
     * Fetch unread notifications for a user (newest first).
     */
    public static function forUser(string $userType, int $userId, int $limit = 10): array
    {
        try {
            $stmt = Database::connection()->prepare(
                "SELECT * FROM notifications
                 WHERE user_type = :t AND user_id = :id
                 ORDER BY created_at DESC LIMIT :lim"
            );
            $stmt->bindValue('t',   $userType);
            $stmt->bindValue('id',  $userId, \PDO::PARAM_INT);
            $stmt->bindValue('lim', $limit,  \PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } catch (\Throwable $e) {
            return [];
        }
    }

    /**
     * Count unread notifications for a user.
     */
    public static function unreadCount(string $userType, int $userId): int
    {
        try {
            $stmt = Database::connection()->prepare(
                "SELECT COUNT(*) FROM notifications WHERE user_type = :t AND user_id = :id AND is_read = 0"
            );
            $stmt->execute(['t' => $userType, 'id' => $userId]);
            return (int)$stmt->fetchColumn();
        } catch (\Throwable $e) {
            return 0;
        }
    }

    /**
     * Mark all of a user's notifications as read.
     */
    public static function markAllRead(string $userType, int $userId): void
    {
        try {
            Database::connection()->prepare(
                "UPDATE notifications SET is_read = 1 WHERE user_type = :t AND user_id = :id"
            )->execute(['t' => $userType, 'id' => $userId]);
        } catch (\Throwable $e) {}
    }
}
