<?php
namespace Core\Services;

class BehaviorIntelligenceService {
    private $db;

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

    /**
     * Unified Discipline Score: Habits + Behaviors + Journaling
     */
    public function getUnifiedDisciplineScore($userId) {
        $date30DaysAgo = date('Y-m-d', strtotime('-30 days'));
        
        // 0. Calculate Active Days
        $sqlActive = "SELECT COUNT(DISTINCT date_col) FROM (
            SELECT date as date_col FROM daily_journal WHERE user_id = ? AND date >= ?
            UNION
            SELECT log_date as date_col FROM habit_logs WHERE user_id = ? AND log_date >= ? AND deleted_at IS NULL
            UNION
            SELECT l.date as date_col FROM behavior_logs l JOIN behavior_habits h ON h.id = l.habit_id WHERE h.user_id = ? AND l.date >= ?
        ) AS active_dates";
        $stmtActive = $this->db->prepare($sqlActive);
        $stmtActive->execute([$userId, $date30DaysAgo, $userId, $date30DaysAgo, $userId, $date30DaysAgo]);
        $activeDays = $stmtActive->fetchColumn() ?: 0;

        if ($activeDays == 0) {
            return 0; // No activity means no discipline score
        }

        // 1. Behavioral Habits (Build/Break)
        $sqlBeh = "
            SELECT h.id, h.habit_type, h.severity, h.intensity,
                (SELECT COUNT(*) FROM behavior_logs l WHERE l.habit_id = h.id AND l.status = 1 AND l.date >= ?) as times_logged
            FROM behavior_habits h
            WHERE h.user_id = ? AND h.is_active = 1
        ";
        $stmtBeh = $this->db->prepare($sqlBeh);
        $stmtBeh->execute([$date30DaysAgo, $userId]);
        $behaviors = $stmtBeh->fetchAll(\PDO::FETCH_ASSOC);

        // 2. Daily Rituals (Habits Module)
        $sqlHabits = "
            SELECT h.id, h.habit_type, h.intensity,
                (SELECT COUNT(*) FROM habit_logs hl WHERE hl.habit_id = h.id AND hl.log_date >= ? AND hl.deleted_at IS NULL) as times_checked
            FROM habits h
            WHERE h.user_id = ? AND h.deleted_at IS NULL
        ";
        $stmtHabits = $this->db->prepare($sqlHabits);
        $stmtHabits->execute([$date30DaysAgo, $userId]);
        $rituals = $stmtHabits->fetchAll(\PDO::FETCH_ASSOC);

        // 3. Journaling Consistency (Impact on Discipline)
        $sqlJournal = "SELECT COUNT(*) as days_journaled FROM daily_journal WHERE user_id = ? AND date >= ?";
        $stmtJournal = $this->db->prepare($sqlJournal);
        $stmtJournal->execute([$userId, $date30DaysAgo]);
        $journalDays = $stmtJournal->fetchColumn() ?: 0;

        $totalWeight = 0;
        $earnedWeight = 0;

        // Process Behaviors
        foreach ($behaviors as $b) {
            $weight = ($b['severity'] == 'high' ? 3 : ($b['severity'] == 'medium' ? 2 : 1)) * $b['intensity'];
            $totalWeight += $weight;
            $rate = min(1, $b['times_logged'] / 30);
            if ($b['habit_type'] === 'build') {
                $earnedWeight += $rate * $weight;
            } else {
                // Break habits: only get points for active days where they didn't fail
                $successDays = max(0, $activeDays - $b['times_logged']);
                $earnedWeight += ($successDays / 30) * $weight;
            }
        }

        // Process Rituals (Habits)
        foreach ($rituals as $r) {
            $weight = 2 * ($r['intensity'] ?: 1); // Rituals carry a base weight of 2
            $totalWeight += $weight;
            $rate = min(1, $r['times_checked'] / 30);
            if ($r['habit_type'] === 'build') {
                $earnedWeight += $rate * $weight;
            } else {
                $successDays = max(0, $activeDays - $r['times_checked']);
                $earnedWeight += ($successDays / 30) * $weight;
            }
        }

        // Add Journaling as a Meta-Habit
        $journalWeight = 10; // High weight for reflection
        $totalWeight += $journalWeight;
        $earnedWeight += (min(1, $journalDays / 30) * $journalWeight);

        if ($totalWeight > 0) {
            return round(($earnedWeight / $totalWeight) * 100);
        }
        return 100; // Perfect score if no habits defined
    }

    public function getIdentityNarrative($score) {
        if ($score >= 90) return "أنت شخص صارم الانضباط بنسبة {$score}% 🏆";
        if ($score >= 75) return "أنت شخص منضبط وملتزم بنسبة {$score}% ✨";
        if ($score >= 50) return "أنت شخص مجاهد لنفسه بنسبة {$score}% 🌱";
        return "انضباطك يحتاج لتدخل بنسبة {$score}% ⚠️";
    }

    public function getMomentumScore($userId) {
        $last7Days = date('Y-m-d', strtotime('-7 days'));
        // Count total successful actions in last 7 days vs potential
        // Simplified: (Successful Behaviors + Rituals + Journals) / (Total Expected)
        $score = $this->getUnifiedDisciplineScore($userId); // Simplified for now
        return $score; 
    }

    public function detectPreFailure($userId) {
        $warnings = [];

        // Condition 1: Low Mood
        try {
            $stmt = $this->db->prepare("SELECT mood_score, mood_tags FROM journal_entries WHERE user_id = ? ORDER BY entry_date DESC LIMIT 1");
            $stmt->execute([$userId]);
            $mood = $stmt->fetch(\PDO::FETCH_ASSOC);
            if ($mood && $mood['mood_score'] <= 4) {
                $warnings[] = "مستشعر المزاج: حالتك النفسية ($mood[mood_score]/10) تجعلك عرضة للانتكاسة اليوم. كن يقظاً!";
            }
        } catch (\Exception $e) {}

        // Condition 2: High Spending
        try {
            $stmt = $this->db->prepare("SELECT SUM(amount) FROM finance_expenses WHERE user_id = ? AND expense_date = CURRENT_DATE()");
            $stmt->execute([$userId]);
            $spentToday = $stmt->fetchColumn() ?: 0;
            if ($spentToday > 500) {
                $warnings[] = "مستشعر المال: إنفاقك اليوم مرتفع، قد يكون استهلاكاً تعويضياً. توقف وراقب اندفاعك!";
            }
        } catch (\Exception $e) {}
        
        return $warnings;
    }

    public function suggestRecovery($userId) {
        $sql = "
            SELECT h.name, h.habit_type 
            FROM behavior_logs l
            JOIN behavior_habits h ON h.id = l.habit_id
            WHERE h.user_id = ? AND l.date >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY) AND h.habit_type = 'break' AND l.status = 1
            LIMIT 1
        ";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
        $failed = $stmt->fetch(\PDO::FETCH_ASSOC);

        if ($failed) {
            return [
                "لا تجعل انتكاستك في '{$failed['name']}' كسر للزجاج. عد للتمسك بانضباطك الآن.",
                "اشرب كوباً من الماء، خذ نفساً عميقاً، ولا تعاقب نفسك... فقط عد للمسار."
            ];
        }
        return [];
    }

    public function autoDetectTriggerIntelligence($userId) {
        $insights = [];
        
        $sql = "
            SELECT h.name, DAYNAME(l.date) as day_of_week, COUNT(*) as fails
            FROM behavior_logs l
            JOIN behavior_habits h ON h.id = l.habit_id
            WHERE h.user_id = ? AND h.habit_type = 'break' AND l.status = 1
            GROUP BY h.id, day_of_week
            ORDER BY fails DESC
            LIMIT 1
        ";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
        $pattern = $stmt->fetch(\PDO::FETCH_ASSOC);

        if ($pattern && $pattern['fails'] > 2) {
            $dayAr = $this->translateDay($pattern['day_of_week']);
            $insights[] = "رصد آلي: عادة الانتكاس في '{$pattern['name']}' ترتفع دائمًا في يوم {$dayAr}!";
        }

        return $insights;
    }

    public function detectStreakRisk($userId) {
        $today = date('Y-m-d');
        // Find habits with streak > 5 that haven't been checked today
        $sql = "
            SELECT h.id, h.name 
            FROM habits h
            LEFT JOIN habit_logs hl ON hl.habit_id = h.id AND hl.log_date = ? AND hl.deleted_at IS NULL
            WHERE h.user_id = ? AND h.deleted_at IS NULL AND hl.id IS NULL
        ";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$today, $userId]);
        $pending = $stmt->fetchAll(\PDO::FETCH_OBJ);
        
        $risks = [];
        foreach ($pending as $p) {
            $risks[] = "عادة '{$p->name}' مهددة بكسر التتابعية! قم بإتمامها الآن.";
        }
        return array_slice($risks, 0, 1); // One smart alert only
    }

    private function translateDay($dayEn) {
        $days = [
            'Saturday' => 'السبت', 'Sunday' => 'الأحد', 'Monday' => 'الاثنين', 
            'Tuesday' => 'الثلاثاء', 'Wednesday' => 'الأربعاء', 'Thursday' => 'الخميس', 'Friday' => 'الجمعة'
        ];
        return $days[$dayEn] ?? $dayEn;
    }
}
