<?php
/**
 * Access Control System
 * Version: 2.0
 * PHP: 7.4+
 */

declare(strict_types=1);

class AccessControl {
    private static ?AccessControl $instance = null;
    private SubscriptionManager $subManager;
    private Telegram $telegram;
    
    private function __construct() {
        $this->subManager = SubscriptionManager::getInstance();
        $this->telegram = Telegram::getInstance();
    }
    
    public static function getInstance(): AccessControl {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Check if user has access to feature
     */
    public function hasAccess(int $userId, string $feature): bool {
        // Admins always have access
        if (in_array($userId, ADMIN_IDS)) {
            return true;
        }
        
        // If subscription is not required, everyone has access
        if (!SUBSCRIPTION_REQUIRED) {
            return true;
        }
        
        // Check if feature requires subscription
        $features = SUBSCRIPTION_FEATURES;
        if (!isset($features[$feature]) || !$features[$feature]) {
            return true; // Feature doesn't require subscription
        }
        
        // Check free trial
        if (FREE_TRIAL_DAYS > 0 && $this->isInFreeTrial($userId)) {
            return true;
        }
        
        // Check active subscription
        return $this->subManager->hasActiveSubscription($userId);
    }
    
    /**
     * Check if user is in free trial period
     */
    public function isInFreeTrial(int $userId): bool {
        if (FREE_TRIAL_DAYS <= 0) {
            return false;
        }
        
        $db = Database::getInstance();
        $user = $db->fetchOne(
            "SELECT joined_at FROM `members` WHERE id = ?",
            [$userId]
        );
        
        if (!$user) {
            return false;
        }
        
        $joinedTime = strtotime($user['joined_at']);
        $trialEndTime = $joinedTime + (FREE_TRIAL_DAYS * 86400);
        
        return time() < $trialEndTime;
    }
    
    /**
     * Get remaining trial days
     */
    public function getRemainingTrialDays(int $userId): int {
        if (FREE_TRIAL_DAYS <= 0) {
            return 0;
        }
        
        $db = Database::getInstance();
        $user = $db->fetchOne(
            "SELECT joined_at FROM `members` WHERE id = ?",
            [$userId]
        );
        
        if (!$user) {
            return 0;
        }
        
        $joinedTime = strtotime($user['joined_at']);
        $trialEndTime = $joinedTime + (FREE_TRIAL_DAYS * 86400);
        $remainingSeconds = $trialEndTime - time();
        
        if ($remainingSeconds <= 0) {
            return 0;
        }
        
        return (int)ceil($remainingSeconds / 86400);
    }
    
    /**
     * Require subscription for feature
     */
    public function requireSubscription(int $userId, int $chatId, string $feature): bool {
        if ($this->hasAccess($userId, $feature)) {
            return true;
        }
        
        // User doesn't have access
        $this->sendAccessDeniedMessage($userId, $chatId, $feature);
        return false;
    }
    
    /**
     * Send access denied message
     */
    private function sendAccessDeniedMessage(int $userId, int $chatId, string $feature): void {
        $featureNames = [
            'ai_chat' => 'چت با هوش مصنوعی',
            'ai_advanced' => 'قابلیت‌های پیشرفته AI',
            'plugins' => 'پلاگین‌ها',
            'broadcast' => 'ارسال همگانی'
        ];
        
        $featureName = $featureNames[$feature] ?? 'این قابلیت';
        
        // Check if in trial
        if (FREE_TRIAL_DAYS > 0) {
            $remainingDays = $this->getRemainingTrialDays($userId);
            
            if ($remainingDays > 0) {
                $message = "✅ شما در دوره آزمایشی هستید!\n\n" .
                           "⏳ روزهای باقیمانده: {$remainingDays} روز\n\n" .
                           "بعد از اتمام دوره آزمایشی، برای استفاده از {$featureName} نیاز به اشتراک دارید.";
            } else {
                $message = "⚠️ *دوره آزمایشی شما به پایان رسید!*\n\n" .
                           "برای استفاده از {$featureName} نیاز به خرید اشتراک دارید.\n\n" .
                           "💎 مشاهده پلن‌ها: /subscribe";
            }
        } else {
            $message = "⚠️ *نیاز به اشتراک*\n\n" .
                       "برای استفاده از {$featureName} نیاز به اشتراک فعال دارید.\n\n" .
                       "💎 مشاهده پلن‌ها: /subscribe\n" .
                       "📊 اشتراک من: /mysubscription";
        }
        
        $keyboard = [
            'inline_keyboard' => [
                [['text' => '💎 خرید اشتراک', 'callback_data' => 'back_to_plans']],
                [['text' => '📊 اشتراک من', 'callback_data' => 'my_subscription']]
            ]
        ];
        
        $this->telegram->sendMessage($chatId, $message, 'Markdown', $keyboard);
    }
    
    /**
     * Get access status for user
     */
    public function getAccessStatus(int $userId): array {
        $status = [
            'has_subscription' => false,
            'in_trial' => false,
            'trial_days_left' => 0,
            'subscription_end' => null,
            'is_admin' => false
        ];
        
        // Check admin
        if (in_array($userId, ADMIN_IDS)) {
            $status['is_admin'] = true;
            return $status;
        }
        
        // Check subscription
        $subscription = $this->subManager->getUserSubscription($userId);
        if ($subscription) {
            $status['has_subscription'] = true;
            $status['subscription_end'] = $subscription['end_date'];
        }
        
        // Check trial
        if (FREE_TRIAL_DAYS > 0) {
            $remainingDays = $this->getRemainingTrialDays($userId);
            if ($remainingDays > 0) {
                $status['in_trial'] = true;
                $status['trial_days_left'] = $remainingDays;
            }
        }
        
        return $status;
    }
    
    /**
     * Check if bot is in subscription mode
     */
    public static function isSubscriptionMode(): bool {
        return SUBSCRIPTION_REQUIRED;
    }
    
    /**
     * Get feature list with access status
     */
    public function getFeatureAccess(int $userId): array {
        $features = SUBSCRIPTION_FEATURES;
        $access = [];
        
        foreach ($features as $feature => $requiresSub) {
            $access[$feature] = [
                'requires_subscription' => $requiresSub,
                'has_access' => $this->hasAccess($userId, $feature)
            ];
        }
        
        return $access;
    }
}
