<?php
/**
 * Helper Functions
 * Utility functions for the bot
 */

class Helpers {
    private static $db = null;

    /**
     * Generate unique order ID
     */
    public static function generateOrderId() {
        return 'ORD-' . strtoupper(substr(uniqid(), -6)) . '-' . date('Ymd');
    }

    /**
     * Generate unique ticket ID
     */
    public static function generateTicketId() {
        return 'TKT-' . strtoupper(substr(uniqid(), -6)) . '-' . date('Ymd');
    }

    /**
     * Generate reseller code
     */
    public static function generateResellerCode($name) {
        $prefix = strtoupper(substr(preg_replace('/[^a-zA-Z]/', '', $name), 0, 4));
        $suffix = strtoupper(substr(uniqid(), -4));
        return $prefix . $suffix;
    }

    /**
     * Format price in INR
     */
    public static function formatPrice($price) {
        return '₹' . number_format($price, 2);
    }

    /**
     * Format date
     */
    public static function formatDate($date, $format = 'd M Y, h:i A') {
        if (empty($date)) return 'N/A';
        return date($format, strtotime($date));
    }

    /**
     * Truncate text
     */
    public static function truncate($text, $length = 100) {
        if (strlen($text) <= $length) return $text;
        return substr($text, 0, $length) . '...';
    }

    /**
     * Escape HTML
     */
    public static function e($text) {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }

    /**
     * Get database instance
     */
    public static function db() {
        if (self::$db === null) {
            self::$db = Database::getInstance();
        }
        return self::$db;
    }

    /**
     * Log activity
     */
    public static function log($type, $message, $data = []) {
        $logFile = LOGS_PATH . date('Y-m-d') . '_' . $type . '.log';
        $timestamp = date('Y-m-d H:i:s');
        $logEntry = "[{$timestamp}] {$message}";

        if (!empty($data)) {
            $logEntry .= " | Data: " . json_encode($data);
        }

        $logEntry .= "
";
        file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
    }

    /**
     * Send notification to admin
     */
    public static function notifyAdmin($message) {
        $telegram = new Telegram();
        return $telegram->sendMessage(ADMIN_TELEGRAM_ID, $message);
    }

    /**
     * Check if user is admin
     */
    public static function isAdmin($userId) {
        $user = self::db()->fetch(
            "SELECT is_admin FROM users WHERE telegram_id = ?",
            [$userId],
            'i'
        );
        return $user && $user['is_admin'] == 1;
    }

    /**
     * Check if user is reseller
     */
    public static function isReseller($userId) {
        $user = self::db()->fetch(
            "SELECT is_reseller FROM users WHERE telegram_id = ?",
            [$userId],
            'i'
        );
        return $user && $user['is_reseller'] == 1;
    }

    /**
     * Get or create user
     */
    public static function getOrCreateUser($telegramUser) {
        $db = self::db();

        $existing = $db->fetch(
            "SELECT * FROM users WHERE telegram_id = ?",
            [$telegramUser['id']],
            'i'
        );

        if ($existing) {
            // Update last activity
            $db->update('users', 
                ['last_activity' => date('Y-m-d H:i:s')],
                'telegram_id = ?',
                [$telegramUser['id']]
            );
            return $existing;
        }

        // Create new user
        $userData = [
            'telegram_id' => $telegramUser['id'],
            'username' => $telegramUser['username'] ?? null,
            'first_name' => $telegramUser['first_name'] ?? null,
            'last_name' => $telegramUser['last_name'] ?? null,
            'joined_at' => date('Y-m-d H:i:s'),
            'last_activity' => date('Y-m-d H:i:s')
        ];

        $db->insert('users', $userData);

        // Check if referred
        if (isset($telegramUser['start_param']) && !empty($telegramUser['start_param'])) {
            self::processReferral($telegramUser['id'], $telegramUser['start_param']);
        }

        // Notify admin
        self::notifyAdmin("🆕 <b>New User!</b>
👤 Name: " . ($userData['first_name'] ?? 'Unknown') . "
🆔 ID: {$telegramUser['id']}
📅 Joined: " . date('d M Y h:i A'));

        return $db->fetch(
            "SELECT * FROM users WHERE telegram_id = ?",
            [$telegramUser['id']],
            'i'
        );
    }

    /**
     * Process referral
     */
    public static function processReferral($newUserId, $referralCode) {
        $db = self::db();

        $referrer = $db->fetch(
            "SELECT telegram_id FROM users WHERE reseller_code = ?",
            [$referralCode],
            's'
        );

        if ($referrer) {
            // Update referred_by
            $db->update('users',
                ['referred_by' => $referrer['telegram_id']],
                'telegram_id = ?',
                [$newUserId]
            );

            // Add referral bonus to referrer
            $db->execute(
                "UPDATE users SET balance = balance + ?, total_spent = total_spent + ? WHERE telegram_id = ?",
                [REFERRAL_BONUS, REFERRAL_BONUS, $referrer['telegram_id']],
                'ddi'
            );

            // Log transaction
            $db->insert('transactions', [
                'user_id' => $referrer['telegram_id'],
                'type' => 'deposit',
                'amount' => REFERRAL_BONUS,
                'description' => 'Referral bonus for user ' . $newUserId,
                'reference_id' => $referralCode,
                'status' => 'completed'
            ]);

            // Notify referrer
            $telegram = new Telegram();
            $telegram->sendMessage(
                $referrer['telegram_id'],
                "🎉 <b>Referral Bonus!</b>

Someone joined using your code!
💰 You earned " . self::formatPrice(REFERRAL_BONUS) . "
👥 Keep sharing your reseller code!"
            );
        }
    }

    /**
     * Get user stats
     */
    public static function getUserStats($userId) {
        $db = self::db();

        $stats = [];

        // Total orders
        $orders = $db->fetch(
            "SELECT COUNT(*) as count, SUM(total_price) as total FROM orders WHERE user_id = ? AND order_status != 'cancelled'",
            [$userId],
            'i'
        );
        $stats['total_orders'] = $orders['count'] ?? 0;
        $stats['total_spent'] = $orders['total'] ?? 0;

        // Referral count
        $referrals = $db->fetch(
            "SELECT COUNT(*) as count FROM users WHERE referred_by = ?",
            [$userId],
            'i'
        );
        $stats['referrals'] = $referrals['count'] ?? 0;

        // Commission earned
        $commission = $db->fetch(
            "SELECT SUM(amount) as total FROM commissions WHERE reseller_id = ? AND status = 'approved'",
            [$userId],
            'i'
        );
        $stats['commission_earned'] = $commission['total'] ?? 0;

        // Open tickets
        $tickets = $db->fetch(
            "SELECT COUNT(*) as count FROM tickets WHERE user_id = ? AND status IN ('open', 'in_progress')",
            [$userId],
            'i'
        );
        $stats['open_tickets'] = $tickets['count'] ?? 0;

        return $stats;
    }

    /**
     * Validate coupon
     */
    public static function validateCoupon($code, $orderAmount = 0) {
        $db = self::db();

        $coupon = $db->fetch(
            "SELECT * FROM coupons WHERE code = ? AND status = 'active' AND (valid_until IS NULL OR valid_until > NOW())",
            [$code],
            's'
        );

        if (!$coupon) {
            return ['valid' => false, 'error' => 'Invalid or expired coupon'];
        }

        if ($coupon['max_uses'] !== null && $coupon['used_count'] >= $coupon['max_uses']) {
            return ['valid' => false, 'error' => 'Coupon usage limit reached'];
        }

        if ($orderAmount < $coupon['min_order_amount']) {
            return ['valid' => false, 'error' => 'Minimum order amount is ' . self::formatPrice($coupon['min_order_amount'])];
        }

        $discount = 0;
        if ($coupon['discount_type'] == 'percentage') {
            $discount = $orderAmount * ($coupon['discount_value'] / 100);
        } else {
            $discount = $coupon['discount_value'];
        }

        return [
            'valid' => true,
            'discount' => $discount,
            'coupon' => $coupon
        ];
    }

    /**
     * Rate limit check
     */
    public static function checkRateLimit($userId, $action = 'default') {
        $key = "rate_limit_{$action}_{$userId}";
        $file = sys_get_temp_dir() . '/' . md5($key) . '.txt';

        $now = time();
        $requests = [];

        if (file_exists($file)) {
            $requests = json_decode(file_get_contents($file), true) ?: [];
        }

        // Remove old requests (older than 1 minute)
        $requests = array_filter($requests, function($time) use ($now) {
            return ($now - $time) < 60;
        });

        if (count($requests) >= RATE_LIMIT_REQUESTS) {
            return false;
        }

        $requests[] = $now;
        file_put_contents($file, json_encode($requests));

        return true;
    }

    /**
     * Mask sensitive data
     */
    public static function maskEmail($email) {
        if (empty($email) || !strpos($email, '@')) return '***';
        list($local, $domain) = explode('@', $email);
        $maskedLocal = substr($local, 0, 2) . str_repeat('*', max(0, strlen($local) - 2));
        return $maskedLocal . '@' . $domain;
    }

    /**
     * Mask phone
     */
    public static function maskPhone($phone) {
        if (empty($phone)) return '***';
        $len = strlen($phone);
        if ($len <= 4) return '***';
        return str_repeat('*', $len - 4) . substr($phone, -4);
    }

    /**
     * Generate UPI payment link
     */
    public static function generateUPILink($amount, $note, $upiId = UPI_ID) {
        $encodedNote = urlencode($note);
        return "upi://pay?pa={$upiId}&pn=Team%20Hydra%20Shop&am={$amount}&cu=INR&tn={$encodedNote}";
    }

    /**
     * Get setting value
     */
    public static function getSetting($key, $default = '') {
        $setting = self::db()->fetch(
            "SELECT setting_value FROM settings WHERE setting_key = ?",
            [$key],
            's'
        );
        return $setting ? $setting['setting_value'] : $default;
    }

    /**
     * Update setting
     */
    public static function updateSetting($key, $value) {
        $db = self::db();
        $existing = $db->fetch(
            "SELECT id FROM settings WHERE setting_key = ?",
            [$key],
            's'
        );

        if ($existing) {
            return $db->update('settings', ['setting_value' => $value], 'setting_key = ?', [$key]);
        } else {
            return $db->insert('settings', [
                'setting_key' => $key,
                'setting_value' => $value
            ]);
        }
    }

    /**
     * Get bot statistics
     */
    public static function getBotStats() {
        $db = self::db();

        $stats = [];

        $users = $db->fetch("SELECT COUNT(*) as total, COUNT(CASE WHEN DATE(created_at) = CURDATE() THEN 1 END) as today FROM users");
        $stats['total_users'] = $users['total'] ?? 0;
        $stats['new_users_today'] = $users['today'] ?? 0;

        $orders = $db->fetch("SELECT COUNT(*) as total, SUM(total_price) as revenue, COUNT(CASE WHEN DATE(created_at) = CURDATE() THEN 1 END) as today FROM orders WHERE order_status != 'cancelled'");
        $stats['total_orders'] = $orders['total'] ?? 0;
        $stats['total_revenue'] = $orders['revenue'] ?? 0;
        $stats['orders_today'] = $orders['today'] ?? 0;

        $tickets = $db->fetch("SELECT COUNT(*) as open FROM tickets WHERE status IN ('open', 'in_progress')");
        $stats['open_tickets'] = $tickets['open'] ?? 0;

        $resellers = $db->fetch("SELECT COUNT(*) as total FROM users WHERE is_reseller = 1");
        $stats['total_resellers'] = $resellers['total'] ?? 0;

        return $stats;
    }
}
