<?php
namespace Core\Services;
use Core\Database;
use PDO;

class ReminderService {
    private $db;

    public function __construct() {
        $this->db = Database::getInstance();
    }

    public function evaluateTriggers($userId) {
        // 1. Auto-Resolve existing pending reminders that are no longer valid
        $this->autoResolvePending($userId);

        // 2. Enforce Daily Limit (max 5 triggers generated per day)
        $dailyCount = $this->db->query(
            "SELECT COUNT(id) FROM smart_reminders WHERE user_id = ? AND DATE(created_at) = CURDATE()",
            [$userId]
        )->fetchColumn();

        if ($dailyCount >= 5) {
            return; // Daily limit reached
        }

        // 3. Evaluate new triggers dynamically (Time-Aware + Cooldown + Adaptation)
        $hour = (int) date('H');
        $isMorning = ($hour >= 5 && $hour < 12);
        $isAfternoon = ($hour >= 12 && $hour < 17);
        $isEvening = ($hour >= 17 || $hour < 5);

        // Check rules in Priority Order (Health > Productivity > Spiritual > Finance > Education)

        // ============ HEALTH (ANYTIME) ============
        $this->evaluateHealth($userId, $dailyCount);

        // ============ PRODUCTIVITY (MORNING) ============
        if ($isMorning) {
            $this->evaluateProductivity($userId, $dailyCount);
        }

        // ============ SPIRITUAL (AFTERNOON) ============
        if ($isAfternoon) {
            $this->evaluateSpiritual($userId, $dailyCount);
        }

        // ============ FINANCE (EVENING) ============
        if ($isEvening) {
            $this->evaluateFinance($userId, $dailyCount);
        }

        // ============ EDUCATION (MORNING) ============
        if ($isMorning) {
            $this->evaluateEducation($userId, $dailyCount);
        }
    }

    private function autoResolvePending($userId) {
        $pending = $this->db->query("SELECT * FROM smart_reminders WHERE user_id = ? AND status = 'pending'", [$userId])->fetchAll(PDO::FETCH_ASSOC);

        foreach ($pending as $rem) {
            $resolved = false;
            if ($rem['category'] === 'health_meds') {
                // Resolved if they took meds today
                $took = $this->db->query("SELECT COUNT(*) FROM health_med_logs WHERE user_id = ? AND DATE(taken_at) = CURDATE()", [$userId])->fetchColumn();
                if ($took > 0) $resolved = true;
            } elseif ($rem['category'] === 'productivity_zero') {
                $done = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id = ? AND status = 'done' AND DATE(updated_at) = CURDATE()", [$userId])->fetchColumn();
                if ($done > 0) $resolved = true;
            } elseif ($rem['category'] === 'spiritual_prayer') {
                $prayed = $this->db->query("SELECT fajr, dhuhr, asr, maghrib, isha FROM spiritual_prayers WHERE user_id = ? AND date = CURDATE()", [$userId])->fetch(PDO::FETCH_ASSOC);
                if ($prayed && ($prayed['fajr'] || $prayed['dhuhr'] || $prayed['asr'] || $prayed['maghrib'] || $prayed['isha'])) {
                    $resolved = true;
                }
            } elseif ($rem['category'] === 'health_lab_abnormal') {
                // Resolved if no urgent labs remaining without tasks. Complex auto-resolve: Just marking true if they created a task today
                $tasksCheck = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id = ? AND DATE(created_at) = CURDATE()", [$userId])->fetchColumn();
                if ($tasksCheck > 0) $resolved = true;
            }

            if ($resolved) {
                $this->db->query("UPDATE smart_reminders SET status = 'done', resolved_at = CURRENT_TIMESTAMP WHERE id = ?", [$rem['id']]);
                
                // Track in reminder_logs
                $this->db->query(
                    "INSERT INTO reminder_logs (user_id, reminder_category, module_type, priority, trigger_time, action_taken, message) VALUES (?, ?, ?, ?, ?, 'auto_resolved', ?)",
                    [$userId, $rem['category'], $rem['module_type'], $rem['priority'], $rem['trigger_time'], $rem['message']]
                );
            }
        }
    }

    private function canTrigger($userId, $category, &$config) {
        // Find how many times ignored
        $ignoreCount = $this->db->query(
            "SELECT COUNT(id) FROM smart_reminders WHERE user_id = ? AND category = ? AND status = 'ignored'",
            [$userId, $category]
        )->fetchColumn();

        $cooldownHours = 3;
        
        // Behavior Adaptation
        if ($ignoreCount >= 3) {
            // Downgrade priority
            if ($config['priority'] === 'high') $config['priority'] = 'medium';
            elseif ($config['priority'] === 'medium') $config['priority'] = 'low';
            // Increase cooldown
            $cooldownHours = 12;
        }

        // Check cooldown
        $lastTrigger = $this->db->query(
            "SELECT trigger_time FROM smart_reminders WHERE user_id = ? AND category = ? ORDER BY trigger_time DESC LIMIT 1",
            [$userId, $category]
        )->fetchColumn();

        if ($lastTrigger) {
            $hoursSince = (time() - strtotime($lastTrigger)) / 3600;
            if ($hoursSince < $cooldownHours) {
                return false;
            }
        }

        return true;
    }

    private function pushReminder($userId, $module, $category, $message, $config, &$dailyCount) {
        if ($dailyCount >= 5) return false;
        
        // Prevent duplicate pending rule
        $isPending = $this->db->query("SELECT id FROM smart_reminders WHERE user_id=? AND category=? AND status='pending'", [$userId, $category])->fetchColumn();
        if ($isPending) return false;

        if (!$this->canTrigger($userId, $category, $config)) return false;

        $this->db->query(
            "INSERT INTO smart_reminders (user_id, module_type, category, message, priority, status) VALUES (?, ?, ?, ?, ?, 'pending')",
            [$userId, $module, $category, $message, $config['priority']]
        );
        
        $dailyCount++;
        return true;
    }

    // ================= RULES =================

    private function evaluateHealth($userId, &$dailyCount) {
        $config = ['priority' => 'high'];

        // Rule 1: Missing Meds today
        $activeMeds = $this->db->query("SELECT COUNT(*) FROM health_medications WHERE user_id = ? AND status = 'active'", [$userId])->fetchColumn();
        if ($activeMeds > 0) {
            $takenToday = $this->db->query("SELECT COUNT(*) FROM health_med_logs WHERE user_id = ? AND DATE(taken_at) = CURDATE()", [$userId])->fetchColumn();
            if ($takenToday == 0 && (int)date('H') >= 10) { // If past 10 AM and no meds
                $this->pushReminder($userId, 'health', 'health_meds', 'تنبيه صحي: لم تسجل تناول أدويتك اليوم.', $config, $dailyCount);
            }
        }

        // Rule 2: Abnormal labs + no action (has urgent un-acted labs last 7 days)
        $urgentLabs = $this->db->query("SELECT COUNT(*) FROM health_labs WHERE user_id=? AND action_level IN ('urgent', 'doctor_visit') AND test_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)", [$userId])->fetchColumn();
        $tasksCreatedSince = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND DATE(created_at) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)", [$userId])->fetchColumn();
        if ($urgentLabs > 0 && $tasksCreatedSince == 0) {
            $this->pushReminder($userId, 'health', 'health_lab_abnormal', 'لديك نتائج تحاليل حرجة مؤخراً ولم تنشئ لها أي إجراء طبي (مهمة/موعد).', $config, $dailyCount);
        }
    }

    private function evaluateProductivity($userId, &$dailyCount) {
        // High Priority: Overdue Tasks
        $overdueCount = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id = ? AND status != 'done' AND due_date < CURDATE() AND deleted_at IS NULL", [$userId])->fetchColumn();
        if ($overdueCount > 0) {
            $this->pushReminder($userId, 'productivity', 'todo_overdue', "لديك {$overdueCount} مهمة متأخرة! يرجى مراجعتها وإعادة جدولتها أو إنجازها اليوم.", ['priority' => 'high'], $dailyCount);
        }

        // Medium Priority: Upcoming Calendar Events
        $upcomingEvents = $this->db->query("SELECT COUNT(*) FROM calendar_events WHERE user_id = ? AND event_date = CURDATE() AND status = 'active' AND is_completed = 0 AND deleted_at IS NULL", [$userId])->fetchColumn();
        if ($upcomingEvents > 0) {
            $this->pushReminder($userId, 'calendar', 'calendar_upcoming', "تذكير: لديك {$upcomingEvents} حدث/أحداث مبرمجة في التقويم لهذا اليوم.", ['priority' => 'medium'], $dailyCount);
        }

        $config = ['priority' => 'medium'];
        $doneToday = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id = ? AND status = 'done' AND DATE(updated_at) = CURDATE()", [$userId])->fetchColumn();
        if ($doneToday == 0 && (int)date('H') >= 10) { // Late morning check
            $this->pushReminder($userId, 'productivity', 'productivity_zero', 'الإنتاجية صفر اليوم! ابدأ بمهمة صغيرة لمدة 5 دقائق الآن لكسر الجمود.', $config, $dailyCount);
        }
    }

    private function evaluateSpiritual($userId, &$dailyCount) {
        $config = ['priority' => 'medium'];
        $prayed = $this->db->query("SELECT * FROM spiritual_prayers WHERE user_id = ? AND date = CURDATE()", [$userId])->fetch(PDO::FETCH_ASSOC);
        if (!$prayed || (!$prayed['fajr'] && !$prayed['dhuhr'] && !$prayed['asr'])) {
            $this->pushReminder($userId, 'spiritual', 'spiritual_prayer', 'صلاتك هي مصدر بركتك.. لا تدع يومك يسرقك منها. قم للصلاة الآن.', $config, $dailyCount);
        }
    }

    private function evaluateFinance($userId, &$dailyCount) {
        $config = ['priority' => 'medium'];

        // Dynamic target: avg daily spending last 30 days
        $pastSum = $this->db->query("SELECT SUM(amount) FROM finance_expenses WHERE user_id = ? AND expense_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND DATE_SUB(CURDATE(), INTERVAL 1 DAY)", [$userId])->fetchColumn();
        $avgDaily = ($pastSum ?: 0) / 30;
        if ($avgDaily <= 0) $avgDaily = 50; // Fallback baseline

        $todaySum = $this->db->query("SELECT SUM(amount) FROM finance_expenses WHERE user_id = ? AND expense_date = CURDATE()", [$userId])->fetchColumn() ?: 0;

        if ($todaySum > ($avgDaily * 1.5)) {
            $this->pushReminder($userId, 'finance', 'finance_overspending', 'انذار مالي: معدل إنفاقك اليوم تجاوز 150% من متوسطك المعتاد!', $config, $dailyCount);
        }
    }

    private function evaluateEducation($userId, &$dailyCount) {
        $config = ['priority' => 'low'];
        $activeCourses = $this->db->query("SELECT COUNT(*) FROM edu_courses WHERE user_id = ? AND status = 'in_progress'", [$userId])->fetchColumn();
        if ($activeCourses > 0) {
            $recentProgress = $this->db->query("SELECT COUNT(*) FROM edu_courses WHERE user_id = ? AND status = 'in_progress' AND updated_at >= DATE_SUB(CURDATE(), INTERVAL 3 DAY)", [$userId])->fetchColumn();
            if ($recentProgress == 0) {
                $this->pushReminder($userId, 'education', 'education_stagnant', 'رحلتك التعليمية متوقفة منذ أيام. خصص 15 دقيقة اليوم لاستئناف مسارك المعرفي.', $config, $dailyCount);
            }
        }
    }

    public function getPendingReminders($userId) {
        $this->evaluateTriggers($userId); // Try to trigger or resolve first
        
        $focusMode = 0;
        try {
            $focusMode = $this->db->query("SELECT focus_mode FROM user_settings WHERE user_id = ?", [$userId])->fetchColumn() ?: 0;
        } catch (\PDOException $e) {}

        if ($focusMode == 1) {
            return $this->db->query("SELECT * FROM smart_reminders WHERE user_id = ? AND status = 'pending' AND priority = 'high' ORDER BY created_at DESC", [$userId])->fetchAll(PDO::FETCH_ASSOC);
        }

        $allPending = $this->db->query("SELECT * FROM smart_reminders WHERE user_id = ? AND status = 'pending' ORDER BY FIELD(priority, 'high', 'medium', 'low'), created_at DESC", [$userId])->fetchAll(PDO::FETCH_ASSOC);

        // Smart Bundling
        $high = [];
        $lowMed = [];
        foreach($allPending as $r) {
            if ($r['priority'] === 'high') {
                $high[] = $r;
            } else {
                $lowMed[] = $r;
            }
        }

        if (count($lowMed) > 1) {
            $bundle = [
                'id' => "'bundle'", // output as string for JS
                'user_id' => $userId,
                'module_type' => 'system',
                'category' => 'bundled',
                'message' => "لديك " . count($lowMed) . " تنبيهات منخفضة ومتوسطة الأهمية تحتاج مراجعة.",
                'priority' => 'medium'
            ];
            $high[] = $bundle;
            return $high;
        }

        return $allPending;
    }

    public function markReminderStatus($userId, $reminderId, $status) {
        if (!in_array($status, ['done', 'ignored'])) return false;

        if ($reminderId === 'bundle') {
            $pendingList = $this->db->query("SELECT * FROM smart_reminders WHERE user_id = ? AND status = 'pending' AND priority IN ('low', 'medium')", [$userId])->fetchAll(PDO::FETCH_ASSOC);
            foreach($pendingList as $rem) {
                $this->markReminderStatus($userId, $rem['id'], $status);
            }
            return true;
        }

        $rem = $this->db->query("SELECT * FROM smart_reminders WHERE id = ? AND user_id = ?", [$reminderId, $userId])->fetch(PDO::FETCH_ASSOC);
        if (!$rem) return false;

        $this->db->query("UPDATE smart_reminders SET status = ?, resolved_at = CURRENT_TIMESTAMP WHERE id = ?", [$status, $reminderId]);
        
        $action = ($status === 'done') ? 'completed' : 'ignored';
        $this->db->query(
            "INSERT INTO reminder_logs (user_id, reminder_category, module_type, priority, trigger_time, action_taken, message) VALUES (?, ?, ?, ?, ?, ?, ?)",
            [$userId, $rem['category'], $rem['module_type'], $rem['priority'], $rem['trigger_time'], $action, $rem['message']]
        );

        return true;
    }
}
