<?php
/**
 * Store Manager Class
 * Handles all store-related operations for multi-tenant system
 */

class StoreManager {
    private $conn;
    
    public function __construct($connection) {
        $this->conn = $connection;
    }
    
    /**
     * Create a new store
     */
    public function createStore($storeName, $ownerId, $storeData = []) {
        // Generate unique store slug
        $storeSlug = $this->generateStoreSlug($storeName, $ownerId);
        
        // Validate store slug is unique
        if ($this->storeSlugExists($storeSlug)) {
            $storeSlug = $this->generateStoreSlug($storeName, $ownerId, true);
        }
        
        // Prepare store data
        $description = $storeData['description'] ?? '';
        $phone = $storeData['phone'] ?? '';
        $momoName = $storeData['momo_name'] ?? '';
        $email = $storeData['email'] ?? '';
        $whatsapp = $storeData['whatsapp'] ?? $phone;
        $address = $storeData['address'] ?? '';
        $status = $storeData['status'] ?? 'active';
        
        // Check if momo_name column exists, if not add it
        $this->ensureMomoNameColumnExists();
        
        // Insert store
        $stmt = $this->conn->prepare("
            INSERT INTO stores (store_name, store_slug, owner_id, description, phone, momo_name, email, whatsapp, address, status)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $stmt->bind_param("ssisssssss", 
            $storeName, $storeSlug, $ownerId, $description, 
            $phone, $momoName, $email, $whatsapp, $address, $status
        );
        
        if ($stmt->execute()) {
            $storeId = $this->conn->insert_id;
            $stmt->close();
            
            // Update agent to mark as store owner
            $this->markUserAsStoreOwner($ownerId, $storeId);
            
            // Copy default pricing to store
            $this->setupDefaultPricing($storeId);
            
            return [
                'success' => true,
                'store_id' => $storeId,
                'store_slug' => $storeSlug,
                'message' => 'Store created successfully'
            ];
        } else {
            $error = $stmt->error;
            $stmt->close();
            return [
                'success' => false,
                'message' => 'Failed to create store: ' . $error
            ];
        }
    }
    
    /**
     * Get store by ID
     */
    public function getStoreById($storeId) {
        // Ensure momo_name column exists before querying
        $this->ensureMomoNameColumnExists();
        
        $stmt = $this->conn->prepare("
            SELECT s.*, a.username as owner_username, a.email as owner_email
            FROM stores s
            INNER JOIN agents a ON s.owner_id = a.id
            WHERE s.id = ?
        ");
        $stmt->bind_param("i", $storeId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $store = $result->fetch_assoc();
            $stmt->close();
            return $store;
        }
        
        $stmt->close();
        return null;
    }
    
    /**
     * Get store by slug
     */
    public function getStoreBySlug($storeSlug) {
        // Ensure momo_name column exists before querying
        $this->ensureMomoNameColumnExists();
        
        $stmt = $this->conn->prepare("
            SELECT s.*, a.username as owner_username, a.email as owner_email
            FROM stores s
            INNER JOIN agents a ON s.owner_id = a.id
            WHERE s.store_slug = ?
        ");
        $stmt->bind_param("s", $storeSlug);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $store = $result->fetch_assoc();
            $stmt->close();
            return $store;
        }
        
        $stmt->close();
        return null;
    }
    
    /**
     * Get store by owner ID
     */
    public function getStoreByOwnerId($ownerId) {
        // Ensure momo_name column exists before querying
        $this->ensureMomoNameColumnExists();
        
        $stmt = $this->conn->prepare("
            SELECT s.*, a.username as owner_username
            FROM stores s
            INNER JOIN agents a ON s.owner_id = a.id
            WHERE s.owner_id = ?
        ");
        $stmt->bind_param("i", $ownerId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $store = $result->fetch_assoc();
            $stmt->close();
            return $store;
        }
        
        $stmt->close();
        return null;
    }
    
    /**
     * Update store information
     */
    public function updateStore($storeId, $storeData) {
        $updateFields = [];
        $params = [];
        $types = "";
        
        // Store name cannot be changed after creation for security (permanent URL)
        // if (isset($storeData['store_name'])) {
        //     $updateFields[] = "store_name = ?";
        //     $params[] = $storeData['store_name'];
        //     $types .= "s";
        // }
        
        if (isset($storeData['description'])) {
            $updateFields[] = "description = ?";
            $params[] = $storeData['description'];
            $types .= "s";
        }
        
        if (isset($storeData['phone'])) {
            $updateFields[] = "phone = ?";
            $params[] = $storeData['phone'];
            $types .= "s";
        }
        
        if (isset($storeData['momo_name'])) {
            // Ensure column exists before updating
            $this->ensureMomoNameColumnExists();
            $updateFields[] = "momo_name = ?";
            $params[] = $storeData['momo_name'];
            $types .= "s";
        }
        
        if (isset($storeData['email'])) {
            $updateFields[] = "email = ?";
            $params[] = $storeData['email'];
            $types .= "s";
        }
        
        if (isset($storeData['whatsapp'])) {
            $updateFields[] = "whatsapp = ?";
            $params[] = $storeData['whatsapp'];
            $types .= "s";
        }
        
        if (isset($storeData['whatsapp_group_link'])) {
            $updateFields[] = "whatsapp_group_link = ?";
            $params[] = $storeData['whatsapp_group_link'];
            $types .= "s";
        }
        
        if (isset($storeData['address'])) {
            $updateFields[] = "address = ?";
            $params[] = $storeData['address'];
            $types .= "s";
        }
        
        if (isset($storeData['logo_url'])) {
            $updateFields[] = "logo_url = ?";
            $params[] = $storeData['logo_url'];
            $types .= "s";
        }
        
        if (isset($storeData['hero_color_1'])) {
            $updateFields[] = "hero_color_1 = ?";
            $params[] = $storeData['hero_color_1'];
            $types .= "s";
        }
        
        if (isset($storeData['hero_color_2'])) {
            $updateFields[] = "hero_color_2 = ?";
            $params[] = $storeData['hero_color_2'];
            $types .= "s";
        }
        
        if (isset($storeData['button_color'])) {
            $updateFields[] = "button_color = ?";
            $params[] = $storeData['button_color'];
            $types .= "s";
        }
        
        if (isset($storeData['button_hover_color'])) {
            $updateFields[] = "button_hover_color = ?";
            $params[] = $storeData['button_hover_color'];
            $types .= "s";
        }
        
        if (isset($storeData['background_color'])) {
            $updateFields[] = "background_color = ?";
            $params[] = $storeData['background_color'];
            $types .= "s";
        }
        
        if (isset($storeData['form_theme'])) {
            $updateFields[] = "form_theme = ?";
            $params[] = $storeData['form_theme'];
            $types .= "s";
        }
        
        if (isset($storeData['working_hours'])) {
            // working_hours is stored as JSON
            $updateFields[] = "working_hours = ?";
            $params[] = $storeData['working_hours'];
            $types .= "s";
        }
        
        if (isset($storeData['status'])) {
            $updateFields[] = "status = ?";
            $params[] = $storeData['status'];
            $types .= "s";
        }
        
        if (empty($updateFields)) {
            return ['success' => false, 'message' => 'No fields to update'];
        }
        
        $sql = "UPDATE stores SET " . implode(", ", $updateFields) . " WHERE id = ?";
        $params[] = $storeId;
        $types .= "i";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param($types, ...$params);
        
        if ($stmt->execute()) {
            $stmt->close();
            return ['success' => true, 'message' => 'Store updated successfully'];
        } else {
            $error = $stmt->error;
            $stmt->close();
            return ['success' => false, 'message' => 'Failed to update store: ' . $error];
        }
    }
    
    /**
     * Get all agents for a store
     */
    public function getStoreAgents($storeId) {
        $stmt = $this->conn->prepare("
            SELECT a.*, sa.role as store_role, sa.joined_at, sa.status as agent_status
            FROM agents a
            INNER JOIN store_agents sa ON a.id = sa.agent_id
            WHERE sa.store_id = ?
            ORDER BY sa.joined_at DESC
        ");
        $stmt->bind_param("i", $storeId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        $agents = [];
        while ($row = $result->fetch_assoc()) {
            $agents[] = $row;
        }
        
        $stmt->close();
        return $agents;
    }
    
    /**
     * Create agent directly and add to store
     * STRICT RULE: Store owners can ONLY create agents, never store owners
     * This method enforces role = 'agent' and is_store_owner = 0
     */
    public function createAgentDirectly($storeId, $agentData) {
        // CRITICAL: Explicitly reject any attempt to set role or is_store_owner
        // Store owners can ONLY create agents, never store owners
        if (isset($agentData['role']) && $agentData['role'] !== 'agent') {
            return ['success' => false, 'message' => 'Invalid role. Store owners can only create agents.'];
        }
        
        if (isset($agentData['is_store_owner']) && $agentData['is_store_owner'] != 0) {
            return ['success' => false, 'message' => 'Store owners cannot create other store owners.'];
        }
        
        // Validate required fields
        if (empty($agentData['username']) || empty($agentData['email']) || empty($agentData['phone']) || empty($agentData['password'])) {
            return ['success' => false, 'message' => 'All fields are required'];
        }
        
        // Validate email format
        if (!filter_var($agentData['email'], FILTER_VALIDATE_EMAIL)) {
            return ['success' => false, 'message' => 'Invalid email format'];
        }
        
        // Validate username length
        if (strlen($agentData['username']) < 3) {
            return ['success' => false, 'message' => 'Username must be at least 3 characters'];
        }
        
        // Validate password length
        if (strlen($agentData['password']) < 6) {
            return ['success' => false, 'message' => 'Password must be at least 6 characters'];
        }
        
        // Validate phone number - must be exactly 10 digits starting with 0
        $clean_phone = preg_replace('/\D/', '', $agentData['phone']);
        if (strlen($clean_phone) !== 10 || substr($clean_phone, 0, 1) !== '0') {
            return ['success' => false, 'message' => 'Phone must be exactly 10 digits starting with 0'];
        }
        $phone = $clean_phone;
        
        // Check if username already exists
        $checkUsernameStmt = $this->conn->prepare("SELECT id FROM agents WHERE username = ? LIMIT 1");
        $checkUsernameStmt->bind_param("s", $agentData['username']);
        $checkUsernameStmt->execute();
        $usernameResult = $checkUsernameStmt->get_result();
        
        if ($usernameResult->num_rows > 0) {
            $checkUsernameStmt->close();
            return ['success' => false, 'message' => 'Username already exists'];
        }
        $checkUsernameStmt->close();
        
        // Check if email already exists
        $checkEmailStmt = $this->conn->prepare("SELECT id FROM agents WHERE email = ? LIMIT 1");
        $checkEmailStmt->bind_param("s", $agentData['email']);
        $checkEmailStmt->execute();
        $emailResult = $checkEmailStmt->get_result();
        
        if ($emailResult->num_rows > 0) {
            $checkEmailStmt->close();
            return ['success' => false, 'message' => 'Email already registered'];
        }
        $checkEmailStmt->close();
        
        // Check if user already exists and is a store owner
        $checkExistingStmt = $this->conn->prepare("SELECT id, is_store_owner, store_id FROM agents WHERE email = ? OR username = ? LIMIT 1");
        $checkExistingStmt->bind_param("ss", $agentData['email'], $agentData['username']);
        $checkExistingStmt->execute();
        $existingResult = $checkExistingStmt->get_result();
        
        if ($existingResult->num_rows > 0) {
            $existing = $existingResult->fetch_assoc();
            $checkExistingStmt->close();
            
            if ($existing['is_store_owner'] == 1) {
                return ['success' => false, 'message' => 'Store owners cannot be added as sub-agents'];
            }
            
            if ($existing['store_id'] !== null && $existing['store_id'] != $storeId) {
                return ['success' => false, 'message' => 'User is already registered under another store'];
            }
            
            if ($existing['store_id'] == $storeId) {
                return ['success' => false, 'message' => 'User is already an agent for this store'];
            }
        }
        $checkExistingStmt->close();
        
        // Hash the password
        $password_hash = password_hash($agentData['password'], PASSWORD_BCRYPT);
        
        // STRICT ENFORCEMENT: Store owners can ONLY create agents
        // Force role = 'agent' and is_store_owner = 0 (ignore any values passed in agentData)
        $balance = floatval($agentData['balance'] ?? 0.00);
        $role = 'agent'; // ALWAYS 'agent' - never 'store_owner'
        $is_store_owner = 0; // ALWAYS 0 - never 1
        
        $insertStmt = $this->conn->prepare("INSERT INTO agents (username, email, phone, password_hash, balance, role, is_store_owner, store_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())");
        $insertStmt->bind_param("ssssdsii", $agentData['username'], $agentData['email'], $phone, $password_hash, $balance, $role, $is_store_owner, $storeId);
        
        if ($insertStmt->execute()) {
            $newAgentId = $this->conn->insert_id;
            $insertStmt->close();
            
            // Verify agent was created correctly
            $verifyStmt = $this->conn->prepare("SELECT is_store_owner, store_id FROM agents WHERE id = ?");
            $verifyStmt->bind_param("i", $newAgentId);
            $verifyStmt->execute();
            $verifyResult = $verifyStmt->get_result();
            $verifyAgent = $verifyResult->fetch_assoc();
            $verifyStmt->close();
            
            if ($verifyAgent['is_store_owner'] == 0 && $verifyAgent['store_id'] == $storeId) {
                // Add to store_agents junction table
                $addResult = $this->addAgentToStore($storeId, $newAgentId, 'agent');
                
                if ($addResult['success']) {
                    // Final verification
                    $finalVerifyStmt = $this->conn->prepare("SELECT is_store_owner, store_id, role FROM agents WHERE id = ?");
                    $finalVerifyStmt->bind_param("i", $newAgentId);
                    $finalVerifyStmt->execute();
                    $finalVerifyResult = $finalVerifyStmt->get_result();
                    $finalVerifyAgent = $finalVerifyResult->fetch_assoc();
                    $finalVerifyStmt->close();
                    
                    if ($finalVerifyAgent['is_store_owner'] == 0 && $finalVerifyAgent['store_id'] == $storeId && $finalVerifyAgent['role'] == 'agent') {
                        return ['success' => true, 'message' => 'Agent created and added to store successfully', 'agent_id' => $newAgentId];
                    } else {
                        // Rollback
                        $rollbackStmt = $this->conn->prepare("DELETE FROM agents WHERE id = ?");
                        $rollbackStmt->bind_param("i", $newAgentId);
                        $rollbackStmt->execute();
                        $rollbackStmt->close();
                        
                        $removeStmt = $this->conn->prepare("DELETE FROM store_agents WHERE agent_id = ?");
                        $removeStmt->bind_param("i", $newAgentId);
                        $removeStmt->execute();
                        $removeStmt->close();
                        
                        return ['success' => false, 'message' => 'Agent role assignment failed'];
                    }
                } else {
                    // Rollback agent creation
                    $rollbackStmt = $this->conn->prepare("DELETE FROM agents WHERE id = ?");
                    $rollbackStmt->bind_param("i", $newAgentId);
                    $rollbackStmt->execute();
                    $rollbackStmt->close();
                    
                    return ['success' => false, 'message' => 'Failed to add agent to store: ' . $addResult['message']];
                }
            } else {
                // Rollback
                $rollbackStmt = $this->conn->prepare("DELETE FROM agents WHERE id = ?");
                $rollbackStmt->bind_param("i", $newAgentId);
                $rollbackStmt->execute();
                $rollbackStmt->close();
                
                return ['success' => false, 'message' => 'Agent created incorrectly'];
            }
        } else {
            $error = $insertStmt->error;
            $insertStmt->close();
            return ['success' => false, 'message' => 'Failed to create agent: ' . $error];
        }
    }
    
    /**
     * Add agent to store
     * NOTE: This is for adding EXISTING agents to a store (e.g., via invitation)
     * For creating NEW agents, use createAgentDirectly() which enforces role = 'agent'
     */
    public function addAgentToStore($storeId, $agentId, $role = 'agent') {
        // Check if agent already in store
        $checkStmt = $this->conn->prepare("
            SELECT id FROM store_agents WHERE store_id = ? AND agent_id = ?
        ");
        $checkStmt->bind_param("ii", $storeId, $agentId);
        $checkStmt->execute();
        $checkResult = $checkStmt->get_result();
        
        if ($checkResult->num_rows > 0) {
            $checkStmt->close();
            return ['success' => false, 'message' => 'Agent already in this store'];
        }
        $checkStmt->close();
        
        // Add agent to store
        $stmt = $this->conn->prepare("
            INSERT INTO store_agents (store_id, agent_id, role, status)
            VALUES (?, ?, ?, 'active')
        ");
        $stmt->bind_param("iis", $storeId, $agentId, $role);
        
        if ($stmt->execute()) {
            $stmt->close();
            
            // CRITICAL FIX: Update agent's store_id
            // For new sub-agents (from register_agent.php), ensure is_store_owner = 0
            // For existing agents (from invitations), preserve their is_store_owner status
            // Check if agent is already a store owner before updating
            $checkOwnerStmt = $this->conn->prepare("SELECT is_store_owner FROM agents WHERE id = ?");
            $checkOwnerStmt->bind_param("i", $agentId);
            $checkOwnerStmt->execute();
            $ownerResult = $checkOwnerStmt->get_result();
            $ownerData = $ownerResult->fetch_assoc();
            $checkOwnerStmt->close();
            
            // Only set is_store_owner = 0 if agent is not already a store owner
            // This prevents new sub-agents from getting is_store_owner = 1, but preserves
            // the status of existing store owners who join via invitation
            if ($ownerData && $ownerData['is_store_owner'] == 1) {
                // Agent is already a store owner - preserve that status, just update store_id
                $updateStmt = $this->conn->prepare("UPDATE agents SET store_id = ? WHERE id = ?");
                $updateStmt->bind_param("ii", $storeId, $agentId);
            } else {
                // Agent is not a store owner - explicitly ensure is_store_owner = 0
                $updateStmt = $this->conn->prepare("UPDATE agents SET store_id = ?, is_store_owner = 0 WHERE id = ?");
                $updateStmt->bind_param("ii", $storeId, $agentId);
            }
            $updateStmt->execute();
            $updateStmt->close();
            
            return ['success' => true, 'message' => 'Agent added to store successfully'];
        } else {
            $error = $stmt->error;
            $stmt->close();
            return ['success' => false, 'message' => 'Failed to add agent: ' . $error];
        }
    }
    
    /**
     * Remove agent from store
     */
    public function removeAgentFromStore($storeId, $agentId) {
        $stmt = $this->conn->prepare("
            DELETE FROM store_agents WHERE store_id = ? AND agent_id = ?
        ");
        $stmt->bind_param("ii", $storeId, $agentId);
        
        if ($stmt->execute()) {
            $affected = $stmt->affected_rows;
            $stmt->close();
            
            // Clear agent's store_id
            $updateStmt = $this->conn->prepare("UPDATE agents SET store_id = NULL WHERE id = ?");
            $updateStmt->bind_param("i", $agentId);
            $updateStmt->execute();
            $updateStmt->close();
            
            if ($affected > 0) {
                return ['success' => true, 'message' => 'Agent removed from store'];
            } else {
                return ['success' => false, 'message' => 'Agent not found in store'];
            }
        } else {
            $error = $stmt->error;
            $stmt->close();
            return ['success' => false, 'message' => 'Failed to remove agent: ' . $error];
        }
    }
    
    /**
     * Update agent status in store (suspend/activate)
     */
    public function updateAgentStatus($storeId, $agentId, $status) {
        // Validate status
        if (!in_array($status, ['active', 'suspended'])) {
            return ['success' => false, 'message' => 'Invalid status. Must be "active" or "suspended"'];
        }
        
        // Verify agent belongs to this store
        $checkStmt = $this->conn->prepare("
            SELECT id FROM store_agents WHERE store_id = ? AND agent_id = ?
        ");
        $checkStmt->bind_param("ii", $storeId, $agentId);
        $checkStmt->execute();
        $checkResult = $checkStmt->get_result();
        
        if ($checkResult->num_rows === 0) {
            $checkStmt->close();
            return ['success' => false, 'message' => 'Agent not found in this store'];
        }
        $checkStmt->close();
        
        // Prevent suspending store owner
        $ownerStmt = $this->conn->prepare("
            SELECT owner_id FROM stores WHERE id = ?
        ");
        $ownerStmt->bind_param("i", $storeId);
        $ownerStmt->execute();
        $ownerResult = $ownerStmt->get_result();
        $ownerData = $ownerResult->fetch_assoc();
        $ownerStmt->close();
        
        if ($ownerData && $ownerData['owner_id'] == $agentId && $status === 'suspended') {
            return ['success' => false, 'message' => 'Cannot suspend store owner'];
        }
        
        // Update status
        $stmt = $this->conn->prepare("
            UPDATE store_agents 
            SET status = ? 
            WHERE store_id = ? AND agent_id = ?
        ");
        $stmt->bind_param("sii", $status, $storeId, $agentId);
        
        if ($stmt->execute()) {
            $stmt->close();
            return [
                'success' => true, 
                'message' => 'Agent status updated successfully',
                'status' => $status
            ];
        } else {
            $error = $stmt->error;
            $stmt->close();
            return ['success' => false, 'message' => 'Failed to update agent status: ' . $error];
        }
    }
    
    /**
     * Generate store invitation code
     */
    public function createInvitation($storeId, $email = null, $phone = null, $expiryDays = 30) {
        $invitationCode = $this->generateInvitationCode();
        $expiresAt = date('Y-m-d H:i:s', strtotime("+$expiryDays days"));
        
        $stmt = $this->conn->prepare("
            INSERT INTO store_invitations (store_id, invitation_code, email, phone, expires_at)
            VALUES (?, ?, ?, ?, ?)
        ");
        $stmt->bind_param("issss", $storeId, $invitationCode, $email, $phone, $expiresAt);
        
        if ($stmt->execute()) {
            $invitationId = $this->conn->insert_id;
            $stmt->close();
            return [
                'success' => true,
                'invitation_id' => $invitationId,
                'invitation_code' => $invitationCode,
                'expires_at' => $expiresAt
            ];
        } else {
            $error = $stmt->error;
            $stmt->close();
            return ['success' => false, 'message' => 'Failed to create invitation: ' . $error];
        }
    }
    
    /**
     * Validate and use invitation code
     */
    public function useInvitation($invitationCode, $agentId) {
        $stmt = $this->conn->prepare("
            SELECT * FROM store_invitations 
            WHERE invitation_code = ? AND status = 'pending'
            AND (expires_at IS NULL OR expires_at > NOW())
        ");
        $stmt->bind_param("s", $invitationCode);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $invitation = $result->fetch_assoc();
            $stmt->close();
            
            // Update invitation status
            $updateStmt = $this->conn->prepare("
                UPDATE store_invitations 
                SET status = 'accepted', used_at = NOW(), used_by_agent_id = ?
                WHERE id = ?
            ");
            $updateStmt->bind_param("ii", $agentId, $invitation['id']);
            $updateStmt->execute();
            $updateStmt->close();
            
            // Add agent to store
            $result = $this->addAgentToStore($invitation['store_id'], $agentId);
            $result['store_id'] = $invitation['store_id'];
            return $result;
        } else {
            $stmt->close();
            return ['success' => false, 'message' => 'Invalid or expired invitation code'];
        }
    }
    
    /**
     * Get store statistics (includes all order sources)
     */
    public function getStoreStats($storeId) {
        $stats = [];
        
        // Total agents
        $agentStmt = $this->conn->prepare("
            SELECT COUNT(*) as total_agents FROM store_agents WHERE store_id = ? AND status = 'active'
        ");
        $agentStmt->bind_param("i", $storeId);
        $agentStmt->execute();
        $agentResult = $agentStmt->get_result();
        $stats['total_agents'] = $agentResult->fetch_assoc()['total_agents'];
        $agentStmt->close();
        
        // Orders from 'orders' table (direct customer orders)
        $directOrderStmt = $this->conn->prepare("
            SELECT COUNT(*) as count, COALESCE(SUM(amount), 0) as revenue 
            FROM orders WHERE store_id = ?
        ");
        $directOrderStmt->bind_param("i", $storeId);
        $directOrderStmt->execute();
        $directResult = $directOrderStmt->get_result();
        $directData = $directResult->fetch_assoc();
        $directOrderStmt->close();
        
        // Orders from 'agent_orders' table (agent orders)
        $agentOrderStmt = $this->conn->prepare("
            SELECT COUNT(*) as count, COALESCE(SUM(amount), 0) as revenue 
            FROM agent_orders WHERE store_id = ?
        ");
        $agentOrderStmt->bind_param("i", $storeId);
        $agentOrderStmt->execute();
        $agentResult = $agentOrderStmt->get_result();
        $agentData = $agentResult->fetch_assoc();
        $agentOrderStmt->close();
        
        // Combine stats
        $stats['total_orders'] = ($directData['count'] ?? 0) + ($agentData['count'] ?? 0);
        $stats['total_revenue'] = ($directData['revenue'] ?? 0) + ($agentData['revenue'] ?? 0);
        $stats['customer_orders'] = $directData['count'] ?? 0;
        $stats['agent_orders'] = $agentData['count'] ?? 0;
        
        return $stats;
    }
    
    /**
     * Get all stores (admin function)
     */
    public function getAllStores($limit = 100, $offset = 0) {
        $stmt = $this->conn->prepare("
            SELECT s.*, a.username as owner_username,
                   (SELECT COUNT(*) FROM store_agents sa WHERE sa.store_id = s.id) as agent_count
            FROM stores s
            INNER JOIN agents a ON s.owner_id = a.id
            ORDER BY s.created_at DESC
            LIMIT ? OFFSET ?
        ");
        $stmt->bind_param("ii", $limit, $offset);
        $stmt->execute();
        $result = $stmt->get_result();
        
        $stores = [];
        while ($row = $result->fetch_assoc()) {
            $stores[] = $row;
        }
        
        $stmt->close();
        return $stores;
    }
    
    // ========== PRIVATE HELPER METHODS ==========
    
    /**
     * Generate unique store slug
     */
    private function generateStoreSlug($storeName, $ownerId, $addRandom = false) {
        $slug = strtolower(trim($storeName));
        $slug = preg_replace('/[^a-z0-9-]/', '', str_replace(' ', '-', $slug));
        $slug = preg_replace('/-+/', '-', $slug);
        $slug = trim($slug, '-');
        
        if (empty($slug)) {
            $slug = 'store' . $ownerId;
        }
        
        if ($addRandom) {
            $slug .= '-' . substr(md5(uniqid()), 0, 6);
        }
        
        return $slug;
    }
    
    /**
     * Check if store slug exists
     */
    private function storeSlugExists($storeSlug) {
        $stmt = $this->conn->prepare("SELECT id FROM stores WHERE store_slug = ?");
        $stmt->bind_param("s", $storeSlug);
        $stmt->execute();
        $result = $stmt->get_result();
        $exists = $result->num_rows > 0;
        $stmt->close();
        return $exists;
    }
    
    /**
     * Ensure momo_name column exists in stores table
     */
    private function ensureMomoNameColumnExists() {
        $checkStmt = $this->conn->prepare("SHOW COLUMNS FROM stores LIKE 'momo_name'");
        $checkStmt->execute();
        $result = $checkStmt->get_result();
        $exists = $result->num_rows > 0;
        $checkStmt->close();
        
        if (!$exists) {
            // Add momo_name column after phone column
            $this->conn->query("ALTER TABLE stores ADD COLUMN momo_name VARCHAR(100) NULL AFTER phone");
        }
    }
    
    /**
     * Mark user as store owner
     * MULTI-LAYER SECURITY: Sets both role = 'store_owner' AND is_store_owner = 1
     * This creates complete separation from agents
     */
    private function markUserAsStoreOwner($userId, $storeId) {
        // LAYER 1: Set role to 'store_owner' (distinct from 'agent')
        // LAYER 2: Set is_store_owner = 1
        // LAYER 3: Set store_id to the owned store
        $stmt = $this->conn->prepare("
            UPDATE agents 
            SET is_store_owner = 1, role = 'store_owner', store_id = ? 
            WHERE id = ?
        ");
        $stmt->bind_param("ii", $storeId, $userId);
        $stmt->execute();
        $stmt->close();
        
        // Verify the update was successful
        $verifyStmt = $this->conn->prepare("
            SELECT role, is_store_owner, store_id 
            FROM agents 
            WHERE id = ?
        ");
        $verifyStmt->bind_param("i", $userId);
        $verifyStmt->execute();
        $verifyResult = $verifyStmt->get_result();
        $verifyData = $verifyResult->fetch_assoc();
        $verifyStmt->close();
        
        // Ensure all layers are correct
        if ($verifyData['role'] !== 'store_owner' || 
            $verifyData['is_store_owner'] != 1 || 
            $verifyData['store_id'] != $storeId) {
            error_log("CRITICAL: Failed to properly set store owner - User ID: $userId");
            // Retry once
            $retryStmt = $this->conn->prepare("
                UPDATE agents 
                SET is_store_owner = 1, role = 'store_owner', store_id = ? 
                WHERE id = ?
            ");
            $retryStmt->bind_param("ii", $storeId, $userId);
            $retryStmt->execute();
            $retryStmt->close();
        }
    }
    
    /**
     * MULTI-LAYER VALIDATION: Verify user is a legitimate store owner
     * Checks: role = 'store_owner', is_store_owner = 1, AND actually owns a store
     */
    public function verifyStoreOwner($userId) {
        $stmt = $this->conn->prepare("
            SELECT a.id, a.role, a.is_store_owner, a.store_id, s.id as store_exists
            FROM agents a
            LEFT JOIN stores s ON s.owner_id = a.id
            WHERE a.id = ?
        ");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        $user = $result->fetch_assoc();
        $stmt->close();
        
        if (!$user) {
            return ['valid' => false, 'reason' => 'User not found'];
        }
        
        // LAYER 1: Check role
        if ($user['role'] !== 'store_owner') {
            return ['valid' => false, 'reason' => 'Invalid role: ' . $user['role']];
        }
        
        // LAYER 2: Check is_store_owner flag
        if ($user['is_store_owner'] != 1) {
            return ['valid' => false, 'reason' => 'is_store_owner flag is not set'];
        }
        
        // LAYER 3: Verify actually owns a store
        if (empty($user['store_exists'])) {
            return ['valid' => false, 'reason' => 'User does not own a store'];
        }
        
        // LAYER 4: Verify store_id matches
        if ($user['store_id'] != $user['store_exists']) {
            return ['valid' => false, 'reason' => 'store_id mismatch'];
        }
        
        return ['valid' => true, 'store_id' => $user['store_exists']];
    }
    
    /**
     * MULTI-LAYER VALIDATION: Verify user is a legitimate agent (not store owner)
     * Checks: role = 'agent', is_store_owner = 0, AND belongs to a store
     */
    public function verifyAgent($userId) {
        $stmt = $this->conn->prepare("
            SELECT a.id, a.role, a.is_store_owner, a.store_id, sa.store_id as store_agent_store_id
            FROM agents a
            LEFT JOIN store_agents sa ON a.id = sa.agent_id AND sa.status = 'active'
            WHERE a.id = ?
        ");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        $user = $result->fetch_assoc();
        $stmt->close();
        
        if (!$user) {
            return ['valid' => false, 'reason' => 'User not found'];
        }
        
        // LAYER 1: Check role
        if ($user['role'] !== 'agent') {
            return ['valid' => false, 'reason' => 'Invalid role: ' . $user['role']];
        }
        
        // LAYER 2: Check is_store_owner flag
        if ($user['is_store_owner'] != 0) {
            return ['valid' => false, 'reason' => 'is_store_owner flag is set (should be 0)'];
        }
        
        // LAYER 3: Verify belongs to a store
        if (empty($user['store_id']) && empty($user['store_agent_store_id'])) {
            return ['valid' => false, 'reason' => 'Agent does not belong to a store'];
        }
        
        // LAYER 4: Verify not a store owner
        $storeCheck = $this->conn->prepare("SELECT id FROM stores WHERE owner_id = ?");
        $storeCheck->bind_param("i", $userId);
        $storeCheck->execute();
        $storeResult = $storeCheck->get_result();
        if ($storeResult->num_rows > 0) {
            $storeCheck->close();
            return ['valid' => false, 'reason' => 'User owns a store (should be agent only)'];
        }
        $storeCheck->close();
        
        return ['valid' => true, 'store_id' => $user['store_id'] ?? $user['store_agent_store_id']];
    }
    
    /**
     * Setup default pricing for new store
     */
    private function setupDefaultPricing($storeId) {
        // Copy default pricing from agent_pricing_rules
        $stmt = $this->conn->prepare("
            INSERT INTO store_pricing (store_id, network_type, min_size_gb, max_size_gb, price_per_gb, is_active)
            SELECT ?, network_type, min_size_gb, max_size_gb, price_per_gb, is_active
            FROM agent_pricing_rules
            WHERE role = 'agent' AND is_active = 1
        ");
        $stmt->bind_param("i", $storeId);
        $stmt->execute();
        $stmt->close();
    }
    
    /**
     * Generate invitation code
     */
    private function generateInvitationCode() {
        return strtoupper(substr(md5(uniqid(rand(), true)), 0, 10));
    }
    
    /**
     * Check if user is store owner
     */
    public function isStoreOwner($userId) {
        $stmt = $this->conn->prepare("SELECT is_store_owner FROM agents WHERE id = ?");
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $row = $result->fetch_assoc();
            $stmt->close();
            return $row['is_store_owner'] == 1;
        }
        
        $stmt->close();
        return false;
    }
    
    /**
     * Change agent password (store owner only)
     * Verifies that the agent belongs to the store owner's store
     */
    public function changeAgentPassword($storeOwnerId, $agentId, $newPassword) {
        // Verify store owner owns a store
        $store = $this->getStoreByOwnerId($storeOwnerId);
        if (!$store) {
            return ['success' => false, 'message' => 'Store not found'];
        }
        
        // Verify agent belongs to this store
        $checkStmt = $this->conn->prepare("
            SELECT a.id, a.username, a.email 
            FROM agents a
            INNER JOIN store_agents sa ON a.id = sa.agent_id
            WHERE a.id = ? AND sa.store_id = ? AND sa.status = 'active'
        ");
        $checkStmt->bind_param("ii", $agentId, $store['id']);
        $checkStmt->execute();
        $result = $checkStmt->get_result();
        
        if ($result->num_rows === 0) {
            $checkStmt->close();
            return ['success' => false, 'message' => 'Agent not found or does not belong to your store'];
        }
        
        $agent = $result->fetch_assoc();
        $checkStmt->close();
        
        // Validate password length
        if (strlen($newPassword) < 6) {
            return ['success' => false, 'message' => 'Password must be at least 6 characters'];
        }
        
        // Hash the new password
        $password_hash = password_hash($newPassword, PASSWORD_BCRYPT);
        
        // Update password
        $updateStmt = $this->conn->prepare("UPDATE agents SET password_hash = ? WHERE id = ?");
        $updateStmt->bind_param("si", $password_hash, $agentId);
        
        if ($updateStmt->execute()) {
            $updateStmt->close();
            return [
                'success' => true, 
                'message' => 'Password changed successfully for agent: ' . $agent['username']
            ];
        } else {
            $error = $updateStmt->error;
            $updateStmt->close();
            return ['success' => false, 'message' => 'Failed to update password: ' . $error];
        }
    }
}
?>



