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

class NudgeService {
    private $db;

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

    public function getActiveNudge($userId, $advisorData = []) {
        // Enforce Limiting Rules
        
        // 1. Max 2 nudges per day
        $dailyCount = $this->db->query("SELECT COUNT(*) FROM smart_nudges_log WHERE user_id=? AND DATE(shown_at) = CURDATE()", [$userId])->fetchColumn();
        if ($dailyCount >= 2) return null;

        // Collect Candidate Nudges
        $candidates = [];

        $hour = (int)date('H');

        // ==== Inactivity Check (HIGH PRIORITY) ====
        // No tasks created or updated today/yesterday, no meals, no expenses
        $recentUpdates = $this->db->query("
            SELECT 
                (SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND DATE(created_at) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) +
                (SELECT COUNT(*) FROM health_meals WHERE user_id=? AND DATE(eaten_at) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) +
                (SELECT COUNT(*) FROM spiritual_daily_logs WHERE user_id=? AND date >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND final_score > 0)
            AS total
        ", [$userId, $userId, $userId])->fetchColumn();

        if ($recentUpdates == 0) {
            $candidates[] = [
                'code' => 'inactivity_2days',
                'priority' => 'high',
                'message' => 'بقالك فترة مسجلتش أي تقدم في النظام، ارجع حتى لو بخطوة واحدة بسيطة النهاردة.',
                'action_text' => 'إضافة مهمة سريعة',
                'action_url' => '#quickAddForm',
                'tags' => ['system']
            ];
        }

        // ==== Low Productivity (HIGH PRIORITY) ====
        if ($hour >= 15) {
            $doneTasks = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status='done' AND target_date=CURDATE() AND deleted_at IS NULL", [$userId])->fetchColumn();
            $pendingTasks = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status!='done' AND target_date=CURDATE() AND deleted_at IS NULL", [$userId])->fetchColumn();
            
            if ($doneTasks == 0 && $pendingTasks > 0) {
                $candidates[] = [
                    'code' => 'low_prod_afternoon',
                    'priority' => 'high',
                    'message' => 'اليوم قرب يخلص ومفيش أي منجزات حتى الآن، ابدأ بأصغر وأسهل مهمة حالاً عشان تكسر الحاجز.',
                    'action_text' => 'تفقد مهامك',
                    'action_url' => BASE_URL . '/todo',
                    'tags' => ['productivity']
                ];
            }
        }

        // ==== Spiritual Dryness (MEDIUM PRIORITY) ====
        $spiritualScore = $this->db->query("SELECT final_score FROM spiritual_daily_logs WHERE user_id=? AND date=CURDATE()", [$userId])->fetchColumn();
        if ($spiritualScore !== false && $spiritualScore < 30 && $hour >= 18) {
            $candidates[] = [
                'code' => 'spiritual_dryness',
                'priority' => 'medium',
                'message' => 'رصيدك الروحي النهاردة منخفض جداً، ما زال أمامك وقت لتدارك اليوم ببعض الأذكار أو ورك قرآني خفيف.',
                'action_text' => 'تحديث الروحانيات',
                'action_url' => BASE_URL . '/spiritual',
                'tags' => ['spiritual']
            ];
        }

        // ==== Broken Streak (MEDIUM PRIORITY) ====
        // (Simplified logic: if they didn't do anything yesterday but did the day before)
        $doneYesterday = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status='done' AND target_date=DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND deleted_at IS NULL", [$userId])->fetchColumn();
        $doneDayBefore = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND status='done' AND target_date=DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND deleted_at IS NULL", [$userId])->fetchColumn();
        
        if ($doneYesterday == 0 && $doneDayBefore > 0) {
            $candidates[] = [
                'code' => 'broken_streak',
                'priority' => 'medium',
                'message' => 'سلسلة إنجازاتك انكسرت امبارح! مفيش مشكلة، المهم إنك ترجع النهاردة بقوة وتستمر.',
                'action_text' => 'استأنف أهدافك',
                'action_url' => BASE_URL . '/todo',
                'tags' => ['streak', 'productivity']
            ];
        }

        // ==== Empty Morning (LOW PRIORITY) ====
        if ($hour < 12) {
            $totalTasks = $this->db->query("SELECT COUNT(*) FROM todo_tasks WHERE user_id=? AND target_date=CURDATE() AND deleted_at IS NULL", [$userId])->fetchColumn();
            if ($totalTasks == 0) {
                $candidates[] = [
                    'code' => 'empty_morning',
                    'priority' => 'low',
                    'message' => 'صباح الخير! يومك لسه أبيض، حط قدامك هدف أو مهمتين للتركيز عليهم النهارده.',
                    'action_text' => 'إضافة هدف اليوم',
                    'action_url' => '#quickAddForm',
                    'tags' => ['planning']
                ];
            }
        }

        // --- FILTERING & SELECTION ---
        if (empty($candidates)) return null;

        // Advisor Sync Restriction: Avoid nudges with same tags as main advice
        $advisorTags = $advisorData['main_advice']['tags'] ?? [];
        $candidates = array_filter($candidates, function($c) use ($advisorTags) {
            foreach($c['tags'] as $tg) {
                if (in_array($tg, $advisorTags)) return false;
            }
            return true;
        });

        // 24h Cooldown & Dismiss Logic Filter
        $validCandidates = [];
        foreach($candidates as $c) {
            $history = $this->db->query("SELECT shown_at, dismiss_count FROM smart_nudges_log WHERE user_id=? AND nudge_code=? ORDER BY shown_at DESC LIMIT 1", [$userId, $c['code']])->fetch();
            
            if ($history) {
                $hoursSince = (time() - strtotime($history->shown_at)) / 3600;
                // If they dismissed it heavily (> 3 times), exact 7 day penalty. Otherwise 24h cooldown.
                $cooldown = ($history->dismiss_count >= 3) ? (24 * 7) : 24;

                if ($hoursSince < $cooldown) {
                    continue; // Skip, still in cooldown
                }
            }
            $validCandidates[] = $c;
        }

        if (empty($validCandidates)) return null;

        // Priority Rule: If high exists -> show ONLY high
        $highs = array_filter($validCandidates, fn($c) => $c['priority'] === 'high');
        $meds = array_filter($validCandidates, fn($c) => $c['priority'] === 'medium');
        $lows = array_filter($validCandidates, fn($c) => $c['priority'] === 'low');

        $finalPool = !empty($highs) ? $highs : (!empty($meds) ? $meds : $lows);
        
        // Randomly pick one from the highest available tier
        $selected = $finalPool[array_rand($finalPool)];

        // Log the Nudge (to enforce cooldowns)
        $this->logNudgeView($userId, $selected['code']);

        return $selected;
    }

    private function logNudgeView($userId, $code) {
        $exists = $this->db->query("SELECT id FROM smart_nudges_log WHERE user_id=? AND nudge_code=?", [$userId, $code])->fetchColumn();
        if ($exists) {
            // Update time
            $this->db->query("UPDATE smart_nudges_log SET shown_at=NOW() WHERE id=?", [$exists]);
        } else {
            // Insert
            $this->db->query("INSERT INTO smart_nudges_log (user_id, nudge_code, shown_at, dismiss_count) VALUES (?, ?, NOW(), 0)", [$userId, $code]);
        }
    }

    public function logDismissal($userId, $code) {
        $this->db->query("UPDATE smart_nudges_log SET dismissed_at=NOW(), dismiss_count = dismiss_count + 1 WHERE user_id=? AND nudge_code=?", [$userId, $code]);
    }
}
