<?php
/**
 * Gamification Service — Badges & Points
 * 
 * Awards points and badges based on user actions.
 * Call GamificationService::award() from relevant endpoints.
 */

declare(strict_types=1);

namespace App\Services;

use App\Core\Database;

class GamificationService
{
    // Points per action
    private const POINTS = [
        'invoice_uploaded'    => 5,
        'invoice_approved'    => 10,
        'jofotara_submitted'  => 15,
        'company_created'     => 20,
        'referral_registered' => 50,
        'first_login'         => 10,
        'streak_7_days'       => 30,
        'streak_30_days'      => 100,
    ];

    // Badge definitions
    private const BADGES = [
        'starter'        => ['name' => 'بداية موفقة', 'icon' => '🌟', 'desc' => 'رفعت أول فاتورة', 'condition' => 'invoices >= 1'],
        'active_10'      => ['name' => 'نشيط', 'icon' => '🔥', 'desc' => '10 فواتير مرفوعة', 'condition' => 'invoices >= 10'],
        'pro_50'         => ['name' => 'محترف', 'icon' => '💎', 'desc' => '50 فاتورة مرفوعة', 'condition' => 'invoices >= 50'],
        'master_200'     => ['name' => 'خبير فوترة', 'icon' => '👑', 'desc' => '200 فاتورة مرفوعة', 'condition' => 'invoices >= 200'],
        'jofotara_first' => ['name' => 'رسمي', 'icon' => '🏛️', 'desc' => 'أول إرسال لجوفوترا', 'condition' => 'submitted >= 1'],
        'jofotara_50'    => ['name' => 'فوترة ذهبية', 'icon' => '🏆', 'desc' => '50 فاتورة مرسلة لجوفوترا', 'condition' => 'submitted >= 50'],
        'multi_company'  => ['name' => 'مدير شركات', 'icon' => '🏢', 'desc' => 'تدير 3 شركات أو أكثر', 'condition' => 'companies >= 3'],
        'referrer'       => ['name' => 'سفير مُصادَق', 'icon' => '🤝', 'desc' => 'أحلت مستخدم جديد', 'condition' => 'referrals >= 1'],
        'streak_week'    => ['name' => 'مثابر', 'icon' => '📅', 'desc' => 'دخلت 7 أيام متتالية', 'condition' => 'streak >= 7'],
    ];

    /**
     * Award points for an action
     */
    public static function award(string $userId, string $tenantId, string $action): void
    {
        try {
            $points = self::POINTS[$action] ?? 0;
            if ($points === 0) return;

            $db = Database::getInstance();

            // Add points
            $db->prepare("
                INSERT INTO user_points (id, user_id, tenant_id, action, points, created_at)
                VALUES (UUID(), ?, ?, ?, ?, NOW())
            ")->execute([$userId, $tenantId, $action, $points]);

            // Check for new badges
            self::checkBadges($userId, $tenantId);

        } catch (\Throwable $e) {
            error_log("[Gamification] Award failed: " . $e->getMessage());
        }
    }

    /**
     * Check and award any earned badges
     */
    private static function checkBadges(string $userId, string $tenantId): void
    {
        $db = Database::getInstance();

        // Get user stats
        $invoices = (int)$db->prepare("SELECT COUNT(*) FROM invoices WHERE tenant_id = ?")->execute([$tenantId])?->fetchColumn() ?: 0;
        $submitted = (int)$db->prepare("SELECT COUNT(*) FROM invoices WHERE tenant_id = ? AND status = 'submitted'")->execute([$tenantId])?->fetchColumn() ?: 0;
        $companies = (int)$db->prepare("SELECT COUNT(*) FROM companies WHERE tenant_id = ? AND deleted_at IS NULL")->execute([$tenantId])?->fetchColumn() ?: 0;
        $referrals = (int)$db->prepare("SELECT COUNT(*) FROM referrals WHERE referrer_id = ?")->execute([$userId])?->fetchColumn() ?: 0;

        // Get existing badges
        $existingStmt = $db->prepare("SELECT badge_key FROM user_badges WHERE user_id = ?");
        $existingStmt->execute([$userId]);
        $existing = $existingStmt->fetchAll(\PDO::FETCH_COLUMN);

        $stats = compact('invoices', 'submitted', 'companies', 'referrals');

        foreach (self::BADGES as $key => $badge) {
            if (in_array($key, $existing)) continue;

            if (self::evaluateCondition($badge['condition'], $stats)) {
                $db->prepare("
                    INSERT INTO user_badges (id, user_id, tenant_id, badge_key, badge_name, badge_icon, earned_at)
                    VALUES (UUID(), ?, ?, ?, ?, ?, NOW())
                ")->execute([$userId, $tenantId, $key, $badge['name'], $badge['icon']]);

                // Notify user
                SmartNotifications::send($tenantId, $userId, 'badge_earned',
                    "{$badge['icon']} شارة جديدة: {$badge['name']}!",
                    $badge['desc'],
                    ['badge_key' => $key]
                );
            }
        }
    }

    /**
     * Simple condition evaluator
     */
    private static function evaluateCondition(string $condition, array $stats): bool
    {
        if (preg_match('/(\w+)\s*>=\s*(\d+)/', $condition, $m)) {
            $field = $m[1];
            $value = (int)$m[2];
            return ($stats[$field] ?? 0) >= $value;
        }
        return false;
    }

    /**
     * Get user's gamification profile
     */
    public static function getProfile(string $userId, string $tenantId): array
    {
        $db = Database::getInstance();

        // Total points
        $pointsStmt = $db->prepare("SELECT COALESCE(SUM(points), 0) FROM user_points WHERE user_id = ?");
        $pointsStmt->execute([$userId]);
        $totalPoints = (int)$pointsStmt->fetchColumn();

        // Badges
        $badgesStmt = $db->prepare("SELECT badge_key, badge_name, badge_icon, earned_at FROM user_badges WHERE user_id = ? ORDER BY earned_at DESC");
        $badgesStmt->execute([$userId]);
        $badges = $badgesStmt->fetchAll();

        // Level (every 100 points = 1 level)
        $level = max(1, (int)floor($totalPoints / 100) + 1);
        $levelNames = ['', 'مبتدئ', 'ناشط', 'متقدم', 'خبير', 'أسطورة', 'سيد الفوترة'];
        $levelName = $levelNames[min($level, count($levelNames) - 1)] ?? 'أسطورة';

        // Progress to next level
        $pointsInLevel = $totalPoints % 100;
        $progressPercent = $pointsInLevel;

        return [
            'total_points'     => $totalPoints,
            'level'            => $level,
            'level_name'       => $levelName,
            'progress_percent' => $progressPercent,
            'badges'           => $badges,
            'badges_count'     => count($badges),
            'available_badges' => count(self::BADGES),
        ];
    }
}
