<?php
/**
 * سودانا — SuggestionsAgent v1
 * يُحلِّل اقتراحات المستخدمين ويُولِّد تقرير للإدارة
 * Input: suggestion data → Output: priority + analysis + recommendation
 */
class SuggestionsAgent {

    const TYPE_WEIGHTS = [
        'bug'         => 0.90, // أعلى أولوية — مشكلة تؤثر على المستخدمين
        'improvement' => 0.70,
        'solution'    => 0.65,
        'new_service' => 0.50,
        'positive'    => 0.20, // للتوثيق فقط
    ];

    const PLAN_WEIGHTS = [
        'pro'  => 1.20,
        'plus' => 1.10,
        'free' => 1.00,
        'corp' => 1.30,
    ];

    const SERVICE_TEAMS = [
        'medical'   => 'product',
        'legal'     => 'product',
        'pharmacy'  => 'product',
        'education' => 'product',
        'market'    => 'product',
        'community' => 'product',
        'payment'   => 'tech',
        'wallet'    => 'tech',
        'api'       => 'tech',
        'platform'  => 'tech',
        'billing'   => 'tech',
        'ui'        => 'design',
        'ux'        => 'design',
        'general'   => 'product',
    ];

    // ── analyze(): التحليل الكامل ─────────────────────────────────
    public static function analyze(array $suggestion): array {
        $type        = $suggestion['type'] ?? 'improvement';
        $service     = $suggestion['service'] ?? 'general';
        $description = $suggestion['description'] ?? '';
        $planKey     = $suggestion['user_plan'] ?? 'free';
        $votes       = (int)($suggestion['votes_count'] ?? 0);

        // 1. Base score from type
        $baseScore = self::TYPE_WEIGHTS[$type] ?? 0.50;

        // 2. Complexity inverse (shorter = simpler = higher priority)
        $wordCount  = str_word_count($description);
        $complexity = min($wordCount / 200, 1.0);
        $simplicityScore = 1.0 - ($complexity * 0.3);

        // 3. Novelty — check for duplicates
        $duplicateIds = self::findSimilar($description, $suggestion['id'] ?? 0);
        $noveltyScore = empty($duplicateIds) ? 1.0 : 0.2;

        // 4. User plan weight
        $planMultiplier = self::PLAN_WEIGHTS[$planKey] ?? 1.0;

        // 5. Votes impact
        $votesScore = min($votes / 100, 1.0) * 0.3;

        // Final score
        $rawScore = ($baseScore * 0.40) + ($simplicityScore * 0.25) +
                    ($noveltyScore * 0.20) + ($votesScore * 0.15);
        $finalScore = min(round($rawScore * $planMultiplier, 2), 1.0);

        // Priority label
        $priority = match(true) {
            $finalScore >= 0.80 => 'urgent',
            $finalScore >= 0.60 => 'high',
            $finalScore >= 0.40 => 'medium',
            $finalScore >= 0.20 => 'low',
            !empty($duplicateIds) => 'duplicate',
            default              => 'out_of_scope',
        };

        // Effort estimation
        [$effort, $effortHours] = self::estimateEffort($type, $service, $description);

        // Revenue impact
        $revenueImpact = self::estimateRevenue($type, $service, $votes);

        // Team responsible
        $team = self::SERVICE_TEAMS[$service] ?? 'product';
        if ($type === 'bug') $team = 'tech';

        // Risk level
        $risk = match($type) {
            'bug'         => 'high',
            'improvement' => 'low',
            'solution'    => 'medium',
            'new_service' => 'medium',
            default       => 'low',
        };

        // Roadmap quarter
        $quarter = match($priority) {
            'urgent' => 'Q' . ceil(date('n') / 3),
            'high'   => 'Q' . min(ceil(date('n') / 3) + 1, 4),
            'medium' => 'Q' . min(ceil(date('n') / 3) + 2, 4),
            default  => 'Backlog',
        };

        // Affected users estimate
        $affected = self::estimateAffected($service, $votes);

        // AI recommendation
        $recommendation = self::buildRecommendation($priority, $type, $effort, $affected);

        // AI Summary (using Gemini for cost efficiency)
        $aiSummary = self::generateSummary($suggestion, [
            'priority'    => $priority,
            'score'       => $finalScore,
            'effort'      => $effort,
            'affected'    => $affected,
            'team'        => $team,
        ]);

        return [
            'priority_score'   => $finalScore,
            'priority_label'   => $priority,
            'ai_summary'       => $aiSummary,
            'ai_recommendation'=> $recommendation,
            'affected_estimate'=> $affected,
            'effort_level'     => $effort,
            'effort_hours'     => $effortHours,
            'revenue_impact'   => $revenueImpact,
            'team_responsible' => $team,
            'risk_level'       => $risk,
            'roadmap_quarter'  => $quarter,
            'similar_ids'      => $duplicateIds,
            'category_tag'     => self::categorize($type, $service),
        ];
    }

    // ── findSimilar(): البحث عن اقتراحات مشابهة ─────────────────
    public static function findSimilar(string $description, int $excludeId = 0): array {
        try {
            $words  = array_filter(explode(' ', mb_strtolower($description)), fn($w) => mb_strlen($w) > 3);
            $query  = implode(' ', array_slice($words, 0, 8));
            if (empty($query)) return [];

            $st = db()->prepare(
                "SELECT id, title, description FROM user_suggestions
                 WHERE id != ? AND status != 'rejected'
                 ORDER BY created_at DESC LIMIT 50"
            );
            $st->execute([$excludeId]);
            $existing = $st->fetchAll();

            $similar = [];
            foreach ($existing as $row) {
                $sim = self::jaccard($words, explode(' ', mb_strtolower($row['description'])));
                if ($sim > 0.35) {
                    $similar[] = $row['id'];
                }
            }
            return array_slice($similar, 0, 5);
        } catch (Throwable $e) {
            return [];
        }
    }

    // ── jaccard(): حساب تشابه النصوص ─────────────────────────────
    private static function jaccard(array $a, array $b): float {
        $a = array_filter($a, fn($w) => mb_strlen($w) > 3);
        $b = array_filter($b, fn($w) => mb_strlen($w) > 3);
        if (empty($a) || empty($b)) return 0.0;
        $intersection = count(array_intersect($a, $b));
        $union        = count(array_unique(array_merge($a, $b)));
        return $union > 0 ? round($intersection / $union, 2) : 0.0;
    }

    // ── estimateEffort() ─────────────────────────────────────────
    private static function estimateEffort(string $type, string $service, string $desc): array {
        $words = str_word_count($desc);
        if ($type === 'positive') return ['low', 0];
        if ($type === 'bug') return ['medium', rand(4, 16)];
        if ($words < 30) return ['low',   rand(2,  8)];
        if ($words < 80) return ['medium',rand(8,  40)];
        return ['high', rand(40, 200)];
    }

    // ── estimateRevenue() ────────────────────────────────────────
    private static function estimateRevenue(string $type, string $service, int $votes): string {
        if ($type === 'positive') return 'none';
        if (in_array($service, ['payment','billing','wallet'])) return 'high';
        if ($votes > 50) return 'medium';
        if ($type === 'new_service') return 'medium';
        return 'low';
    }

    // ── estimateAffected() ───────────────────────────────────────
    private static function estimateAffected(string $service, int $votes): int {
        $base = match($service) {
            'medical'   => 500,
            'platform'  => 1000,
            'payment'   => 800,
            'community' => 600,
            default     => 200,
        };
        return (int)($base + ($votes * 10));
    }

    // ── buildRecommendation() ────────────────────────────────────
    private static function buildRecommendation(
        string $priority, string $type, string $effort, int $affected
    ): string {
        if ($priority === 'duplicate')    return 'merge_with_existing';
        if ($priority === 'out_of_scope') return 'reject';
        if ($type === 'bug')              return 'fix_immediately';
        if ($priority === 'urgent')       return 'implement_next_sprint';
        if ($priority === 'high')         return 'implement_q_plan';
        if ($effort === 'low')            return 'quick_win';
        return 'add_to_backlog';
    }

    // ── generateSummary(): AI ملخص ───────────────────────────────
    private static function generateSummary(array $suggestion, array $analysis): string {
        $prompt = "اكتب ملخصاً تنفيذياً موجزاً (3 جمل بالعربية) لهذا الاقتراح:"
            . "\nالنوع: {$suggestion['type']}"
            . "\nالخدمة: {$suggestion['service']}"
            . "\nالوصف: " . mb_substr($suggestion['description'] ?? '', 0, 200)
            . "\n\nحدد: المشكلة + الحل المقترح + الأثر المتوقع."
            . "\nالأولوية: {$analysis['priority']} | المتأثرون: ~{$analysis['affected']} مستخدم";

        $summary = '';
        try {
            // P2 FIX: Route through UsageMeter for billing visibility (skip_debit=true: platform cost)
            // Previously used raw ask_gemini() — bypassed ai_usage logging and cost tracking
            require_once __DIR__ . '/UsageMeter.php';
            require_once __DIR__ . '/AIClient.php';
            $sysPrompt = 'أنت محلل منتجات متخصص. اكتب تحليلاً موجزاً ومفيداً.';
            $metered = UsageMeter::wrap(
                0,            // platform user id (system call, no specific user)
                'analysis',   // event type
                'platform',   // service
                fn() => AIClient::call($prompt, $sysPrompt, ['max_tokens' => 300]),
                ['skip_debit' => true]  // platform bears the cost, no user debit
            );
            $summary = $metered['text'] ?? '';
        } catch (Throwable $e) {}

        if (!$summary) {
            // Fallback: structured summary
            $typeMap = ['improvement'=>'تحسين','bug'=>'مشكلة','solution'=>'حل','new_service'=>'خدمة جديدة','positive'=>'تقييم إيجابي'];
            $summary = "المستخدم يقترح " . ($typeMap[$suggestion['type']] ?? 'تحسين')
                . " في خدمة " . ($suggestion['service'] ?? 'المنصة') . ". "
                . "الأثر المتوقع: ~{$analysis['affected']} مستخدم. "
                . "التوصية: " . $analysis['priority'] . ".";
        }
        return $summary;
    }

    // ── categorize() ─────────────────────────────────────────────
    private static function categorize(string $type, string $service): string {
        if ($type === 'bug') return "bug/{$service}";
        if ($type === 'positive') return "testimonial/{$service}";
        return "feature/{$service}";
    }

    // ── generateRef() ────────────────────────────────────────────
    public static function generateRef(): string {
        return 'SUG-' . strtoupper(substr(md5(uniqid()), 0, 6));
    }

    // ── awardPoints(): منح نقاط الإنجاز ─────────────────────────
    public static function awardPoints(int $userId, string $event): void {
        $pts = ['suggestion_submitted' => 10, 'suggestion_accepted' => 50, 'suggestion_implemented' => 200];
        $points = $pts[$event] ?? 0;
        if ($points > 0 && $userId > 0) {
            try {
                db()->prepare("UPDATE users SET achievement_points=COALESCE(achievement_points,0)+? WHERE id=?")
                   ->execute([$points, $userId]);
            } catch (Throwable $e) {}
        }
    }
}
