<?php
/**
 * Notifications Library
 * GHAMECC Job Portal
 * 
 * This file contains functions for creating, retrieving, and managing notifications
 * for the job portal system.
 */

// Include database connection if not already included
if (!function_exists('fetchRows')) {
    require_once __DIR__ . '/../config/database.php';
    require_once __DIR__ . '/functions.php';
}

/**
 * Create a new notification
 * 
 * @param int $userId ID of the user to notify
 * @param string $type Type of notification (see notifications_schema.sql for types)
 * @param string $message Notification message
 * @param string $link Optional link to redirect to when notification is clicked
 * @param int $relatedId Optional ID related to this notification (job_id, profile_id, etc.)
 * @return int|bool ID of the created notification or false on failure
 */
function createNotification($userId, $type, $message, $link = null, $relatedId = null) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("INSERT INTO notifications (user_id, type, message, link, related_id) VALUES (?, ?, ?, ?, ?)");
        $stmt->bind_param("isssi", $userId, $type, $message, $link, $relatedId);
        
        if ($stmt->execute()) {
            return $conn->insert_id;
        }
    } catch (Exception $e) {
        error_log("Error creating notification: " . $e->getMessage());
    }
    
    return false;
}

/**
 * Get notifications for a user
 * 
 * @param int $userId ID of the user
 * @param bool $onlyUnread Whether to get only unread notifications
 * @param int $limit Maximum number of notifications to return
 * @param int $offset Offset for pagination
 * @return array Array of notifications
 */
function getUserNotifications($userId, $onlyUnread = false, $limit = 10, $offset = 0) {
    $query = "SELECT * FROM notifications WHERE user_id = ?";
    
    if ($onlyUnread) {
        $query .= " AND is_read = 0";
    }
    
    $query .= " ORDER BY created_at DESC LIMIT ? OFFSET ?";
    
    return fetchRows($query, [$userId, $limit, $offset]);
}

/**
 * Count unread notifications for a user
 * 
 * @param int $userId ID of the user
 * @return int Number of unread notifications
 */
function countUnreadNotifications($userId) {
    $query = "SELECT COUNT(*) as count FROM notifications WHERE user_id = ? AND is_read = 0";
    $result = fetchRow($query, [$userId]);
    
    return $result ? $result['count'] : 0;
}

/**
 * Mark a notification as read
 * 
 * @param int $notificationId ID of the notification
 * @param int $userId ID of the user (for security check)
 * @return bool True on success, false on failure
 */
function markNotificationAsRead($notificationId, $userId) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("UPDATE notifications SET is_read = 1 WHERE id = ? AND user_id = ?");
        $stmt->bind_param("ii", $notificationId, $userId);
        
        return $stmt->execute();
    } catch (Exception $e) {
        error_log("Error marking notification as read: " . $e->getMessage());
    }
    
    return false;
}

/**
 * Mark all notifications as read for a user
 * 
 * @param int $userId ID of the user
 * @return bool True on success, false on failure
 */
function markAllNotificationsAsRead($userId) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("UPDATE notifications SET is_read = 1 WHERE user_id = ?");
        $stmt->bind_param("i", $userId);
        
        return $stmt->execute();
    } catch (Exception $e) {
        error_log("Error marking all notifications as read: " . $e->getMessage());
    }
    
    return false;
}

/**
 * Delete a notification
 * 
 * @param int $notificationId ID of the notification
 * @param int $userId ID of the user (for security check)
 * @return bool True on success, false on failure
 */
function deleteNotification($notificationId, $userId) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("DELETE FROM notifications WHERE id = ? AND user_id = ?");
        $stmt->bind_param("ii", $notificationId, $userId);
        
        return $stmt->execute();
    } catch (Exception $e) {
        error_log("Error deleting notification: " . $e->getMessage());
    }
    
    return false;
}

/**
 * Delete all notifications for a user
 * 
 * @param int $userId ID of the user
 * @return bool True on success, false on failure
 */
function deleteAllNotifications($userId) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("DELETE FROM notifications WHERE user_id = ?");
        $stmt->bind_param("i", $userId);
        
        return $stmt->execute();
    } catch (Exception $e) {
        error_log("Error deleting all notifications: " . $e->getMessage());
    }
    
    return false;
}

/**
 * Create a notification for a new rating
 * 
 * @param int $ratedUserId ID of the user who received the rating
 * @param int $raterUserId ID of the user who gave the rating
 * @param float $rating Rating value
 * @return int|bool ID of the created notification or false on failure
 */
function createRatingNotification($ratedUserId, $raterUserId, $rating) {
    // Get rater's name
    $rater = fetchRow("SELECT first_name, last_name FROM members WHERE id = ?", [$raterUserId]);
    
    if (!$rater) {
        return false;
    }
    
    $raterName = $rater['first_name'] . ' ' . $rater['last_name'];
    $message = "$raterName has rated your profile with $rating stars";
    $link = "/jobs/profile-details.php?id=$ratedUserId";
    
    return createNotification($ratedUserId, 'new_rating', $message, $link, $ratedUserId);
}

/**
 * Create a notification for a new review
 * 
 * @param int $reviewedUserId ID of the user who received the review
 * @param int $reviewerUserId ID of the user who gave the review
 * @return int|bool ID of the created notification or false on failure
 */
function createReviewNotification($reviewedUserId, $reviewerUserId) {
    // Get reviewer's name
    $reviewer = fetchRow("SELECT first_name, last_name FROM members WHERE id = ?", [$reviewerUserId]);
    
    if (!$reviewer) {
        return false;
    }
    
    $reviewerName = $reviewer['first_name'] . ' ' . $reviewer['last_name'];
    $message = "$reviewerName has left a review on your profile";
    $link = "/jobs/profile-details.php?id=$reviewedUserId";
    
    return createNotification($reviewedUserId, 'new_review', $message, $link, $reviewedUserId);
}

/**
 * Create a notification for a new job application
 * 
 * @param int $jobOwnerId ID of the job posting owner
 * @param int $applicantId ID of the applicant
 * @param int $jobId ID of the job
 * @return int|bool ID of the created notification or false on failure
 */
function createJobApplicationNotification($jobOwnerId, $applicantId, $jobId) {
    // Get applicant's name
    $applicant = fetchRow("SELECT first_name, last_name FROM members WHERE id = ?", [$applicantId]);
    
    // Get job title
    $job = fetchRow("SELECT title FROM job_postings WHERE id = ?", [$jobId]);
    
    if (!$applicant || !$job) {
        return false;
    }
    
    $applicantName = $applicant['first_name'] . ' ' . $applicant['last_name'];
    $jobTitle = $job['title'];
    
    $message = "$applicantName has applied for your job: $jobTitle";
    $link = "/jobs/applications.php?job_id=$jobId";
    
    return createNotification($jobOwnerId, 'job_application', $message, $link, $jobId);
}

/**
 * Create a notification for an application status change
 * 
 * @param int $applicantId ID of the applicant
 * @param int $jobId ID of the job
 * @param string $status New status of the application
 * @return int|bool ID of the created notification or false on failure
 */
function createApplicationStatusNotification($applicantId, $jobId, $status) {
    // Get job details
    $job = fetchRow("SELECT title, posted_by FROM job_postings WHERE id = ?", [$jobId]);
    
    if (!$job) {
        return false;
    }
    
    $jobTitle = $job['title'];
    
    // Format status for display
    $statusDisplay = ucfirst(str_replace('_', ' ', $status));
    
    $message = "Your application for \"$jobTitle\" has been $statusDisplay";
    $link = "/jobs/my-applications.php";
    
    return createNotification($applicantId, 'application_status', $message, $link, $jobId);
}

/**
 * Create notifications for users with matching skills when a new job is posted
 * 
 * @param int $jobId ID of the new job
 * @param array $requiredSkills Array of skills required for the job
 * @return int Number of notifications created
 */
function createNewJobMatchNotifications($jobId, $requiredSkills) {
    // Get job details
    $job = fetchRow("SELECT title FROM job_postings WHERE id = ?", [$jobId]);
    
    if (!$job) {
        return 0;
    }
    
    $jobTitle = $job['title'];
    $notificationCount = 0;
    
    // Find users with matching skills
    $users = [];
    foreach ($requiredSkills as $skill) {
        $skillTerm = "%$skill%";
        $matchingUsers = fetchRows("SELECT DISTINCT mp.member_id 
                                   FROM member_profiles mp 
                                   WHERE mp.skills LIKE ?", [$skillTerm]);
        
        foreach ($matchingUsers as $user) {
            $userId = $user['member_id'];
            if (!isset($users[$userId])) {
                $users[$userId] = true;
                
                $message = "New job posting matches your skills: \"$jobTitle\"";
                $link = "/jobs/job-details.php?id=$jobId";
                
                if (createNotification($userId, 'new_job', $message, $link, $jobId)) {
                    $notificationCount++;
                }
            }
        }
    }
    
    return $notificationCount;
}

/**
 * Display notification badge with unread count
 * 
 * @param int $userId ID of the user
 * @return string HTML for the notification badge
 */
function displayNotificationBadge($userId) {
    $count = countUnreadNotifications($userId);
    
    if ($count > 0) {
        return '<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">' . 
               $count . '<span class="visually-hidden">unread notifications</span></span>';
    }
    
    return '';
}

/**
 * Display notification dropdown with recent notifications
 * 
 * @param int $userId ID of the user
 * @param int $limit Maximum number of notifications to show
 * @return string HTML for the notification dropdown
 */
function displayNotificationsDropdown($userId, $limit = 5) {
    $notifications = getUserNotifications($userId, false, $limit);
    $unreadCount = countUnreadNotifications($userId);
    
    $html = '<div class="dropdown">';
    $html .= '<a class="nav-link dropdown-toggle position-relative" href="#" id="notificationsDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">';
    $html .= '<i class="fas fa-bell"></i>';
    
    if ($unreadCount > 0) {
        $html .= '<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">' . 
                $unreadCount . '<span class="visually-hidden">unread notifications</span></span>';
    }
    
    $html .= '</a>';
    $html .= '<ul class="dropdown-menu dropdown-menu-end notification-dropdown" aria-labelledby="notificationsDropdown" style="width: 320px; max-height: 400px; overflow-y: auto;">';
    
    if (empty($notifications)) {
        $html .= '<li><div class="dropdown-item text-center text-muted">No notifications</div></li>';
    } else {
        $html .= '<li><h6 class="dropdown-header">Notifications</h6></li>';
        
        foreach ($notifications as $notification) {
            $isUnread = $notification['is_read'] == 0 ? 'unread' : '';
            $html .= '<li>';
            
            if (!empty($notification['link'])) {
                $html .= '<a class="dropdown-item notification-item ' . $isUnread . '" href="' . $notification['link'] . '" 
                          onclick="markNotificationAsRead(' . $notification['id'] . ')">';
            } else {
                $html .= '<div class="dropdown-item notification-item ' . $isUnread . '">';
            }
            
            // Icon based on notification type
            $html .= '<div class="notification-icon ';
            switch ($notification['type']) {
                case 'new_rating':
                    $html .= 'bg-warning"><i class="fas fa-star"></i>';
                    break;
                case 'new_review':
                    $html .= 'bg-info"><i class="fas fa-comment"></i>';
                    break;
                case 'job_application':
                    $html .= 'bg-primary"><i class="fas fa-file-alt"></i>';
                    break;
                case 'application_status':
                    $html .= 'bg-success"><i class="fas fa-check-circle"></i>';
                    break;
                case 'new_job':
                    $html .= 'bg-secondary"><i class="fas fa-briefcase"></i>';
                    break;
                default:
                    $html .= 'bg-secondary"><i class="fas fa-bell"></i>';
            }
            $html .= '</div>';
            
            $html .= '<div class="notification-content">';
            $html .= '<div class="notification-text">' . htmlspecialchars($notification['message']) . '</div>';
            $html .= '<div class="notification-time">' . timeAgo($notification['created_at']) . '</div>';
            $html .= '</div>';
            
            if (!empty($notification['link'])) {
                $html .= '</a>';
            } else {
                $html .= '</div>';
            }
            
            $html .= '</li>';
        }
        
        $html .= '<li><hr class="dropdown-divider"></li>';
        $html .= '<li><a class="dropdown-item text-center" href="/jobs/notifications.php">View All Notifications</a></li>';
        $html .= '<li><a class="dropdown-item text-center" href="#" onclick="markAllNotificationsAsRead(); return false;">Mark All as Read</a></li>';
    }
    
    $html .= '</ul>';
    $html .= '</div>';
    
    // Add JavaScript for marking notifications as read
    $html .= '<script>
        function markNotificationAsRead(id) {
            fetch("/jobs/ajax/mark_notification_read.php?id=" + id, {
                method: "POST",
                credentials: "same-origin"
            });
        }
        
        function markAllNotificationsAsRead() {
            fetch("/jobs/ajax/mark_all_notifications_read.php", {
                method: "POST",
                credentials: "same-origin"
            }).then(() => {
                document.querySelectorAll(".notification-item.unread").forEach(item => {
                    item.classList.remove("unread");
                });
                document.querySelector("#notificationsDropdown .badge")?.remove();
            });
        }
    </script>';
    
    return $html;
}

/**
 * Display notification dropdown items only (without the full dropdown wrapper)
 * 
 * @param int $userId ID of the user
 * @param int $limit Maximum number of notifications to show
 * @return string HTML for the notification dropdown items
 */
function displayNotificationDropdownItems($userId, $limit = 5) {
    $notifications = getUserNotifications($userId, false, $limit);
    
    $html = '';
    
    if (empty($notifications)) {
        $html .= '<div class="dropdown-item text-center text-muted">No notifications</div>';
    } else {
        foreach ($notifications as $notification) {
            $isUnread = $notification['is_read'] == 0 ? 'unread' : '';
            
            if (!empty($notification['link'])) {
                $html .= '<a href="' . htmlspecialchars($notification['link']) . '" class="dropdown-item notification-item ' . $isUnread . '">';
            } else {
                $html .= '<div class="dropdown-item notification-item ' . $isUnread . '">';
            }
            
            $html .= '<div class="d-flex">';
            $html .= '<div class="notification-icon me-3">';
            
            // Icon based on notification type
            switch ($notification['type']) {
                case 'job_application':
                    $html .= '<i class="fas fa-briefcase text-primary"></i>';
                    break;
                case 'job_approval':
                    $html .= '<i class="fas fa-check-circle text-success"></i>';
                    break;
                case 'profile_view':
                    $html .= '<i class="fas fa-eye text-info"></i>';
                    break;
                case 'message':
                    $html .= '<i class="fas fa-envelope text-warning"></i>';
                    break;
                default:
                    $html .= '<i class="fas fa-bell text-secondary"></i>';
            }
            $html .= '</div>';
            
            $html .= '<div class="notification-content flex-grow-1">';
            $html .= '<div class="notification-text">' . htmlspecialchars($notification['message']) . '</div>';
            $html .= '<div class="notification-time text-muted small">' . timeAgo($notification['created_at']) . '</div>';
            $html .= '</div>';
            $html .= '</div>';
            
            if (!empty($notification['link'])) {
                $html .= '</a>';
            } else {
                $html .= '</div>';
            }
        }
    }
    
    return $html;
}

/**
 * Helper function to get time ago string if not already defined
 * 
 * @param string $datetime MySQL datetime string
 * @return string Time ago string (e.g., "2 hours ago")
 */
if (!function_exists('timeAgo')) {
    function timeAgo($datetime) {
        $time = strtotime($datetime);
        $now = time();
        $diff = $now - $time;
        
        if ($diff < 60) {
            return "Just now";
        } elseif ($diff < 3600) {
            $mins = floor($diff / 60);
            return $mins . " min" . ($mins > 1 ? "s" : "") . " ago";
        } elseif ($diff < 86400) {
            $hours = floor($diff / 3600);
            return $hours . " hour" . ($hours > 1 ? "s" : "") . " ago";
        } elseif ($diff < 604800) {
            $days = floor($diff / 86400);
            return $days . " day" . ($days > 1 ? "s" : "") . " ago";
        } else {
            return date("M j, Y", $time);
        }
    }
}
?>
