<?php
require_once '../config/database.php';
require_once '../config/config.php';
require_once 'functions.php';

class AdminFunctions {
    private $db;
    private $functions;

    public function __construct() {
        global $functions;
        $this->functions = $functions;
        $this->db = Database::getInstance()->getConnection();
    }

    // ============ DASHBOARD STATISTICS ============

    // Get dashboard statistics
    public function getDashboardStats() {
        $stats = [];

        // User statistics
        $stats['total_users'] = $this->getTotalUsers();
        $stats['active_users'] = $this->getActiveUsers();
        $stats['new_users_today'] = $this->getNewUsersToday();
        $stats['verified_users'] = $this->getVerifiedUsers();

        // Investment statistics
        $stats['total_investments'] = $this->getTotalInvestments();
        $stats['active_investments'] = $this->getActiveInvestments();
        $stats['total_investment_amount'] = $this->getTotalInvestmentAmount();
        $stats['today_investments'] = $this->getTodayInvestments();

        // Transaction statistics
        $stats['total_deposits'] = $this->getTotalDeposits();
        $stats['total_withdrawals'] = $this->getTotalWithdrawals();
        $stats['pending_withdrawals'] = $this->getPendingWithdrawals();
        $stats['today_transactions'] = $this->getTodayTransactions();

        // Financial statistics
        $stats['total_platform_balance'] = $this->getTotalPlatformBalance();
        $stats['monthly_revenue'] = $this->getMonthlyRevenue();
        $stats['total_profits_paid'] = $this->getTotalProfitsPaid();

        // Support statistics
        $stats['open_tickets'] = $this->getOpenTickets();
        $stats['pending_kyc'] = $this->getPendingKYC();

        return $stats;
    }

    // User statistics
    private function getTotalUsers() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM users");
        return $stmt->fetch()['count'];
    }

    private function getActiveUsers() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM users WHERE account_status = 'active'");
        return $stmt->fetch()['count'];
    }

    private function getNewUsersToday() {
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM users WHERE DATE(created_at) = CURDATE()");
        $stmt->execute();
        return $stmt->fetch()['count'];
    }

    private function getVerifiedUsers() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM users WHERE kyc_status = 'verified'");
        return $stmt->fetch()['count'];
    }

    // Investment statistics
    private function getTotalInvestments() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM investments");
        return $stmt->fetch()['count'];
    }

    private function getActiveInvestments() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM investments WHERE status = 'running'");
        return $stmt->fetch()['count'];
    }

    private function getTotalInvestmentAmount() {
        $stmt = $this->db->query("SELECT SUM(amount) as total FROM investments");
        return $stmt->fetch()['total'] ?? 0;
    }

    private function getTodayInvestments() {
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM investments WHERE DATE(created_at) = CURDATE()");
        $stmt->execute();
        return $stmt->fetch()['count'];
    }

    // Transaction statistics
    private function getTotalDeposits() {
        $stmt = $this->db->query("SELECT SUM(amount) as total FROM transactions WHERE type = 'deposit' AND status = 'completed'");
        return $stmt->fetch()['total'] ?? 0;
    }

    private function getTotalWithdrawals() {
        $stmt = $this->db->query("SELECT SUM(amount) as total FROM transactions WHERE type = 'withdrawal' AND status = 'completed'");
        return $stmt->fetch()['total'] ?? 0;
    }

    private function getPendingWithdrawals() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM transactions WHERE type = 'withdrawal' AND status = 'pending'");
        return $stmt->fetch()['count'];
    }

    private function getTodayTransactions() {
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM transactions WHERE DATE(created_at) = CURDATE()");
        $stmt->execute();
        return $stmt->fetch()['count'];
    }

    // Financial statistics
    private function getTotalPlatformBalance() {
        $stmt = $this->db->query("SELECT SUM(balance) as total FROM users");
        return $stmt->fetch()['total'] ?? 0;
    }

    private function getMonthlyRevenue() {
        $stmt = $this->db->prepare("
            SELECT SUM(amount) as total
            FROM transactions
            WHERE type = 'deposit'
            AND status = 'completed'
            AND YEAR(created_at) = YEAR(CURDATE())
            AND MONTH(created_at) = MONTH(CURDATE())
        ");
        $stmt->execute();
        return $stmt->fetch()['total'] ?? 0;
    }

    private function getTotalProfitsPaid() {
        $stmt = $this->db->query("SELECT SUM(amount) as total FROM transactions WHERE type = 'profit' AND status = 'completed'");
        return $stmt->fetch()['total'] ?? 0;
    }

    // Support statistics
    private function getOpenTickets() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM support_tickets WHERE status = 'open'");
        return $stmt->fetch()['count'];
    }

    private function getPendingKYC() {
        $stmt = $this->db->query("SELECT COUNT(*) as count FROM users WHERE kyc_status = 'pending'");
        return $stmt->fetch()['count'];
    }

    // ============ USER MANAGEMENT ============

    // Get users with pagination and filters
    public function getUsers($page = 1, $limit = 20, $filters = []) {
        $offset = ($page - 1) * $limit;
        $where = "WHERE 1=1";
        $params = [];

        // Apply filters
        if (!empty($filters['status'])) {
            $where .= " AND account_status = ?";
            $params[] = $filters['status'];
        }

        if (!empty($filters['kyc_status'])) {
            $where .= " AND kyc_status = ?";
            $params[] = $filters['kyc_status'];
        }

        if (!empty($filters['search'])) {
            $where .= " AND (username LIKE ? OR email LIKE ? OR full_name LIKE ?)";
            $search = "%{$filters['search']}%";
            $params[] = $search;
            $params[] = $search;
            $params[] = $search;
        }

        // Get total count
        $count_stmt = $this->db->prepare("SELECT COUNT(*) as total FROM users $where");
        $count_stmt->execute($params);
        $total = $count_stmt->fetch()['total'];

        // Get users
        $sql = "
            SELECT
                u.*,
                (SELECT COUNT(*) FROM investments WHERE user_id = u.id) as total_investments,
                (SELECT SUM(amount) FROM investments WHERE user_id = u.id) as total_invested,
                (SELECT SUM(amount) FROM transactions WHERE user_id = u.id AND type = 'profit' AND status = 'completed') as total_profits,
                (SELECT COUNT(*) FROM support_tickets WHERE user_id = u.id) as total_tickets
            FROM users u
            $where
            ORDER BY u.created_at DESC
            LIMIT ? OFFSET ?
        ";

        $params[] = $limit;
        $params[] = $offset;

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $users = $stmt->fetchAll();

        return [
            'users' => $users,
            'total' => $total,
            'pages' => ceil($total / $limit),
            'current_page' => $page
        ];
    }

    // Update user status
    public function updateUserStatus($user_id, $status) {
        $valid_statuses = ['active', 'inactive', 'suspended', 'banned'];
        if (!in_array($status, $valid_statuses)) {
            return ['success' => false, 'message' => 'Invalid status'];
        }

        $stmt = $this->db->prepare("UPDATE users SET account_status = ?, updated_at = NOW() WHERE id = ?");
        $result = $stmt->execute([$status, $user_id]);

        if ($result) {
            // Log the action
            $this->logAdminAction($_SESSION['admin_id'], 'update_user_status', "Updated user $user_id status to $status");
            return ['success' => true, 'message' => 'User status updated successfully'];
        }

        return ['success' => false, 'message' => 'Failed to update user status'];
    }

    // Update user KYC status
    public function updateUserKYC($user_id, $status, $notes = '') {
        $valid_statuses = ['pending', 'verified', 'rejected'];
        if (!in_array($status, $valid_statuses)) {
            return ['success' => false, 'message' => 'Invalid KYC status'];
        }

        $stmt = $this->db->prepare("UPDATE users SET kyc_status = ?, kyc_notes = ?, kyc_verified_at = NOW(), updated_at = NOW() WHERE id = ?");
        $result = $stmt->execute([$status, $notes, $user_id]);

        if ($result) {
            // Log the action
            $this->logAdminAction($_SESSION['admin_id'], 'update_user_kyc', "Updated user $user_id KYC status to $status");
            return ['success' => true, 'message' => 'User KYC status updated successfully'];
        }

        return ['success' => false, 'message' => 'Failed to update user KYC status'];
    }

    // ============ INVESTMENT MANAGEMENT ============

    // Get investments with pagination and filters
    public function getInvestments($page = 1, $limit = 20, $filters = []) {
        $offset = ($page - 1) * $limit;
        $where = "WHERE 1=1";
        $params = [];

        // Apply filters
        if (!empty($filters['status'])) {
            $where .= " AND i.status = ?";
            $params[] = $filters['status'];
        }

        if (!empty($filters['plan_id'])) {
            $where .= " AND i.plan_id = ?";
            $params[] = $filters['plan_id'];
        }

        if (!empty($filters['user_id'])) {
            $where .= " AND i.user_id = ?";
            $params[] = $filters['user_id'];
        }

        if (!empty($filters['date_from'])) {
            $where .= " AND DATE(i.created_at) >= ?";
            $params[] = $filters['date_from'];
        }

        if (!empty($filters['date_to'])) {
            $where .= " AND DATE(i.created_at) <= ?";
            $params[] = $filters['date_to'];
        }

        // Get total count
        $count_stmt = $this->db->prepare("SELECT COUNT(*) as total FROM investments i $where");
        $count_stmt->execute($params);
        $total = $count_stmt->fetch()['total'];

        // Get investments
        $sql = "
            SELECT
                i.*,
                u.username,
                u.email,
                p.name as plan_name,
                p.daily_return,
                p.duration_days
            FROM investments i
            JOIN users u ON i.user_id = u.id
            JOIN investment_plans p ON i.plan_id = p.id
            $where
            ORDER BY i.created_at DESC
            LIMIT ? OFFSET ?
        ";

        $params[] = $limit;
        $params[] = $offset;

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $investments = $stmt->fetchAll();

        return [
            'investments' => $investments,
            'total' => $total,
            'pages' => ceil($total / $limit),
            'current_page' => $page
        ];
    }

    // ============ TRANSACTION MANAGEMENT ============

    // Get transactions with pagination and filters
    public function getTransactions($page = 1, $limit = 20, $filters = []) {
        $offset = ($page - 1) * $limit;
        $where = "WHERE 1=1";
        $params = [];

        // Apply filters
        if (!empty($filters['type'])) {
            $where .= " AND t.type = ?";
            $params[] = $filters['type'];
        }

        if (!empty($filters['status'])) {
            $where .= " AND t.status = ?";
            $params[] = $filters['status'];
        }

        if (!empty($filters['user_id'])) {
            $where .= " AND t.user_id = ?";
            $params[] = $filters['user_id'];
        }

        if (!empty($filters['date_from'])) {
            $where .= " AND DATE(t.created_at) >= ?";
            $params[] = $filters['date_from'];
        }

        if (!empty($filters['date_to'])) {
            $where .= " AND DATE(t.created_at) <= ?";
            $params[] = $filters['date_to'];
        }

        // Get total count
        $count_stmt = $this->db->prepare("SELECT COUNT(*) as total FROM transactions t $where");
        $count_stmt->execute($params);
        $total = $count_stmt->fetch()['total'];

        // Get transactions
        $sql = "
            SELECT
                t.*,
                u.username,
                u.email
            FROM transactions t
            JOIN users u ON t.user_id = u.id
            $where
            ORDER BY t.created_at DESC
            LIMIT ? OFFSET ?
        ";

        $params[] = $limit;
        $params[] = $offset;

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $transactions = $stmt->fetchAll();

        return [
            'transactions' => $transactions,
            'total' => $total,
            'pages' => ceil($total / $limit),
            'current_page' => $page
        ];
    }

    // Process withdrawal
    public function processWithdrawal($transaction_id, $action, $notes = '') {
        // Get transaction details
        $stmt = $this->db->prepare("SELECT * FROM transactions WHERE id = ? AND type = 'withdrawal'");
        $stmt->execute([$transaction_id]);
        $transaction = $stmt->fetch();

        if (!$transaction) {
            return ['success' => false, 'message' => 'Transaction not found'];
        }

        if ($transaction['status'] !== 'pending') {
            return ['success' => false, 'message' => 'Transaction is not pending'];
        }

        $new_status = ($action === 'approve') ? 'completed' : 'rejected';

        // Update transaction status
        $update_stmt = $this->db->prepare("
            UPDATE transactions
            SET status = ?, admin_notes = ?, processed_by = ?, processed_at = NOW()
            WHERE id = ?
        ");
        $result = $update_stmt->execute([$new_status, $notes, $_SESSION['admin_id'], $transaction_id]);

        if ($result) {
            if ($action === 'approve') {
                // Deduct from user balance (already deducted when withdrawal was requested)
                // Send notification to user
                $this->sendNotification($transaction['user_id'], 'withdrawal_approved', [
                    'amount' => $transaction['amount'],
                    'reference' => $transaction['reference']
                ]);
            } else {
                // Refund amount to user balance
                $refund_stmt = $this->db->prepare("UPDATE users SET balance = balance + ? WHERE id = ?");
                $refund_stmt->execute([$transaction['amount'], $transaction['user_id']]);

                // Send notification to user
                $this->sendNotification($transaction['user_id'], 'withdrawal_rejected', [
                    'amount' => $transaction['amount'],
                    'reason' => $notes
                ]);
            }

            // Log the action
            $this->logAdminAction($_SESSION['admin_id'], 'process_withdrawal', "Processed withdrawal $transaction_id: $action");

            return ['success' => true, 'message' => 'Withdrawal processed successfully'];
        }

        return ['success' => false, 'message' => 'Failed to process withdrawal'];
    }

    // ============ SETTINGS MANAGEMENT ============

    // Get all settings
    public function getSettings() {
        $stmt = $this->db->query("SELECT * FROM settings ORDER BY category, `key`");
        return $stmt->fetchAll();
    }

    // Update setting
    public function updateSetting($key, $value) {
        $stmt = $this->db->prepare("UPDATE settings SET `value` = ?, updated_at = NOW() WHERE `key` = ?");
        $result = $stmt->execute([$value, $key]);

        if ($result) {
            // Log the action
            $this->logAdminAction($_SESSION['admin_id'], 'update_setting', "Updated setting $key to $value");
            return ['success' => true, 'message' => 'Setting updated successfully'];
        }

        return ['success' => false, 'message' => 'Failed to update setting'];
    }

    // ============ LOGGING AND NOTIFICATIONS ============

    // Log admin action
    private function logAdminAction($admin_id, $action, $details = '') {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO activity_logs (admin_id, action, description, ip_address, user_agent, details, created_at)
                VALUES (?, ?, ?, ?, ?, ?, NOW())
            ");
            $stmt->execute([
                $admin_id,
                $action,
                $details,
                $_SERVER['REMOTE_ADDR'] ?? '',
                $_SERVER['HTTP_USER_AGENT'] ?? '',
                json_encode(['details' => $details])
            ]);
        } catch (Exception $e) {
            error_log("Failed to log admin action: " . $e->getMessage());
        }
    }

    // Send notification to user
    private function sendNotification($user_id, $type, $data = []) {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO notifications (user_id, type, title, message, data, created_at)
                VALUES (?, ?, ?, ?, ?, NOW())
            ");
            $stmt->execute([
                $user_id,
                $type,
                $this->getNotificationTitle($type),
                $this->getNotificationMessage($type, $data),
                json_encode($data)
            ]);
        } catch (Exception $e) {
            error_log("Failed to send notification: " . $e->getMessage());
        }
    }

    private function getNotificationTitle($type) {
        $titles = [
            'withdrawal_approved' => 'Withdrawal Approved',
            'withdrawal_rejected' => 'Withdrawal Rejected',
            'deposit_approved' => 'Deposit Approved',
            'investment_completed' => 'Investment Completed'
        ];
        return $titles[$type] ?? 'Notification';
    }

    private function getNotificationMessage($type, $data) {
        switch ($type) {
            case 'withdrawal_approved':
                return "Your withdrawal of $" . number_format($data['amount'], 2) . " has been approved. Reference: " . $data['reference'];
            case 'withdrawal_rejected':
                return "Your withdrawal of $" . number_format($data['amount'], 2) . " has been rejected. Reason: " . ($data['reason'] ?? 'Not specified');
            case 'deposit_approved':
                return "Your deposit of $" . number_format($data['amount'], 2) . " has been approved and added to your account.";
            case 'investment_completed':
                return "Your investment has been completed. Total profit earned: $" . number_format($data['profit'], 2);
            default:
                return 'You have a new notification.';
        }
    }

    // ============ SYSTEM MAINTENANCE ============

    // Clear old logs
    public function clearOldLogs($days = 30) {
        try {
            // Clear old activity logs
            $stmt = $this->db->prepare("DELETE FROM activity_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY)");
            $stmt->execute([$days]);

            // Clear old notifications
            $stmt = $this->db->prepare("DELETE FROM notifications WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY) AND is_read = 1");
            $stmt->execute([$days]);

            $this->logAdminAction($_SESSION['admin_id'], 'clear_logs', "Cleared logs older than $days days");

            return ['success' => true, 'message' => 'Old logs cleared successfully'];
        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Failed to clear logs: ' . $e->getMessage()];
        }
    }

    // Get system information
    public function getSystemInfo() {
        return [
            'php_version' => PHP_VERSION,
            'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
            'database_version' => $this->getDatabaseVersion(),
            'total_users' => $this->getTotalUsers(),
            'total_investments' => $this->getTotalInvestments(),
            'total_transactions' => $this->db->query("SELECT COUNT(*) as count FROM transactions")->fetch()['count'],
            'disk_usage' => $this->getDiskUsage(),
            'memory_usage' => $this->getMemoryUsage()
        ];
    }

    private function getDatabaseVersion() {
        try {
            $stmt = $this->db->query("SELECT VERSION() as version");
            return $stmt->fetch()['version'];
        } catch (Exception $e) {
            return 'Unknown';
        }
    }

    private function getDiskUsage() {
        $total = disk_total_space('/');
        $free = disk_free_space('/');
        $used = $total - $free;
        return [
            'total' => $this->formatBytes($total),
            'used' => $this->formatBytes($used),
            'free' => $this->formatBytes($free),
            'percentage' => round(($used / $total) * 100, 2)
        ];
    }

    private function getMemoryUsage() {
        return [
            'current' => $this->formatBytes(memory_get_usage()),
            'peak' => $this->formatBytes(memory_get_peak_usage()),
            'limit' => ini_get('memory_limit')
        ];
    }

    private function formatBytes($bytes) {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $i = 0;
        while ($bytes >= 1024 && $i < count($units) - 1) {
            $bytes /= 1024;
            $i++;
        }
        return round($bytes, 2) . ' ' . $units[$i];
    }
}
?>
