<?php
declare(strict_types=1);

class AlertChecker {
    private PDO $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }

    public function runDailyChecks(): void {
        $lastRun = $this->getSetting('last_alert_check_time', '2000-01-01');
        $today = date('Y-m-d');
        if (substr($lastRun, 0, 10) === $today) {
            return; // Already ran today
        }

        $this->checkVehicles();
        $this->checkProjects();
        $this->checkTasks();

        $this->setSetting('last_alert_check_time', date('Y-m-d H:i:s'));
    }

    private function getSetting(string $key, string $default): string {
        $stmt = $this->db->prepare("SELECT setting_value FROM settings WHERE setting_key = ? LIMIT 1");
        $stmt->execute([$key]);
        $val = $stmt->fetchColumn();
        return $val !== false ? (string)$val : $default;
    }

    private function setSetting(string $key, string $value): void {
        $stmt = $this->db->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)");
        $stmt->execute([$key, $value]);
    }

    private function notifyAdmins(string $message, string $linkUrl): void {
        // Query to find all admin users
        $stmt = $this->db->query("SELECT id FROM users WHERE role = 'admin' AND is_active = 1");
        $admins = $stmt->fetchAll(PDO::FETCH_COLUMN);

        foreach ($admins as $adminId) {
            // Check if exact same message sent in last 15 days
            $check = $this->db->prepare("SELECT id FROM user_notifications WHERE user_id = ? AND message = ? AND created_at > DATE_SUB(NOW(), INTERVAL 15 DAY) LIMIT 1");
            $check->execute([$adminId, $message]);
            if ($check->fetch()) {
                continue; // Already notified recently
            }

            // Insert new notification
            $ins = $this->db->prepare("INSERT INTO user_notifications (user_id, message, link_url, is_read) VALUES (?, ?, ?, 0)");
            $ins->execute([$adminId, $message, $linkUrl]);
        }
    }

    private function checkVehicles(): void {
        // Vehicles expiry check (next 30 days)
        $threshold = date('Y-m-d', strtotime('+30 days'));
        
        $stmt = $this->db->query("SELECT id, license_plate, insurance_expiry, kteo_expiry, road_tax_expiry, next_service_date FROM vehicles WHERE active = 1");
        while ($row = $stmt->fetch()) {
            $link = "/gopools/public/vehicles/edit.php?id=" . (int)$row['id'];
            $plate = $row['license_plate'];

            if ($row['kteo_expiry'] && $row['kteo_expiry'] !== '0000-00-00' && $row['kteo_expiry'] <= $threshold) {
                $this->notifyAdmins("KTEO for vehicle {$plate} is expiring on {$row['kteo_expiry']}!", $link);
            }
            if ($row['insurance_expiry'] && $row['insurance_expiry'] !== '0000-00-00' && $row['insurance_expiry'] <= $threshold) {
                $this->notifyAdmins("Insurance for vehicle {$plate} is expiring on {$row['insurance_expiry']}!", $link);
            }
            if ($row['road_tax_expiry'] && $row['road_tax_expiry'] !== '0000-00-00' && $row['road_tax_expiry'] <= $threshold) {
                $this->notifyAdmins("Road tax for vehicle {$plate} is expiring on {$row['road_tax_expiry']}!", $link);
            }
            if ($row['next_service_date'] && $row['next_service_date'] !== '0000-00-00' && $row['next_service_date'] <= $threshold) {
                $this->notifyAdmins("Upcoming Service for vehicle {$plate} scheduled on {$row['next_service_date']}!", $link);
            }
        }
    }

    private function checkProjects(): void {
        // Projects ending in 7 days or overdue
        $threshold = date('Y-m-d', strtotime('+7 days'));
        $today = date('Y-m-d');
        
        $stmt = $this->db->query("SELECT id, title, end_date_planned FROM projects WHERE status IN ('planned', 'active') AND end_date_planned IS NOT NULL AND end_date_planned != '0000-00-00'");
        while ($row = $stmt->fetch()) {
            $link = "/gopools/public/projects/edit.php?id=" . (int)$row['id'];
            $title = $row['title'];
            
            if ($row['end_date_planned'] < $today) {
                $this->notifyAdmins("Project overdue! '{$title}' was scheduled to end on {$row['end_date_planned']}.", $link);
            } elseif ($row['end_date_planned'] <= $threshold) {
                $this->notifyAdmins("Project deadline approaching: '{$title}' ends on {$row['end_date_planned']}.", $link);
            }
        }
    }
    
    private function checkTasks(): void {
        // Tasks check (next 3 days)
        $threshold = date('Y-m-d', strtotime('+3 days'));
        $today = date('Y-m-d');
        
        // Use try catch because module project_tasks might be empty or incomplete
        try {
            $stmt = $this->db->query("SELECT id, title, project_id, due_date FROM project_tasks WHERE status NOT IN ('done','cancelled') AND due_date IS NOT NULL AND due_date != '0000-00-00'");
             while ($row = $stmt->fetch()) {
                $link = "/gopools/public/projects/edit.php?id=" . (int)$row['project_id'] . "#tasks";
                $title = $row['title'];
                
                if ($row['due_date'] < $today) {
                    $this->notifyAdmins("Task overdue! '{$title}' was due on {$row['due_date']}.", $link);
                } elseif ($row['due_date'] <= $threshold) {
                    $this->notifyAdmins("Task deadline approaching: '{$title}' is due on {$row['due_date']}.", $link);
                }
            }
        } catch (Throwable $e) {}
    }
}
