<?php
date_default_timezone_set('Asia/Colombo');
// Prevent execution timeout limit (runs indefinitely if started as daemon)
set_time_limit(0);
ini_set('memory_limit', '512M');

// 1. Setup autoloader pointing to the root directory
spl_autoload_register(function ($class) {
    $prefix = 'App\\';
    $base_dir = dirname(__DIR__) . '/';
    
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    
    $relative_class = substr($class, $len);
    $file = $base_dir . 'src/' . str_replace('\\', '/', $relative_class) . '.php';
    
    if (file_exists($file)) {
        require $file;
    } else {
        $parts = explode('\\', $relative_class);
        if ($parts[0] === 'Config' && isset($parts[1])) {
            $config_file_camel = $base_dir . 'config/' . $parts[1] . '.php';
            $config_file_lower = $base_dir . 'config/' . strtolower($parts[1]) . '.php';
            
            if (file_exists($config_file_camel)) {
                require $config_file_camel;
            } elseif (file_exists($config_file_lower)) {
                require $config_file_lower;
            }
        }
    }
});

use App\Config\Database;
use App\Utils\ExpiryAlertHelper;
use App\Utils\ExpiryPDFGenerator;
use App\Utils\SimpleMailer;

function runScheduler() {
    try {
        $db = Database::getInstance()->getConnection();
        
        // Update heartbeat timestamp to show daemon is active
        $now = date('Y-m-d H:i:s');
        $stmtHb = $db->prepare("
            INSERT INTO settings (setting_key, setting_value) 
            VALUES ('scheduler_last_heartbeat', ?) 
            ON DUPLICATE KEY UPDATE setting_value = ?
        ");
        $stmtHb->execute([$now, $now]);
        
        // Check if scheduler is active (Started) or stopped
        $stmtActive = $db->query("SELECT setting_value FROM settings WHERE setting_key = 'scheduler_active' LIMIT 1");
        $activeVal = $stmtActive->fetchColumn();
        
        if ($activeVal === false) {
            // Initialize setting if not present
            $stmtInit = $db->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('scheduler_active', '0')");
            $stmtInit->execute();
            $activeVal = '0';
        }
        
        if ($activeVal === '0') {
            echo "[~] Scheduler is currently stopped/disabled in settings.\n";
            return;
        }
        
        // 2. Fetch the scheduled run time
        $stmt = $db->query("SELECT setting_value FROM settings WHERE setting_key = 'notify_agent_run_time' LIMIT 1");
        $setting = $stmt->fetch();
        
        if (!$setting) {
            echo "[-] Expiry scheduler runtime setting is not configured in settings table.\n";
            return;
        }
        
        $currentTime = date('H:i');
        $scheduledTime = date('H:i', strtotime($setting['setting_value']));
        
        echo "[*] Checking scheduler: Current Time = {$currentTime}, Scheduled Time = {$scheduledTime}\n";
        
        // 3. Only run matching the scheduled hour and minute
        if ($currentTime === $scheduledTime) {
            echo "[+] Trigger matched! Executing expiry alerts...\n";
            
            // Fetch all active tenants
            $tenants = $db->query("SELECT * FROM tenants")->fetchAll();
            $today = date('Y-m-d');
            
            foreach ($tenants as $tenant) {
                $tenantId = $tenant['id'];
                $tenantName = $tenant['name'];
                
                $alertEmails = trim($tenant['alert_emails'] ?? '');
                $waAlertsJson = $tenant['whatsapp_alerts'] ?? '[]';
                $waAlerts = json_decode($waAlertsJson, true) ?: [];
                
                $featureEmail = $tenant['feature_email_alerts'] ?? 1;
                $featureWa = $tenant['feature_whatsapp_alerts'] ?? 1;
                
                // Check if email already executed today
                $stmtCheckEmail = $db->prepare("SELECT COUNT(*) FROM notifyalertlog WHERE tenant_id = ? AND alert_type IN ('scheduler', 'notify_agent') AND channel = 'Email' AND DATE(created_at) = ?");
                $stmtCheckEmail->execute([$tenantId, $today]);
                $emailAlreadyRan = $stmtCheckEmail->fetchColumn() > 0;
                
                // Check if WA already executed today
                $stmtCheckWa = $db->prepare("SELECT COUNT(*) FROM notifyalertlog WHERE tenant_id = ? AND alert_type = 'scheduler' AND channel = 'WhatsApp' AND DATE(created_at) = ?");
                $stmtCheckWa->execute([$tenantId, $today]);
                $waAlreadyRan = $stmtCheckWa->fetchColumn() > 0;

                $shouldRunEmail = !$emailAlreadyRan && $featureEmail && !empty($alertEmails);
                $shouldRunWa = !$waAlreadyRan && $featureWa && !empty($waAlerts);

                if (!$shouldRunEmail && !$shouldRunWa) {
                    echo "[~] Tenant '{$tenantName}' (ID {$tenantId}) already processed or features disabled/empty. Skipping.\n";
                    continue;
                }
                
                echo "[>] Processing tenant: '{$tenantName}' (ID {$tenantId})...\n";
                
                // Fetch expiring items
                $items = ExpiryAlertHelper::getExpiringSoonItems($tenantId);
                $count = count($items);
                
                if ($count === 0) {
                    // Log 0 items for both if they were supposed to run
                    if ($shouldRunEmail) {
                        $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'Email', 'failure', 'No expiring soon items found', ?, 0)")->execute([$tenantId, $alertEmails]);
                    }
                    if ($shouldRunWa) {
                        $waRecipientsStr = implode(',', array_column($waAlerts, 'phone'));
                        $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'WhatsApp', 'failure', 'No expiring soon items found', ?, 0)")->execute([$tenantId, $waRecipientsStr]);
                    }
                    echo "[-] No expiring items found for tenant '{$tenantName}'.\n";
                    continue;
                }
                
                // ------------------ EMAIL LOGIC ------------------
                if ($shouldRunEmail) {
                    try {
                        $pdfGenerator = new ExpiryPDFGenerator($tenantName);
                        $pdfContent = $pdfGenerator->generate($items);
                        $subject = "Expiry Alerts Notification - " . $tenantName;
                        $year = date('Y');
                        
                        $htmlBody = <<<HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Expiry Alert Notification</title>
    <style>
        body { background-color: #0f172a !important; color: #f1f5f9 !important; font-family: 'Inter', system-ui, -apple-system, sans-serif; margin: 0; padding: 20px; }
        .container { max-width: 600px; margin: 0 auto; background: #1e293b !important; border: 1px solid #334155; border-radius: 12px; padding: 30px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
        .header { border-bottom: 2px solid #4f46e5; padding-bottom: 15px; margin-bottom: 20px; text-align: center; }
        .header h1 { color: #818cf8 !important; margin: 0; font-size: 24px; }
        .content { line-height: 1.6; font-size: 16px; color: #cbd5e1 !important; }
        .alert-box { background-color: rgba(239, 68, 68, 0.1) !important; border-left: 4px solid #ef4444; padding: 15px; border-radius: 6px; margin: 20px 0; }
        .footer { margin-top: 30px; font-size: 12px; color: #94a3b8 !important; text-align: center; border-top: 1px solid #334155; padding-top: 15px; }
        p { color: #cbd5e1 !important; }
    </style>
</head>
<body style="background-color: #0f172a; color: #f1f5f9; font-family: 'Inter', sans-serif; margin: 0; padding: 20px;">
    <div class="container" style="background-color: #1e293b; border: 1px solid #334155; border-radius: 12px; padding: 30px; max-width: 600px; margin: 0 auto;">
        <div class="header" style="border-bottom: 2px solid #4f46e5; padding-bottom: 15px; margin-bottom: 20px; text-align: center;">
            <h1 style="color: #818cf8; margin: 0; font-size: 24px; font-family: 'Inter', sans-serif;">Expiry Alert Notification</h1>
        </div>
        <div class="content" style="font-family: 'Inter', sans-serif; font-size: 16px; line-height: 1.6; color: #cbd5e1;">
            <p style="color: #cbd5e1; margin-bottom: 16px;">Dear Administrator,</p>
            <p style="color: #cbd5e1; margin-bottom: 16px;">This is a system generated notification regarding expiring soon medicine inventory items.</p>
            <div class="alert-box" style="background-color: rgba(239, 68, 68, 0.1); border-left: 4px solid #ef4444; padding: 15px; border-radius: 6px; margin: 20px 0;">
                <p style="margin: 0; color: #fca5a5; font-weight: bold;">We found <strong>{$count}</strong> batch(es) that are expiring soon based on current alert settings.</p>
            </div>
            <p style="color: #cbd5e1; margin-bottom: 16px;">A detailed PDF report has been generated and attached to this email containing the list of medicine details, batch numbers, branches, quantities, and days remaining.</p>
            <p style="color: #cbd5e1; margin-bottom: 16px;">Please take necessary actions to manage or withdraw these items.</p>
        </div>
        <div class="footer" style="margin-top: 30px; font-size: 12px; color: #94a3b8; text-align: center; border-top: 1px solid #334155; padding-top: 15px; font-family: 'Inter', sans-serif;">
            <p style="margin: 0 0 5px; color: #94a3b8;">&copy; {$year} {$tenantName}. All rights reserved.</p>
            <p style="margin: 0; color: #94a3b8;">NexCore-Pharma System Alert</p>
        </div>
    </div>
</body>
</html>
HTML;
                        
                        $localTime = new \DateTime('now', new \DateTimeZone('Asia/Colombo'));
                        $pdfFilename = "expiry_report_" . $localTime->format('Ymd_His') . ".pdf";
                        
                        SimpleMailer::send($alertEmails, $subject, $htmlBody, $pdfContent, $pdfFilename);
                        
                        $stmtLog = $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'Email', 'success', NULL, ?, ?)");
                        $stmtLog->execute([$tenantId, $alertEmails, $count]);
                        echo "[+] Successfully sent Email alerts for '{$tenantName}'.\n";
                    } catch (\Exception $e) {
                        $stmtLog = $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'Email', 'failure', ?, ?, ?)");
                        $stmtLog->execute([$tenantId, $e->getMessage(), $alertEmails, $count]);
                        echo "[!] Email Exception for tenant '{$tenantName}': " . $e->getMessage() . "\n";
                    }
                }
                
                // ------------------ WHATSAPP LOGIC ------------------
                if ($shouldRunWa) {
                    $waRecipientsStr = implode(',', array_column($waAlerts, 'phone'));
                    try {
                        $maxDays = max(array_column($items, 'days_left'));
                        $months = floor($maxDays / 30);
                        $days = $maxDays % 30;
                        $friendlyDuration = "";
                        if ($months > 0) $friendlyDuration .= $months . " month" . ($months > 1 ? "s" : "");
                        if ($days > 0) {
                            if ($months > 0) $friendlyDuration .= ", ";
                            $friendlyDuration .= $days . " day" . ($days > 1 ? "s" : "");
                        }
                        if (empty($friendlyDuration)) $friendlyDuration = "0 days";
                        
                        $stmtAppUrl = $db->query("SELECT setting_value FROM settings WHERE setting_key = 'application_url'");
                        $appUrlSetting = $stmtAppUrl->fetchColumn();
                        $appUrl = $appUrlSetting ? $appUrlSetting : "http://localhost:8000"; // Fallback URL
                        
                        $successWaCount = 0;
                        $failWaCount = 0;
                        $waErrors = [];
                        
                        foreach ($waAlerts as $contact) {
                            if (empty($contact['phone'])) continue;
                            $phone = $contact['phone'];
                            $contactName = $contact['name'] ?: 'Admin';
                            
                            $message = "🚨 *Medicine Expiry Notification*\n\n"
                                     . "Dear {$contactName},\n\n"
                                     . "You currently have {$count} medicines that will expire within the next {$friendlyDuration}.\n\n"
                                     . "Click below to view the details:\n"
                                     . "{$appUrl}\n\n"
                                     . "Thank you,\n"
                                     . "NexCore Pharma.";
                            try {
                                \App\Utils\WhatsAppAlertHelper::send($phone, $message);
                                $successWaCount++;
                            } catch (\Exception $e) {
                                $failWaCount++;
                                $waErrors[] = "Failed for $phone: " . $e->getMessage();
                            }
                        }
                        
                        if ($successWaCount > 0) {
                            $stmtLog = $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'WhatsApp', 'success', NULL, ?, ?)");
                            $stmtLog->execute([$tenantId, $waRecipientsStr, $count]);
                            echo "[+] Successfully sent WhatsApp alerts for '{$tenantName}'.\n";
                        } else {
                            $failureReason = implode(", ", $waErrors);
                            $stmtLog = $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'WhatsApp', 'failure', ?, ?, ?)");
                            $stmtLog->execute([$tenantId, $failureReason, $waRecipientsStr, $count]);
                            echo "[-] Failed WhatsApp alerts for '{$tenantName}': {$failureReason}\n";
                        }
                    } catch (\Exception $e) {
                        $stmtLog = $db->prepare("INSERT INTO notifyalertlog (tenant_id, alert_type, channel, status, failure_reason, recipients, items_count) VALUES (?, 'scheduler', 'WhatsApp', 'failure', ?, ?, ?)");
                        $stmtLog->execute([$tenantId, $e->getMessage(), $waRecipientsStr, $count]);
                        echo "[!] WhatsApp Exception for tenant '{$tenantName}': " . $e->getMessage() . "\n";
                    }
                }
            }
        }
    } catch (\Exception $ex) {
        echo "[-] Error running scheduler: " . $ex->getMessage() . "\n";
    }
}

// 5. Select execution mode based on command arguments
$isDaemon = isset($argv) && in_array('--daemon', $argv);

if ($isDaemon) {
    echo "[*] Expiry scheduler running in continuous Daemon mode (checking every 60s)...\n";
    while (true) {
        runScheduler();
        gc_collect_cycles();
        sleep(60);
    }
} else {
    echo "[*] Expiry scheduler running in single Cron execution mode...\n";
    runScheduler();
}
