<?php
/**
 * Account Status Manager Class
 * Handles account activation, deactivation, and status management
 */

class AccountStatusManager {
    private $conn;
    
    public function __construct($connection) {
        $this->conn = $connection;
    }
    
    
    /**
     * Update account status
     */
    public function updateAccountStatus($userId, $newStatus, $reason = '') {
        // Validate status
        $validStatuses = ['active', 'inactive', 'suspended'];
        if (!in_array($newStatus, $validStatuses)) {
            return [
                'success' => false,
                'message' => 'Invalid account status'
            ];
        }
        
        // Get current status
        $stmt = $this->conn->prepare("SELECT account_status FROM agents WHERE id = ?");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows === 0) {
            $stmt->close();
            return [
                'success' => false,
                'message' => 'User not found'
            ];
        }
        
        $currentStatus = $result->fetch_assoc()['account_status'];
        $stmt->close();
        
        // If status is the same, no need to update
        if ($currentStatus === $newStatus) {
            return [
                'success' => true,
                'message' => 'Status is already ' . $newStatus,
                'action' => 'no_change'
            ];
        }
        
        // Start transaction
        $this->conn->begin_transaction();
        
        try {
            // Update account status
            $stmt = $this->conn->prepare("
                UPDATE agents 
                SET account_status = ?, 
                    account_status_updated_at = NOW()
                WHERE id = ?
            ");
            $stmt->bind_param("si", $newStatus, $userId);
            
            if (!$stmt->execute()) {
                throw new Exception('Failed to update account status');
            }
            $stmt->close();
            
            // Log status change in history
            $historyStmt = $this->conn->prepare("
                INSERT INTO account_status_history (user_id, old_status, new_status, reason)
                VALUES (?, ?, ?, ?)
            ");
            $historyStmt->bind_param("isss", $userId, $currentStatus, $newStatus, $reason);
            
            if (!$historyStmt->execute()) {
                // Log the error for debugging
                error_log("AccountStatusManager: Failed to log status change. Error: " . $historyStmt->error);
                throw new Exception('Failed to log status change: ' . $historyStmt->error);
            }
            $historyStmt->close();
            
            // Commit transaction
            $this->conn->commit();
            
            return [
                'success' => true,
                'message' => 'Account status updated successfully',
                'action' => 'updated',
                'old_status' => $currentStatus,
                'new_status' => $newStatus
            ];
            
        } catch (Exception $e) {
            $this->conn->rollback();
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Get account status
     */
    public function getAccountStatus($userId) {
        $stmt = $this->conn->prepare("
            SELECT 
                a.*
            FROM agents a
            WHERE a.id = ?
        ");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $status = $result->fetch_assoc();
            $stmt->close();
            return $status;
        }
        
        $stmt->close();
        return null;
    }
    
    /**
     * Get all users with their account status
     */
    public function getAllUsersWithStatus($status = null, $role = null, $limit = 100, $offset = 0) {
        // Validate and sanitize parameters
        $limit = max(1, intval($limit));
        $offset = max(0, intval($offset));
        
        $sql = "
            SELECT 
                a.*
            FROM agents a
            WHERE 1=1
        ";
        
        $params = [];
        $types = "";
        
        if ($status !== null) {
            $sql .= " AND a.account_status = ?";
            $params[] = $status;
            $types .= "s";
        }
        
        if ($role !== null) {
            $sql .= " AND a.role = ?";
            $params[] = $role;
            $types .= "s";
        }
        
        $sql .= " ORDER BY a.account_status_updated_at DESC, a.username ASC LIMIT ? OFFSET ?";
        $params[] = $limit;
        $params[] = $offset;
        $types .= "ii";
        
        $stmt = $this->conn->prepare($sql);
        if (!empty($params)) {
            $stmt->bind_param($types, ...$params);
        }
        $stmt->execute();
        $result = $stmt->get_result();
        
        $users = [];
        while ($row = $result->fetch_assoc()) {
            $users[] = $row;
        }
        
        $stmt->close();
        return $users;
    }
    
    /**
     * Get account status statistics
     */
    public function getAccountStatusStats() {
        $stmt = $this->conn->prepare("
            SELECT 
                account_status,
                role,
                COUNT(*) as count
            FROM agents 
            GROUP BY account_status, role
            ORDER BY account_status, role
        ");
        
        $stmt->execute();
        $result = $stmt->get_result();
        
        $stats = [];
        while ($row = $result->fetch_assoc()) {
            $stats[] = $row;
        }
        
        $stmt->close();
        return $stats;
    }
    
    /**
     * Get account status history
     */
    public function getAccountStatusHistory($userId = null, $limit = 50) {
        $sql = "
            SELECT 
                ash.*,
                a.username as user_username
            FROM account_status_history ash
            JOIN agents a ON ash.user_id = a.id
        ";
        
        $params = [];
        $types = "";
        
        if ($userId !== null) {
            $sql .= " WHERE ash.user_id = ?";
            $params[] = $userId;
            $types .= "i";
        }
        
        $sql .= " ORDER BY ash.changed_at DESC LIMIT ?";
        $params[] = $limit;
        $types .= "i";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        $result = $stmt->get_result();
        
        $history = [];
        while ($row = $result->fetch_assoc()) {
            $history[] = $row;
        }
        
        $stmt->close();
        return $history;
    }
    
    /**
     * Check if user can login (account is active)
     */
    public function canUserLogin($userId) {
        $stmt = $this->conn->prepare("SELECT account_status FROM agents WHERE id = ?");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows === 0) {
            $stmt->close();
            return false;
        }
        
        $status = $result->fetch_assoc()['account_status'];
        $stmt->close();
        
        return $status === 'active';
    }
    
    /**
     * Bulk update account status
     */
    public function bulkUpdateAccountStatus($userIds, $newStatus, $reason = '') {
        $results = [];
        $successCount = 0;
        $errorCount = 0;
        
        foreach ($userIds as $userId) {
            $result = $this->updateAccountStatus($userId, $newStatus, $reason);
            $results[] = [
                'user_id' => $userId,
                'result' => $result
            ];
            
            if ($result['success']) {
                $successCount++;
            } else {
                $errorCount++;
            }
        }
        
        return [
            'success_count' => $successCount,
            'error_count' => $errorCount,
            'results' => $results
        ];
    }
    
    /**
     * Get users by status with pagination
     */
    public function getUsersByStatus($status, $page = 1, $perPage = 20) {
        // Validate and sanitize parameters
        $page = max(1, intval($page));
        $perPage = max(1, intval($perPage));
        $offset = ($page - 1) * $perPage;
        
        // Get users
        $users = $this->getAllUsersWithStatus($status, null, $perPage, $offset);
        
        // Get total count
        $stmt = $this->conn->prepare("SELECT COUNT(*) as total FROM agents WHERE account_status = ?");
        $stmt->bind_param("s", $status);
        $stmt->execute();
        $result = $stmt->get_result();
        $total = $result->fetch_assoc()['total'];
        $stmt->close();
        
        return [
            'users' => $users,
            'total' => $total,
            'page' => $page,
            'per_page' => $perPage,
            'total_pages' => ceil($total / $perPage)
        ];
    }
    
    /**
     * Auto-suspend account based on failed logins
     */
    public function autoSuspendAccount($userId, $failedLoginCount) {
        // Get auto-suspend threshold from config
        $stmt = $this->conn->prepare("SELECT config_value FROM payment_config WHERE config_key = 'account_auto_suspend_failed_logins'");
        $stmt->execute();
        $result = $stmt->get_result();
        $threshold = $result->num_rows > 0 ? intval($result->fetch_assoc()['config_value']) : 5;
        $stmt->close();
        
        if ($failedLoginCount >= $threshold) {
            return $this->updateAccountStatus($userId, 'suspended', 'Auto-suspended due to multiple failed login attempts');
        }
        
        return [
            'success' => false,
            'message' => 'Failed login count below threshold'
        ];
    }
    
    /**
     * Get account status summary
     */
    public function getAccountStatusSummary() {
        $stmt = $this->conn->prepare("
            SELECT 
                COUNT(*) as total_users,
                COUNT(CASE WHEN account_status = 'active' THEN 1 END) as active_users,
                COUNT(CASE WHEN account_status = 'inactive' THEN 1 END) as inactive_users,
                COUNT(CASE WHEN account_status = 'suspended' THEN 1 END) as suspended_users,
                COUNT(CASE WHEN role = 'agent' THEN 1 END) as total_agents,
                COUNT(CASE WHEN role = 'super_agent' THEN 1 END) as total_super_agents,
                COUNT(CASE WHEN role = 'dealer' THEN 1 END) as total_dealers
            FROM agents
        ");
        
        $stmt->execute();
        $result = $stmt->get_result();
        $summary = $result->fetch_assoc();
        $stmt->close();
        
        return $summary;
    }
}
?>


