<?php
/**
 * سودانا — ScoringAgent v1
 * يُحلِّل نشاط المستخدم ويُحدِّد إمكانيته كمزود خدمة
 * يعمل في الخلفية — غير مرئي للمستخدم
 */
class ScoringAgent {

    const MIN_INTERACTIONS = 5;   // حد أدنى للتحليل
    const NUDGE_COOLDOWN   = 7;   // أيام بين nudges

    // أوزان الـ scoring
    const WEIGHTS = [
        'sector_focus'    => 0.40,
        'question_depth'  => 0.25,
        'community_help'  => 0.20,
        'explicit_data'   => 0.15,
    ];

    // خرائط القطاع → المجال
    const SECTOR_DOMAIN = [
        'medical'    => 'medical',
        'pharmacy'   => 'medical',
        'legal'      => 'legal',
        'education'  => 'education',
        'academic'   => 'education',
        'business'   => 'business',
        'bde'        => 'business',
        'agriculture'=> 'agriculture',
        'tech'       => 'developer',
        'developer'  => 'developer',
        'market'     => 'market',
        'craft'      => 'craft',
        'food'       => 'food',
        'beauty'     => 'beauty',
    ];

    // ── score(): التحليل الكامل لمستخدم ─────────────────────
    public static function score(int $userId): ?array {
        try {
            // اقرأ آخر 30 تفاعل
            $st = db()->prepare(
                "SELECT sector, question, created_at FROM execution_log
                 WHERE user_id=? ORDER BY created_at DESC LIMIT 30"
            );
            $st->execute([$userId]);
            $interactions = $st->fetchAll();

            if (count($interactions) < self::MIN_INTERACTIONS) {
                return null; // بيانات غير كافية
            }

            // 1. تخصص القطاع (40%)
            $sectorCounts = array_count_values(array_column($interactions, 'sector'));
            arsort($sectorCounts);
            $topSector    = array_key_first($sectorCounts);
            $topCount     = $sectorCounts[$topSector] ?? 0;
            $totalCount   = count($interactions);
            $focusScore   = $topCount / $totalCount; // 70%+ = متخصص

            // 2. عمق الأسئلة (25%)
            $totalWords = 0;
            $techTerms  = 0;
            $medTerms   = ['جرعة','تشخيص','أعراض','علاج','دواء','مرض','تحليل','أشعة'];
            $legalTerms = ['عقد','قانون','دعوى','حكم','محكمة','حق','التزام','ضمان'];
            $techTermsList = ['API','كود','برمجة','خوارزمية','قاعدة بيانات','سيرفر'];

            foreach ($interactions as $i) {
                $words = str_word_count($i['question'] ?? '');
                $totalWords += $words;
                $q = $i['question'] ?? '';
                foreach (array_merge($medTerms, $legalTerms, $techTermsList) as $term) {
                    if (mb_stripos($q, $term) !== false) $techTerms++;
                }
            }

            $avgWords   = $totalWords / $totalCount;
            $depthScore = min(($avgWords / 25) * 0.6 + ($techTerms / $totalCount) * 0.4, 1.0);

            // 3. نشاط المجتمع (20%)
            $communityScore = 0.0;
            try {
                $posts = db()->prepare(
                    "SELECT COUNT(*) FROM pulse_posts WHERE user_id=?"
                );
                $posts->execute([$userId]);
                $postCount  = (int)$posts->fetchColumn();
                $communityScore = min($postCount / 10, 1.0);
            } catch (Throwable $e) {}

            // 4. البيانات الصريحة (15%)
            $explicitScore = 0.0;
            try {
                $user = db()->prepare(
                    "SELECT occupation, education_level FROM users WHERE id=? LIMIT 1"
                );
                $user->execute([$userId]);
                $uRow = $user->fetch();
                if (!empty($uRow['occupation'])) $explicitScore += 0.6;
                if (!empty($uRow['education_level'])) $explicitScore += 0.4;
            } catch (Throwable $e) {}

            // ── الحساب النهائي ────────────────────────────────────
            $finalScore = round(
                ($focusScore   * self::WEIGHTS['sector_focus'])  +
                ($depthScore   * self::WEIGHTS['question_depth']) +
                ($communityScore * self::WEIGHTS['community_help']) +
                ($explicitScore * self::WEIGHTS['explicit_data']),
                2
            );

            // تحديد الـ domain
            $domain = self::SECTOR_DOMAIN[$topSector] ?? null;

            // تحديد profile المستخدم
            $profile = self::detectProfile($userId);

            $signals = [
                'top_sector'       => $topSector,
                'focus_pct'        => round($focusScore * 100),
                'avg_question_len' => round($avgWords),
                'tech_terms'       => $techTerms,
                'community_posts'  => 0,
                'interaction_count'=> $totalCount,
            ];

            // حفظ في provider_potential
            self::saveScore($userId, $domain, $finalScore, $profile, $signals);

            return [
                'user_id'          => $userId,
                'domain'           => $domain,
                'score'            => $finalScore,
                'profile'          => $profile,
                'signals'          => $signals,
                'ready_for_nudge'  => $finalScore >= 0.6,
            ];

        } catch (Throwable $e) {
            error_log("[ScoringAgent::score] " . $e->getMessage());
            return null;
        }
    }

    // ── detectProfile(): شخصية المستخدم ──────────────────────
    private static function detectProfile(int $userId): string {
        try {
            $u = db()->prepare(
                "SELECT created_at, gender FROM users WHERE id=? LIMIT 1"
            );
            $u->execute([$userId]);
            $row = $u->fetch();

            $gender = $row['gender'] ?? '';
            if ($gender === 'female' || $gender === 'أنثى') return 'woman';

            $agedays = (time() - strtotime($row['created_at'] ?? 'now')) / 86400;

            // تقدير العمر من نمط الاستخدام
            return $agedays < 30 ? 'young' : 'professional';
        } catch (Throwable $e) {
            return 'professional';
        }
    }

    // ── saveScore(): حفظ النتيجة ─────────────────────────────
    private static function saveScore(
        int $userId, ?string $domain, float $score,
        string $profile, array $signals
    ): void {
        try {
            db()->prepare(
                "INSERT INTO provider_potential
                 (user_id, detected_domain, confidence_score, user_profile, signals, stage)
                 VALUES (?, ?, ?, ?, ?, ?)
                 ON DUPLICATE KEY UPDATE
                   detected_domain=VALUES(detected_domain),
                   confidence_score=VALUES(confidence_score),
                   user_profile=VALUES(user_profile),
                   signals=VALUES(signals),
                   updated_at=NOW()"
            )->execute([
                $userId, $domain, $score, $profile,
                json_encode($signals, JSON_UNESCAPED_UNICODE),
                $score >= 0.6 ? 2 : ($score >= 0.3 ? 1 : 0),
            ]);
        } catch (Throwable $e) {
            error_log("[ScoringAgent::saveScore] " . $e->getMessage());
        }
    }

    // ── getNudgeMessage(): رسالة الـ nudge المناسبة ───────────
    public static function getNudgeMessage(int $userId): ?array {
        try {
            $pp = db()->prepare(
                "SELECT pp.*, ped.avg_monthly_sdg, ped.demand_level, ped.weekly_requests
                 FROM provider_potential pp
                 LEFT JOIN provider_earnings_display ped
                   ON ped.domain = pp.detected_domain AND ped.city = 'الخرطوم'
                 WHERE pp.user_id=? AND pp.confidence_score >= 0.6
                   AND pp.nudge_response != 'negative'
                   AND (pp.last_nudge_at IS NULL
                        OR DATEDIFF(NOW(), pp.last_nudge_at) >= ?)
                 LIMIT 1"
            );
            $pp->execute([$userId, self::NUDGE_COOLDOWN]);
            $row = $pp->fetch();
            if (!$row) return null;

            $stage  = (int)$row['stage'];
            $domain = $row['detected_domain'];
            $avgSdg = number_format((int)($row['avg_monthly_sdg'] ?? 0));
            $demand = $row['demand_level'] ?? 'medium';
            $weekly = (int)($row['weekly_requests'] ?? 0);

            $domainLabel = [
                'medical'    => 'طبية',
                'legal'      => 'قانونية',
                'education'  => 'تعليمية',
                'business'   => 'الأعمال',
                'craft'      => 'حرفية',
                'food'       => 'طعام',
                'beauty'     => 'تجميل',
                'agriculture'=> 'زراعية',
            ][$domain] ?? 'عامة';

            $profile = $row['user_profile'] ?? 'professional';

            // رسائل حسب المرحلة والـ profile
            $messages = [
                2 => [ // المرحلة 2 — اعتراف بالقيمة
                    'professional' => "أسئلتك في المجال {$domainLabel} دقيقة جداً 🎯\nهل أنت متخصص في هذا المجال؟",
                    'woman'        => "لاحظنا إنك بتسألين في مواضيع {$domainLabel} بشكل متخصص 🌸\nهل هذا مجال عملك؟",
                    'young'        => "أسئلتك {$domainLabel} أعمق من المعتاد 💡\nهل درست في هذا المجال؟",
                ],
                3 => [ // المرحلة 3 — بيانات السوق
                    'professional' => "في السودان الآن — الطلب على الخدمات {$domainLabel} كبير جداً 📊\nأسبوعياً: {$weekly} شخص يبحثون ولا يجدون.",
                    'woman'        => "كثير نساء في سودانا حولن مهاراتهن {$domainLabel} لدخل حقيقي 🌟\nمن بيوتهن وبأوقاتهن.",
                    'young'        => "شباب في سودانا بمهارات {$domainLabel} كسبوا أكثر من وظائفهم الرسمية 🚀",
                ],
                4 => [ // المرحلة 4 — الأرقام
                    'professional' => "متخصص {$domainLabel} في سودانا —\nبمتوسط ٣ ساعات أسبوعياً\nدخل إضافي متوسطه: {$avgSdg} SDG/شهر.",
                    'woman'        => "صاحبة مهارة {$domainLabel} في سودانا\nمن بيتها وبوقتها\nتكسب في المتوسط: {$avgSdg} SDG/شهر.",
                    'young'        => "في مجال {$domainLabel}\nشباب مثلك يكسبون: {$avgSdg} SDG/شهر إضافية.",
                ],
                5 => [ // المرحلة 5 — الدعوة اللطيفة
                    'professional' => "التسجيل كمزود ١٠ دقائق فقط ⚡\nأنت من تحدد وقتك وسعرك تماماً.",
                    'woman'        => "لو يوماً جربتِ — التسجيل سهل ومرن ✅\nأنتِ من تتحكمين في كل شيء.",
                    'young'        => "لو تبي تجرب — بدون التزامات ✅\nسهل وسريع وأنت من تقرر.",
                ],
            ];

            $msg = $messages[$stage][$profile]
                ?? $messages[$stage]['professional']
                ?? null;

            if (!$msg) return null;

            // تحديث وقت آخر nudge
            db()->prepare(
                "UPDATE provider_potential SET last_nudge_at=NOW(),
                 stage=LEAST(stage+1, 5) WHERE user_id=?"
            )->execute([$userId]);

            return [
                'message' => $msg,
                'stage'   => $stage,
                'domain'  => $domain,
                'show_register_btn' => $stage >= 5,
            ];

        } catch (Throwable $e) {
            error_log("[ScoringAgent::getNudgeMessage] " . $e->getMessage());
            return null;
        }
    }

    // ── recordResponse(): يحفظ رد المستخدم على الـ nudge ──────
    public static function recordResponse(int $userId, string $response): void {
        try {
            db()->prepare(
                "UPDATE provider_potential SET nudge_response=? WHERE user_id=?"
            )->execute([$response, $userId]);
        } catch (Throwable $e) {}
    }

    // ── runBatch(): يُشغَّل من cron كل 3 أيام ────────────────
    public static function runBatch(int $limit = 100): array {
        $results = ['scored' => 0, 'ready' => 0, 'errors' => 0];
        try {
            $users = db()->query(
                "SELECT DISTINCT user_id FROM execution_log
                 WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
                 GROUP BY user_id HAVING COUNT(*) >= " . self::MIN_INTERACTIONS .
                " LIMIT $limit"
            )->fetchAll(PDO::FETCH_COLUMN);

            foreach ($users as $uid) {
                $r = self::score((int)$uid);
                if ($r) {
                    $results['scored']++;
                    if ($r['ready_for_nudge']) $results['ready']++;
                } else {
                    $results['errors']++;
                }
            }
        } catch (Throwable $e) {
            error_log("[ScoringAgent::runBatch] " . $e->getMessage());
        }
        return $results;
    }
}
