<?php
/**
 * Assignment Reminder Service
 * 
 * This service sends email reminders for upcoming and overdue assignments
 * It should be scheduled to run daily via cron job
 */

require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../../services/email/EmailService.php';

use Services\Email\EmailService;

class AssignmentReminderService {
    private $db;
    private $emailService;
    
    public function __construct() {
        global $db;
        $this->db = $db;
        $this->emailService = new EmailService();
    }
    
    /**
     * Send reminders for all assignments that need attention
     */
    public function sendReminders() {
        $this->sendUpcomingDueReminders();
        $this->sendOverdueReminders();
        $this->sendInactiveAssignmentReminders();
    }
    
    /**
     * Send reminders for assignments due in the next 48 hours
     */
    private function sendUpcomingDueReminders() {
        $conn = $this->db->getConnection();
        
        $query = "SELECT 
                    aa.id, aa.title, aa.description, aa.due_date, aa.priority,
                    m.first_name as member_first_name, m.last_name as member_last_name,
                    a.username as assigned_to_name, a.email as assigned_to_email
                FROM 
                    admin_assignments aa
                JOIN 
                    members m ON aa.member_id = m.id
                JOIN 
                    admin_users a ON aa.assigned_to = a.id
                WHERE 
                    aa.status = 'pending' 
                    AND aa.due_date BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 48 HOUR)
                    AND aa.reminder_sent = 0";
        
        $stmt = $conn->prepare($query);
        $stmt->execute();
        
        $assignments = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($assignments as $assignment) {
            try {
                $memberName = $assignment['member_first_name'] . ' ' . $assignment['member_last_name'];
                
                // Send upcoming due reminder
                $this->emailService->sendAssignmentReminderNotification(
                    $assignment['assigned_to_email'],
                    $assignment['assigned_to_name'],
                    $memberName,
                    $assignment['id'],
                    $assignment['title'],
                    $assignment['due_date'],
                    'upcoming'
                );
                
                // Mark reminder as sent
                $updateQuery = "UPDATE admin_assignments SET reminder_sent = 1 WHERE id = :id";
                $updateStmt = $conn->prepare($updateQuery);
                $updateStmt->bindValue(':id', $assignment['id']);
                $updateStmt->execute();
                
                echo "Sent upcoming reminder for assignment {$assignment['id']}\n";
            } catch (Exception $e) {
                error_log("Error sending upcoming reminder: " . $e->getMessage());
                echo "Error sending upcoming reminder for assignment {$assignment['id']}: {$e->getMessage()}\n";
            }
        }
    }
    
    /**
     * Send reminders for overdue assignments
     */
    private function sendOverdueReminders() {
        $conn = $this->db->getConnection();
        
        $query = "SELECT 
                    aa.id, aa.title, aa.description, aa.due_date, aa.priority,
                    m.first_name as member_first_name, m.last_name as member_last_name,
                    a.username as assigned_to_name, a.email as assigned_to_email,
                    DATEDIFF(NOW(), aa.due_date) as days_overdue
                FROM 
                    admin_assignments aa
                JOIN 
                    members m ON aa.member_id = m.id
                JOIN 
                    admin_users a ON aa.assigned_to = a.id
                WHERE 
                    aa.status = 'pending' 
                    AND aa.due_date < NOW()
                    AND (aa.last_overdue_reminder IS NULL 
                         OR DATEDIFF(NOW(), aa.last_overdue_reminder) >= 3)";
        
        $stmt = $conn->prepare($query);
        $stmt->execute();
        
        $assignments = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($assignments as $assignment) {
            try {
                $memberName = $assignment['member_first_name'] . ' ' . $assignment['member_last_name'];
                
                // Send overdue reminder
                $this->emailService->sendAssignmentReminderNotification(
                    $assignment['assigned_to_email'],
                    $assignment['assigned_to_name'],
                    $memberName,
                    $assignment['id'],
                    $assignment['title'],
                    $assignment['due_date'],
                    'overdue',
                    $assignment['days_overdue']
                );
                
                // Update last reminder timestamp
                $updateQuery = "UPDATE admin_assignments 
                               SET last_overdue_reminder = NOW(),
                                   overdue_reminder_count = IFNULL(overdue_reminder_count, 0) + 1
                               WHERE id = :id";
                $updateStmt = $conn->prepare($updateQuery);
                $updateStmt->bindValue(':id', $assignment['id']);
                $updateStmt->execute();
                
                echo "Sent overdue reminder for assignment {$assignment['id']} ({$assignment['days_overdue']} days overdue)\n";
            } catch (Exception $e) {
                error_log("Error sending overdue reminder: " . $e->getMessage());
                echo "Error sending overdue reminder for assignment {$assignment['id']}: {$e->getMessage()}\n";
            }
        }
    }
    
    /**
     * Send reminders for assignments that have been inactive for more than 7 days
     */
    private function sendInactiveAssignmentReminders() {
        $conn = $this->db->getConnection();
        
        $query = "SELECT 
                    aa.id, aa.title, aa.description, aa.due_date, aa.priority, aa.created_at,
                    m.first_name as member_first_name, m.last_name as member_last_name,
                    a.username as assigned_to_name, a.email as assigned_to_email,
                    supervisor.username as supervisor_name, supervisor.email as supervisor_email
                FROM 
                    admin_assignments aa
                JOIN 
                    members m ON aa.member_id = m.id
                JOIN 
                    admin_users a ON aa.assigned_to = a.id
                LEFT JOIN
                    admin_users supervisor ON a.supervisor_id = supervisor.id
                WHERE 
                    aa.status = 'pending' 
                    AND DATEDIFF(NOW(), aa.updated_at) > 7
                    AND (aa.inactive_reminder_sent = 0 OR DATEDIFF(NOW(), aa.inactive_reminder_sent_at) >= 7)";
        
        $stmt = $conn->prepare($query);
        $stmt->execute();
        
        $assignments = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($assignments as $assignment) {
            try {
                $memberName = $assignment['member_first_name'] . ' ' . $assignment['member_last_name'];
                
                // Send inactive reminder to the assigned admin
                $this->emailService->sendAssignmentReminderNotification(
                    $assignment['assigned_to_email'],
                    $assignment['assigned_to_name'],
                    $memberName,
                    $assignment['id'],
                    $assignment['title'],
                    $assignment['due_date'],
                    'inactive'
                );
                
                // If there's a supervisor, notify them as well for assignments inactive for 14+ days
                if (isset($assignment['supervisor_email']) && 
                    DATEDIFF(NOW(), $assignment['updated_at']) > 14) {
                    
                    $this->emailService->sendSupervisorEscalationNotification(
                        $assignment['supervisor_email'],
                        $assignment['supervisor_name'],
                        $assignment['assigned_to_name'],
                        $memberName,
                        $assignment['id'],
                        $assignment['title'],
                        $assignment['due_date']
                    );
                }
                
                // Update inactive reminder status
                $updateQuery = "UPDATE admin_assignments 
                               SET inactive_reminder_sent = 1,
                                   inactive_reminder_sent_at = NOW()
                               WHERE id = :id";
                $updateStmt = $conn->prepare($updateQuery);
                $updateStmt->bindValue(':id', $assignment['id']);
                $updateStmt->execute();
                
                echo "Sent inactive reminder for assignment {$assignment['id']}\n";
            } catch (Exception $e) {
                error_log("Error sending inactive reminder: " . $e->getMessage());
                echo "Error sending inactive reminder for assignment {$assignment['id']}: {$e->getMessage()}\n";
            }
        }
    }
}

// If called directly, run the reminders
if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
    echo "Starting assignment reminders at " . date('Y-m-d H:i:s') . "\n";
    $reminderService = new AssignmentReminderService();
    $reminderService->sendReminders();
    echo "Completed assignment reminders at " . date('Y-m-d H:i:s') . "\n";
}
