<?php
namespace Core\Services;

class VitalityService {
    private $db;

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

    /**
     * Calculates the daily Vitality Score (0-100) and returns diagnostic breakdown.
     */
    public function calculateDailyVitality($userId) {
        $score = 100;
        $diagnostics = [];
        $actions = [];

        $today = date('Y-m-d');

        // 1. Water Intake (Max impact: 20 points)
        $profile = $this->getProfile($userId);
        $waterGoal = $profile['water_goal'] ?? 8;
        $waterCups = $this->getTodayWater($userId);
        if ($waterCups < $waterGoal) {
            $deduction = (($waterGoal - $waterCups) / $waterGoal) * 20;
            $score -= $deduction;
            $diagnostics[] = "نقص في كمية الماء: مسجل $waterCups من أصل $waterGoal";
            if ($waterCups < ($waterGoal/2)) {
                $actions[] = ['type' => 'water', 'text' => "اقطع ما تفعله الآن واشرب كوبين من الماء!", 'priority' => 'high'];
            } else {
                $actions[] = ['type' => 'water', 'text' => "لا تنسَ شرب المزيد من الماء.", 'priority' => 'medium'];
            }
        } else {
            $diagnostics[] = "ممتاز، أنت ملتزم بالحد الأدنى للماء!";
        }

        // 2. Fasting / Meals
        $activeFast = $this->getActiveFast($userId);
        if ($activeFast) {
            // Good: they are fasting, +score slightly or no deduction
        }

        // Blood Sugar Spikes
        $bloodSugars = $this->getTodayBloodSugars($userId);
        foreach ($bloodSugars as $bs) {
            if ($bs['is_after_meal'] && $bs['level'] >= 140) {
                $score -= 10;
                $diagnostics[] = "رصدنا ارتفاع سكر الدم بعد الوجبة ({$bs['level']})";
                $actions[] = ['type' => 'sugar', 'text' => "مارس المشي السريع لمدة 10 دقائق لخفض مؤشر السكر المرتفع المستشعر.", 'priority' => 'high'];
            }
        }

        // 3. Activity (Impact: 15 points)
        $activities = $this->getTodayActivities($userId);
        if (empty($activities)) {
            $score -= 15;
            $diagnostics[] = "لم تسجل أي نشاط حركي اليوم.";
            $actions[] = ['type' => 'activity', 'text' => "تمرين اليوم لم يُسجل، تحرك الآن أو خصص وقتاً للمشي.", 'priority' => 'medium'];
        }

        // 4. Missing Medications
        $medsMissing = $this->getMissingMeds($userId);
        if ($medsMissing > 0) {
            $score -= (10 * $medsMissing);
            $diagnostics[] = "لم تتناول جميع أدويتك $medsMissing دواء متبقي.";
            $actions[] = ['type' => 'meds', 'text' => "لديك جرعة دواء تأخرت، تناولها فوراً إن كان الوقت يسمح.", 'priority' => 'critical'];
        }

        // 5. Active Symptoms
        $activeSymptoms = $this->getActiveSymptoms($userId);
        if (!empty($activeSymptoms)) {
            foreach($activeSymptoms as $sym) {
                $score -= (5 * $sym['severity']); // High severity impacts heavily
                if ($sym['severity'] >= 8) {
                    $actions[] = ['type' => 'symptom_alert', 'text' => "عرض ({$sym['symptom_name']}) حاد جداً، يجب تحديد موعد مع الطبيب الآن.", 'priority' => 'critical'];
                }
            }
        }

        $score = max(0, min(100, $score)); // clamp 0-100

        // Optionally update the day's record in DB
        $stmt = $this->db->prepare("UPDATE health_profile SET vitality_score = ? WHERE user_id = ?");
        $stmt->execute([$score, $userId]);

        // Default Positive Action if everything is perfect
        if (empty($actions) && $score > 90) {
            $actions[] = ['type' => 'positivity', 'text' => "حالتك الجسدية في ذروتها، استغل هذا النشاط لإنجاز مهامك المعقدة!", 'priority' => 'low'];
        }
        // Sync Intelligence Loop
        $this->syncActionsToTodo($userId, $actions);
        $this->syncFastingToCalendar($userId);

        return [
            'score' => round($score),
            'diagnostics' => $diagnostics,
            'actions' => $actions,
            'status' => $this->getScoreStatus($score)
        ];
    }

    private function getScoreStatus($score) {
        if ($score >= 90) return ['color' => 'success', 'icon' => 'fa-fire-flame-curved', 'text' => 'حيوي ومثالي'];
        if ($score >= 70) return ['color' => 'primary', 'icon' => 'fa-battery-three-quarters', 'text' => 'مستقر وجيد'];
        if ($score >= 50) return ['color' => 'warning', 'icon' => 'fa-battery-half', 'text' => 'يحتاج انتباه'];
        return ['color' => 'danger', 'icon' => 'fa-battery-empty', 'text' => 'إرهاق خطير'];
    }

    public function generateUnifiedTimeline($userId) {
        $timeline = [];
        
        // Meals
        $meals = $this->db->prepare("SELECT 'meal' as type, id, meal_type as title, description, eaten_at as time FROM health_meals WHERE user_id = ? AND DATE(eaten_at) = CURDATE()");
        $meals->execute([$userId]);
        foreach($meals->fetchAll(\PDO::FETCH_ASSOC) as $row) { $timeline[] = $row; }

        // Fasts
        $fasts = $this->db->prepare("SELECT 'fast' as type, id, 'صيام' as title, CONCAT(plan_hours, ' ساعة') as description, start_time as time FROM health_fasts WHERE user_id = ? AND DATE(start_time) = CURDATE()");
        $fasts->execute([$userId]);
        foreach($fasts->fetchAll(\PDO::FETCH_ASSOC) as $row) { $timeline[] = $row; }

        // Labs
        $labs = $this->db->prepare("SELECT 'lab' as type, id, test_name as title, result_value as description, test_date as time FROM health_labs WHERE user_id = ? AND test_date = CURDATE()");
        $labs->execute([$userId]);
        foreach($labs->fetchAll(\PDO::FETCH_ASSOC) as $row) { 
            $row['time'] .= ' 00:00:00'; // Add time part to dates
            $timeline[] = $row; 
        }

        // Blood Sugar
        $sugars = $this->db->prepare("SELECT 'sugar' as type, id, measurement_type as title, level as description, created_at as time FROM health_blood_sugar WHERE user_id = ? AND date = CURDATE()");
        $sugars->execute([$userId]);
        foreach($sugars->fetchAll(\PDO::FETCH_ASSOC) as $row) { $timeline[] = $row; }

        // Sort descending by time
        usort($timeline, function($a, $b) {
            return strtotime($b['time']) - strtotime($a['time']);
        });

        return $timeline;
    }

    public function getPredictiveInsights($userId) {
        $insights = [];

        // 1. Weight Trend (last 7 days over past month)
        // Simple linear logic
        $weights = $this->db->prepare("SELECT weight, logged_at FROM health_weight_logs WHERE user_id = ? ORDER BY logged_at DESC LIMIT 5");
        $weights->execute([$userId]);
        $wData = $weights->fetchAll(\PDO::FETCH_ASSOC);
        
        if (count($wData) >= 2) {
            $diff = $wData[0]['weight'] - $wData[count($wData)-1]['weight'];
            if ($diff > 0) {
                $insights[] = ['type' => 'trend-up', 'text' => "هناك ميل لزيادة الوزن مؤخراً (+$diff كجم). قد تحتاج لتعديل نافذة الصيام."];
            } elseif ($diff < 0) {
                $insights[] = ['type' => 'trend-down', 'text' => "استمر! أنت في مسار نزول ممتاز (" . abs($diff) . " كجم)."];
            }
        }

        // 2. Behavioral link (if Journal exists, mood patterns) - assuming journal schema
        try {
            $stmt = $this->db->prepare("SELECT mood_score FROM journal_entries WHERE user_id = ? AND DATE(created_at) = CURDATE()");
            $stmt->execute([$userId]);
            $journal = $stmt->fetch(\PDO::FETCH_ASSOC);
            if ($journal && $journal['mood_score'] < 3) {
                $insights[] = ['type' => 'behavior', 'text' => "المزاج منخفض اليوم، الإجهاد العقلي قد يرفع الكورتيزول ويؤثر على السكر."];
            }
        } catch (\Exception $e) { }

        return $insights;
    }

    // --- Helper DB queries ---
    private function getProfile($userId) {
        $stmt = $this->db->prepare("SELECT * FROM health_profile WHERE user_id = ?");
        $stmt->execute([$userId]);
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }
    
    private function getTodayWater($userId) {
        $stmt = $this->db->prepare("SELECT cups FROM health_water_logs WHERE user_id = ? AND log_date = CURDATE()");
        $stmt->execute([$userId]);
        return $stmt->fetchColumn() ?: 0;
    }

    private function getActiveFast($userId) {
        $stmt = $this->db->prepare("SELECT * FROM health_fasts WHERE user_id = ? AND status = 'active' LIMIT 1");
        $stmt->execute([$userId]);
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }

    private function getTodayBloodSugars($userId) {
        $stmt = $this->db->prepare("SELECT * FROM health_blood_sugar WHERE user_id = ? AND date = CURDATE()");
        $stmt->execute([$userId]);
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    private function getTodayActivities($userId) {
        $stmt = $this->db->prepare("SELECT * FROM health_activities WHERE user_id = ? AND log_date = CURDATE()");
        $stmt->execute([$userId]);
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    private function getMissingMeds($userId) {
        // active meds not in med_logs today
        $sql = "
            SELECT COUNT(m.id) as missing
            FROM health_medications m
            WHERE m.user_id = ? AND m.is_active = 1 
            AND (m.med_type = 'chronic' OR (m.med_type = 'prescription' AND (m.end_date IS NULL OR m.end_date >= CURDATE())))
            AND m.id NOT IN (
                SELECT l.med_id FROM health_med_logs l WHERE l.user_id = ? AND DATE(l.taken_at) = CURDATE()
            )
        ";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $userId]);
        return $stmt->fetchColumn() ?: 0;
    }

    private function getActiveSymptoms($userId) {
        $stmt = $this->db->prepare("SELECT * FROM health_symptoms_log WHERE user_id = ? AND end_date IS NULL");
        $stmt->execute([$userId]);
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    public function syncGoalsToMonthlyPlan($userId) {
        // Automatically link health goals to monthly plan if feature is enabled
        $profile = $this->getProfile($userId);
        if (empty($profile['sync_monthly_plan'])) return;
        
        $monthKey = date('Y-m');
        
        try {
            $stmt = $this->db->prepare("SELECT id FROM monthly_plans WHERE user_id = ? AND month_key = ?");
            $stmt->execute([$userId, $monthKey]);
            $planId = $stmt->fetchColumn();
        } catch (\PDOException $e) {
            return false;
        }
    }

    private function syncActionsToTodo($userId, $actions) {
        // Disabled: The user requested not to clutter the Todo module with ephemeral health alerts (like drinking water).
        return;
        
        if (empty($actions)) return;
        
        foreach ($actions as $action) {
            // Only sync high/critical priority to Todo
            if (!in_array($action['priority'], ['critical', 'high'])) continue;

            $title = "[تنبيه صحي] " . mb_substr($action['text'], 0, 40) . "...";

            // Check if already synced today to avoid spam
            $check = $this->db->prepare("SELECT id FROM todo_tasks WHERE user_id = ? AND title = ? AND DATE(created_at) = CURDATE()");
            $check->execute([$userId, $title]);
            if ($check->fetchColumn()) continue;

            $priorityMap = ['critical' => 'high', 'high' => 'medium'];
            $todoPriority = $priorityMap[$action['priority']] ?? 'low';

            try {
                $ins = $this->db->prepare("INSERT INTO todo_tasks (user_id, title, description, category, priority, estimated_time, energy_level, target_date, status) VALUES (?, ?, ?, 'الصحة', ?, 15, 'low', CURDATE(), 'pending')");
                $ins->execute([$userId, $title, $action['text'], $todoPriority]);
            } catch (\PDOException $e) { } // Ignore if Todo table missing
        }
    }

    private function syncFastingToCalendar($userId) {
        $fast = $this->getActiveFast($userId);
        if (!$fast) return;

        $startDate = date('Y-m-d', strtotime($fast['start_time']));
        $startTime = date('H:i:s', strtotime($fast['start_time']));
        
        // Calculate End Time
        $planHours = (int)$fast['plan_hours'];
        $endTs = strtotime($fast['start_time']) + ($planHours * 3600);
        $endDate = date('Y-m-d', $endTs);
        $endTime = date('H:i:s', $endTs);

        $title = "نافذة الصيام ($planHours ساعة)";

        // Check if block already exists
        $check = $this->db->prepare("SELECT id FROM calendar_time_blocks WHERE user_id = ? AND title = ? AND block_date = ?");
        $check->execute([$userId, $title, $startDate]);
        if ($check->fetchColumn()) return;

        try {
            // Start blocking the time in Calendar
            $ins = $this->db->prepare("INSERT INTO calendar_time_blocks (user_id, title, block_date, start_time, end_time, category, color_hex, notes) VALUES (?, ?, ?, ?, ?, 'الصحة', '#10b981', 'صيام مستمر')");
            $ins->execute([$userId, $title, $startDate, $startTime, $endTime]);
            
            // If it bridges to next day, block next day too up to end time
            if ($endDate != $startDate) {
                $checkNext = $this->db->prepare("SELECT id FROM calendar_time_blocks WHERE user_id = ? AND title = ? AND block_date = ?");
                $checkNext->execute([$userId, $title, $endDate]);
                if (!$checkNext->fetchColumn()) {
                    $insDay2 = $this->db->prepare("INSERT INTO calendar_time_blocks (user_id, title, block_date, start_time, end_time, category, color_hex, notes) VALUES (?, ?, ?, '00:00:00', ?, 'الصحة', '#10b981', 'استكمال الصيام')");
                    $insDay2->execute([$userId, $title, $endDate, $endTime]);
                }
            }
        } catch (\PDOException $e) { }
    }
}
