<?php

if (file_exists(__DIR__ . '/Logger.php')) {
    require_once __DIR__ . '/Logger.php';
}

/**
 * StockTaking Class for Physical Inventory Verification
 * Handles stock taking sessions for unique code-based inventory system
 */
class StockTaking {
    private $conn;
    private $logger;

    public function __construct($conn, $logger = null) {
        $this->conn = $conn;
        $this->logger = $logger;
    }

    /**
     * Start a new stock taking session (legacy method - use startSessionDual instead)
     *
     * @param int $branchId Branch ID
     * @param int $auditorId User ID of the auditor
     * @param string $notes Optional notes
     * @return int|bool Session ID on success, false on failure
     */
    public function startSession($branchId, $auditorId, $notes = null) {
        // For backward compatibility, determine user role and call new method
        $userRole = $this->getUserRole($auditorId);
        return $this->startSessionDual($branchId, $auditorId, $userRole, $notes);
    }

    /**
     * Start a stock taking session with dual verification support
     *
     * @param int $branchId Branch ID
     * @param int $userId User ID
     * @param string $userRole 'admin' or 'branch_manager'
     * @param string $notes Optional notes
     * @return int|bool Session ID on success, false on failure
     */
	 
    public function startSessionDual($branchId, $userId, $userRole, $notes = null) {
        try {
            error_log("StockTaking: Starting dual session - Branch: $branchId, User: $userId, Role: $userRole");

            // Validate user role
            if (!in_array($userRole, ['admin', 'branch_manager'])) {
                throw new Exception("Invalid user role: $userRole");
            }

            // Check if user has permission for this branch
            if ($userRole === 'branch_manager') {
                $userBranch = $this->getUserBranch($userId);
                if ($userBranch != $branchId) {
                    throw new Exception("Branch manager can only start sessions for their own branch.");
                }
            }

            // Check for existing active sessions for this branch (only block in_progress sessions)
            $checkSql = "SELECT session_id, session_status FROM stock_taking_sessions
                           WHERE branch_id = :branch_id AND session_status = 'in_progress'";
            $stmt = $this->conn->prepare($checkSql);
            $stmt->bindValue(':branch_id', $branchId, PDO::PARAM_INT);
            $stmt->execute();
            $existingSession = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($existingSession) {
                error_log("StockTaking: Found existing active session #{$existingSession['session_id']} with status {$existingSession['session_status']}");
                throw new Exception("An active stock taking session already exists for this branch (Session #{$existingSession['session_id']}, Status: {$existingSession['session_status']}). Please cancel the existing session before starting a new one.");
            }

            // Check if there's a pending session that needs the other party's start
            $pendingSql = "SELECT session_id, session_status,
                                   admin_started_by, branch_started_by
                            FROM stock_taking_sessions
                            WHERE branch_id = :branch_id AND session_status = 'pending_start'";
            $pendingStmt = $this->conn->prepare($pendingSql);
            $pendingStmt->bindValue(':branch_id', $branchId, PDO::PARAM_INT);
            $pendingStmt->execute();
            $pendingSession = $pendingStmt->fetch(PDO::FETCH_ASSOC);

            if ($pendingSession) {
                error_log("StockTaking: Found pending session #{$pendingSession['session_id']}, joining...");
                // Update existing pending session
                return $this->joinPendingSession($pendingSession['session_id'], $userId, $userRole);
            }

            // Count total system items for this branch
            $countSql = "SELECT COUNT(*) as total FROM items
                          WHERE current_location_id = :branch_id
                          AND item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id NOT LIKE '%_VERIFIED_%')";
            $countStmt = $this->conn->prepare($countSql);
            $countStmt->bindValue(':branch_id', $branchId, PDO::PARAM_INT);
            $countStmt->execute();
            $totalItems = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];

            error_log("StockTaking: Found $totalItems items for branch $branchId");

            // Create new session - use explicit column names instead of dynamic SQL
            if ($userRole === 'admin') {
                $sql = "INSERT INTO stock_taking_sessions
                        (branch_id, session_date, auditor_id, notes, total_system_items, session_status,
                         admin_started_by, admin_started_at)
                        VALUES (:branch_id, CURDATE(), :auditor_id, :notes, :total_items, 'pending_start',
                                :user_id, NOW())";
            } else {
                $sql = "INSERT INTO stock_taking_sessions
                        (branch_id, session_date, auditor_id, notes, total_system_items, session_status,
                         branch_started_by, branch_started_at)
                        VALUES (:branch_id, CURDATE(), :auditor_id, :notes, :total_items, 'pending_start',
                                :user_id, NOW())";
            }

            error_log("StockTaking: Executing SQL: $sql");

            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':branch_id', $branchId, PDO::PARAM_INT);
            $stmt->bindValue(':auditor_id', $userId, PDO::PARAM_INT);
            $stmt->bindValue(':notes', $notes, PDO::PARAM_STR);
            $stmt->bindValue(':total_items', $totalItems, PDO::PARAM_INT);
            $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);

            $result = $stmt->execute();

            if ($result) {
                $sessionId = $this->conn->lastInsertId();
                error_log("StockTaking: Created new session #$sessionId");

                // Record participant action
                $this->recordParticipantAction($sessionId, $userId, $userRole, 'started');

                // Log session creation
                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_STARTED', 'stock_taking',
                        "Started stock taking session for branch ID $branchId with $totalItems items (by $userRole)",
                        $sessionId, 'stock_taking_sessions');
                }

                return $sessionId;
            } else {
                $errorInfo = $stmt->errorInfo();
                error_log("StockTaking: Database error creating session: " . json_encode($errorInfo));
                throw new Exception("Database error: Failed to create session");
            }

        } catch (Exception $e) {
            error_log("StockTaking: Error starting stock taking session: " . $e->getMessage());
            // Re-throw the exception so the dashboard can show the specific error message
            throw $e;
        }
    }

    /**
     * Join a pending session started by the other party
     *
     * @param int $sessionId Session ID
     * @param int $userId User ID
     * @param string $userRole User role
     * @return int|bool Session ID on success, false on failure
     */
    private function joinPendingSession($sessionId, $userId, $userRole) {
        try {
            // Get current session state
            $sessionSql = "SELECT admin_started_by, branch_started_by FROM stock_taking_sessions
                          WHERE session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session) {
                throw new Exception("Session not found");
            }

            // Check if this user already started
            $alreadyStarted = ($userRole === 'admin' && $session['admin_started_by']) ||
                             ($userRole === 'branch_manager' && $session['branch_started_by']);

            if ($alreadyStarted) {
                throw new Exception("You have already started this session");
            }

            // Update session with this user's start
            $updateField = $userRole === 'admin' ? 'admin_started_by' : 'branch_started_by';
            $timeField = $userRole === 'admin' ? 'admin_started_at' : 'branch_started_at';

            $updateSql = "UPDATE stock_taking_sessions
                         SET $updateField = :user_id, {$timeField} = NOW(), session_status = 'in_progress'
                         WHERE session_id = :session_id";
            $updateStmt = $this->conn->prepare($updateSql);
            $updateStmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $updateStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);

            if ($updateStmt->execute()) {
                // Record participant action
                $this->recordParticipantAction($sessionId, $userId, $userRole, 'started');

                // Log session join
                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_JOINED', 'stock_taking',
                        "User joined stock taking session $sessionId as $userRole",
                        $sessionId, 'stock_taking_sessions');
                }

                return $sessionId;
            }

            return false;
        } catch (Exception $e) {
            error_log("Error joining pending session: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Record a participant action
     *
     * @param int $sessionId Session ID
     * @param int $userId User ID
     * @param string $userRole User role
     * @param string $action Action performed
     */
    private function recordParticipantAction($sessionId, $userId, $userRole, $action) {
        try {
            $sql = "INSERT INTO stock_taking_session_participants
                   (session_id, user_id, user_role, action)
                   VALUES (:session_id, :user_id, :user_role, :action)";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $stmt->bindValue(':user_role', $userRole, PDO::PARAM_STR);
            $stmt->bindValue(':action', $action, PDO::PARAM_STR);
            $stmt->execute();
        } catch (Exception $e) {
            error_log("Error recording participant action: " . $e->getMessage());
        }
    }

    /**
     * Get user role
     *
     * @param int $userId User ID
     * @return string User role
     */
    public function getUserRole($userId) {
        try {
            $sql = "SELECT role FROM users WHERE user_id = :user_id";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $stmt->execute();
            $result = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($result) {
                $role = $result['role'];
                if (in_array($role, ['super_admin', 'admin', 'warehouse'])) {
                    return 'admin';
                } elseif (in_array($role, ['branch_manager', 'branch'])) {
                    return 'branch_manager';
                }
            }
            return 'admin'; // Default fallback
        } catch (Exception $e) {
            error_log("Error getting user role: " . $e->getMessage());
            return 'admin';
        }
    }

    /**
     * Get user branch
     *
     * @param int $userId User ID
     * @return int|null Branch ID
     */
    private function getUserBranch($userId) {
        try {
            $sql = "SELECT branch_id FROM users WHERE user_id = :user_id";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $stmt->execute();
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result ? $result['branch_id'] : null;
        } catch (Exception $e) {
            error_log("Error getting user branch: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Get items for a stock taking session
     *
     * @param int $sessionId Session ID
     * @return array Array of items to verify
     */
    public function getSessionItems($sessionId) {
        try {
            error_log("StockTaking: getSessionItems called for session: $sessionId");

            // Get session info
            $sessionSql = "SELECT s.*,
                                  b.branch_name,
                                  u.username as auditor_name,
                                  admin_user.username as admin_started_name,
                                  branch_user.username as branch_started_name
                           FROM stock_taking_sessions s
                           JOIN branches b ON s.branch_id = b.branch_id
                           JOIN users u ON s.auditor_id = u.user_id
                           LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                           LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                           WHERE s.session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session) {
                error_log("StockTaking: Session $sessionId not found");
                return ['error' => 'Session not found'];
            }

            error_log("StockTaking: Found session $sessionId for branch {$session['branch_id']}, status: {$session['session_status']}");

            // Get all items currently at the branch
            $itemsSql = "SELECT i.item_id, i.item_name, i.item_details, i.unique_code, i.condition_status,
                                 i.unit_price, i.barcode_image_path
                          FROM items i
                          WHERE i.current_location_id = :branch_id
                          AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id LIKE '%\_VERIFIED\_%')
                          ORDER BY i.item_name";

            $itemsStmt = $this->conn->prepare($itemsSql);
            $itemsStmt->bindValue(':branch_id', $session['branch_id'], PDO::PARAM_INT);
            $itemsStmt->execute();
            $items = $itemsStmt->fetchAll(PDO::FETCH_ASSOC);

            error_log("StockTaking: Found " . count($items) . " items for branch {$session['branch_id']}");

            // Get existing verifications for this session
            $verificationsSql = "SELECT item_id, status, notes, location_found
                                 FROM stock_taking_verifications
                                 WHERE session_id = :session_id";
            $verificationsStmt = $this->conn->prepare($verificationsSql);
            $verificationsStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $verificationsStmt->execute();
            $verifications = $verificationsStmt->fetchAll(PDO::FETCH_ASSOC);

            error_log("StockTaking: Found " . count($verifications) . " existing verifications for session $sessionId");

            // Create lookup array for verifications
            $verificationLookup = [];
            foreach ($verifications as $verification) {
                $verificationLookup[$verification['item_id']] = $verification;
            }

            // Mark items with their verification status
            $verifiedCount = 0;
            foreach ($items as &$item) {
                if (isset($verificationLookup[$item['item_id']])) {
                    $item['verification_status'] = $verificationLookup[$item['item_id']]['status'];
                    $item['verification_notes'] = $verificationLookup[$item['item_id']]['notes'];
                    $item['location_found'] = $verificationLookup[$item['item_id']]['location_found'];
                    $verifiedCount++;
                } else {
                    $item['verification_status'] = 'pending';
                    $item['verification_notes'] = '';
                    $item['location_found'] = '';
                }
            }

            error_log("StockTaking: Session $sessionId has $verifiedCount verified items out of " . count($items) . " total items");

            return [
                'session' => $session,
                'items' => $items,
                'total_items' => count($items),
                'verified_items' => $verifiedCount
            ];
        } catch (Exception $e) {
            error_log("StockTaking: Error getting session items: " . $e->getMessage());
            return ['error' => 'Database error: ' . $e->getMessage()];
        }
    }

    /**
     * Record verification for an item
     *
     * @param int $sessionId Session ID
     * @param int $itemId Item ID (null for extra items)
     * @param string $uniqueCode Unique code
     * @param string $status 'found', 'missing', or 'extra'
     * @param int $verifiedBy User ID
     * @param string $notes Optional notes
     * @param string $locationFound Physical location
     * @return bool Success status
     */
    public function recordVerification($sessionId, $itemId, $uniqueCode, $status, $verifiedBy, $notes = null, $locationFound = null) {
        try {
            error_log("StockTaking: recordVerification called - Session: $sessionId, Item: $itemId, Code: $uniqueCode, Status: $status, User: $verifiedBy");

            // Validate status
            $validStatuses = ['found', 'missing', 'extra'];
            if (!in_array($status, $validStatuses)) {
                throw new Exception("Invalid status: $status");
            }

            // Check if session exists and is active
            $sessionCheckSql = "SELECT session_id, session_status FROM stock_taking_sessions WHERE session_id = :session_id";
            $sessionCheckStmt = $this->conn->prepare($sessionCheckSql);
            $sessionCheckStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionCheckStmt->execute();
            $sessionData = $sessionCheckStmt->fetch(PDO::FETCH_ASSOC);

            if (!$sessionData) {
                throw new Exception("Session $sessionId does not exist");
            }

            error_log("StockTaking: Session status check - Session: $sessionId, Status: {$sessionData['session_status']}");
            if ($sessionData['session_status'] !== 'in_progress') {
                throw new Exception("Session $sessionId is not in progress (status: {$sessionData['session_status']})");
            }

            // Check if item exists and belongs to the session's branch
            $itemCheckSql = "SELECT i.item_id, i.unique_code, i.current_location_id, s.branch_id
                            FROM items i
                            JOIN stock_taking_sessions s ON s.session_id = :session_id
                            WHERE i.item_id = :item_id AND i.unique_code = :unique_code";
            $itemCheckStmt = $this->conn->prepare($itemCheckSql);
            $itemCheckStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $itemCheckStmt->bindValue(':item_id', $itemId, PDO::PARAM_INT);
            $itemCheckStmt->bindValue(':unique_code', $uniqueCode, PDO::PARAM_STR);
            $itemCheckStmt->execute();
            $itemData = $itemCheckStmt->fetch(PDO::FETCH_ASSOC);

            error_log("StockTaking: Item validation - Item ID: $itemId, Code: $uniqueCode, Found: " . ($itemData ? 'YES' : 'NO'));
            if ($itemData) {
                error_log("StockTaking: Item details - Current location: {$itemData['current_location_id']}, Session branch: {$itemData['branch_id']}");
            }

            if (!$itemData) {
                throw new Exception("Item with ID $itemId and code $uniqueCode not found or doesn't belong to this session");
            }

            if ($itemData['current_location_id'] != $itemData['branch_id']) {
                error_log("StockTaking: Warning - Item $itemId is at location {$itemData['current_location_id']} but session is for branch {$itemData['branch_id']}");
            }

            // Check if verification already exists
            $checkSql = "SELECT verification_id, status FROM stock_taking_verifications
                         WHERE session_id = :session_id AND unique_code = :unique_code";
            $checkStmt = $this->conn->prepare($checkSql);
            $checkStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $checkStmt->bindValue(':unique_code', $uniqueCode, PDO::PARAM_STR);
            $checkStmt->execute();
            $existingVerification = $checkStmt->fetch(PDO::FETCH_ASSOC);

            error_log("StockTaking: Existing verification check - Session: $sessionId, Code: $uniqueCode, Found: " . ($existingVerification ? 'YES (ID: ' . $existingVerification['verification_id'] . ', Status: ' . $existingVerification['status'] . ')' : 'NO'));

            if ($existingVerification) {
                // Update existing verification
                $sql = "UPDATE stock_taking_verifications
                        SET status = :status, notes = :notes, location_found = :location_found,
                            verified_at = NOW(), verified_by = :verified_by
                        WHERE session_id = :session_id AND unique_code = :unique_code";
                error_log("StockTaking: Updating existing verification for $uniqueCode");
            } else {
                // Insert new verification
                $sql = "INSERT INTO stock_taking_verifications
                        (session_id, item_id, unique_code, status, notes, verified_by, location_found)
                        VALUES (:session_id, :item_id, :unique_code, :status, :notes, :verified_by, :location_found)";
                error_log("StockTaking: Creating new verification for $uniqueCode");
            }

            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $stmt->bindValue(':unique_code', $uniqueCode, PDO::PARAM_STR);
            $stmt->bindValue(':status', $status, PDO::PARAM_STR);
            $stmt->bindValue(':notes', $notes, PDO::PARAM_STR);
            $stmt->bindValue(':verified_by', $verifiedBy, PDO::PARAM_INT);
            $stmt->bindValue(':location_found', $locationFound, PDO::PARAM_STR);

            // Only bind item_id for INSERT, not for UPDATE
            if (!$existingVerification) {
                $stmt->bindValue(':item_id', $itemId, PDO::PARAM_INT);
            }

            error_log("StockTaking: About to execute SQL: " . ($existingVerification ? 'UPDATE' : 'INSERT'));
            $result = $stmt->execute();

            if ($result) {
                error_log("StockTaking: Verification recorded successfully for $uniqueCode");
                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_VERIFICATION', 'stock_taking',
                        "Item $uniqueCode marked as $status in session $sessionId",
                        $sessionId, 'stock_taking_sessions');
                }
                return true;
            } else {
                $errorInfo = $stmt->errorInfo();
                error_log("StockTaking: Database error recording verification: " . json_encode($errorInfo));
                error_log("StockTaking: SQL that failed: $sql");
                return false;
            }
        } catch (Exception $e) {
            error_log("StockTaking: Error recording verification: " . $e->getMessage());
            return false;
        }
    }


    /**
     * Record that a user has previewed the session (with dual verification that completes session)
     *
     * @param int $sessionId Session ID
     * @param int $userId User ID
     * @param string $userRole User role
     * @return bool Success status
     */
    public function recordPreview($sessionId, $userId, $userRole) {
        try {
            // Validate user role
            if (!in_array($userRole, ['admin', 'branch_manager'])) {
                throw new Exception("Invalid user role: $userRole");
            }

            // Check session status - now accepts 'in_progress' directly (after all items verified)
            $sessionSql = "SELECT session_status, admin_preview_at, branch_preview_at
                          FROM stock_taking_sessions WHERE session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session || !in_array($session['session_status'], ['in_progress', 'pending_preview'])) {
                throw new Exception("Session is not ready for preview");
            }

            // Check if user already previewed
            $alreadyPreviewed = ($userRole === 'admin' && $session['admin_preview_at']) ||
                               ($userRole === 'branch_manager' && $session['branch_preview_at']);

            if ($alreadyPreviewed) {
                throw new Exception("You have already previewed this session");
            }

            // Update preview timestamp and verification fields
            $previewField = $userRole === 'admin' ? 'admin_preview_at' : 'branch_preview_at';
            $verifyField = $userRole === 'admin' ? 'admin_verified_by' : 'branch_verified_by';
            $verifyTimeField = $userRole === 'admin' ? 'admin_verified_at' : 'branch_verified_at';

            $updateSql = "UPDATE stock_taking_sessions
                         SET {$previewField} = NOW(), {$verifyField} = :user_id, {$verifyTimeField} = NOW()
                         WHERE session_id = :session_id";
            $updateStmt = $this->conn->prepare($updateSql);
            $updateStmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $updateStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);

            if ($updateStmt->execute()) {
                // Record participant actions
                $this->recordParticipantAction($sessionId, $userId, $userRole, 'previewed');
                $this->recordParticipantAction($sessionId, $userId, $userRole, 'verified');

                // Check if both have previewed, then complete the session
                $checkSql = "SELECT admin_preview_at, branch_preview_at FROM stock_taking_sessions
                            WHERE session_id = :session_id";
                $checkStmt = $this->conn->prepare($checkSql);
                $checkStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
                $checkStmt->execute();
                $checkResult = $checkStmt->fetch(PDO::FETCH_ASSOC);

                if ($checkResult['admin_preview_at'] && $checkResult['branch_preview_at']) {
                    // Both have previewed and verified, complete the session
                    return $this->finalizeSession($sessionId);
                }

                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_PREVIEWED', 'stock_taking',
                        "User previewed and verified stock taking session $sessionId as $userRole",
                        $sessionId, 'stock_taking_sessions');
                }

                return true;
            }

            return false;
        } catch (Exception $e) {
            error_log("Error recording preview: " . $e->getMessage());
            return false;
        }
    }


    /**
     * Finalize session completion (called when both parties have verified)
     *
     * @param int $sessionId Session ID
     * @return bool Success status
     */
    private function finalizeSession($sessionId) {
        try {
            $this->conn->beginTransaction();

            // Calculate final counts
            $statsSql = "SELECT
                             COUNT(CASE WHEN status = 'found' THEN 1 END) as found_count,
                             COUNT(CASE WHEN status = 'missing' THEN 1 END) as missing_count,
                             COUNT(CASE WHEN status = 'extra' THEN 1 END) as extra_count
                          FROM stock_taking_verifications
                          WHERE session_id = :session_id";

            $statsStmt = $this->conn->prepare($statsSql);
            $statsStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $statsStmt->execute();
            $stats = $statsStmt->fetch(PDO::FETCH_ASSOC);

            // Ensure stats are not null
            $foundCount = (int)($stats['found_count'] ?? 0);
            $missingCount = (int)($stats['missing_count'] ?? 0);
            $extraCount = (int)($stats['extra_count'] ?? 0);

            // Update session with final counts and status
            $updateSql = "UPDATE stock_taking_sessions
                          SET session_status = 'completed', status = 'completed',
                              completed_at = NOW(),
                              total_found_items = :found,
                              total_missing_items = :missing,
                              total_extra_items = :extra
                          WHERE session_id = :session_id";

            $updateStmt = $this->conn->prepare($updateSql);
            $updateStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $updateStmt->bindValue(':found', $foundCount, PDO::PARAM_INT);
            $updateStmt->bindValue(':missing', $missingCount, PDO::PARAM_INT);
            $updateStmt->bindValue(':extra', $extraCount, PDO::PARAM_INT);

            $result = $updateStmt->execute();

            if ($result) {
                $this->conn->commit();

                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_COMPLETED', 'stock_taking',
                        "Completed stock taking session: {$foundCount} found, {$missingCount} missing, {$extraCount} extra",
                        $sessionId, 'stock_taking_sessions');
                }

                return true;
            } else {
                $this->conn->rollBack();
                error_log("Failed to execute update query for session completion");
                return false;
            }
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error finalizing session: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Complete a stock taking session (legacy method - use verifySessionCompletion instead)
     *
     * @param int $sessionId Session ID
     * @return bool Success status
     */
    public function completeSession($sessionId) {
        // For backward compatibility, try to complete directly
        // This should only be used for single-user completion in edge cases
        return $this->finalizeSession($sessionId);
    }

    /**
     * Get detailed session status including participant information
     *
     * @param int $sessionId Session ID
     * @return array Session status data
     */
    public function getSessionStatus($sessionId) {
        try {
            // Get session info with participant details
            $sessionSql = "SELECT s.*,
                                  b.branch_name,
                                  u.username as auditor_name,
                                  admin_user.username as admin_started_name,
                                  branch_user.username as branch_started_name,
                                  admin_verifier.username as admin_verified_name,
                                  branch_verifier.username as branch_verified_name
                           FROM stock_taking_sessions s
                           JOIN branches b ON s.branch_id = b.branch_id
                           JOIN users u ON s.auditor_id = u.user_id
                           LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                           LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                           LEFT JOIN users admin_verifier ON s.admin_verified_by = admin_verifier.user_id
                           LEFT JOIN users branch_verifier ON s.branch_verified_by = branch_verifier.user_id
                           WHERE s.session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session) {
                return ['error' => 'Session not found'];
            }

            // Get participant actions
            $participantsSql = "SELECT * FROM stock_taking_session_participants
                               WHERE session_id = :session_id
                               ORDER BY action_at DESC";
            $participantsStmt = $this->conn->prepare($participantsSql);
            $participantsStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $participantsStmt->execute();
            $participants = $participantsStmt->fetchAll(PDO::FETCH_ASSOC);

            // Calculate progress
            $sessionData = $this->getSessionItems($sessionId);
            $progress = isset($sessionData['error']) ? 0 :
                       ($sessionData['total_items'] > 0 ?
                        round(($sessionData['verified_items'] / $sessionData['total_items']) * 100, 1) : 0);

            return [
                'session' => $session,
                'participants' => $participants,
                'progress' => $progress,
                'can_start' => [
                    'admin' => !$session['admin_started_by'],
                    'branch_manager' => !$session['branch_started_by']
                ],
                'can_preview' => [
                    'admin' => $session['session_status'] === 'in_progress' && !$session['admin_preview_at'],
                    'branch_manager' => $session['session_status'] === 'in_progress' && !$session['branch_preview_at']
                ],
                'is_complete' => $session['session_status'] === 'completed'
            ];
        } catch (Exception $e) {
            error_log("Error getting session status: " . $e->getMessage());
            return ['error' => 'Database error: ' . $e->getMessage()];
        }
    }

    /**
     * Get session report
     *
     * @param int $sessionId Session ID
     * @return array Session report data
     */
    public function getSessionReport($sessionId) {
        try {
            error_log("StockTaking: Getting report for session ID: $sessionId");

            // Get session info with participant details
            $sessionSql = "SELECT s.*,
                                  b.branch_name,
                                  u.username as auditor_name,
                                  admin_user.username as admin_started_name,
                                  branch_user.username as branch_started_name,
                                  admin_verifier.username as admin_verified_name,
                                  branch_verifier.username as branch_verified_name
                           FROM stock_taking_sessions s
                           JOIN branches b ON s.branch_id = b.branch_id
                           JOIN users u ON s.auditor_id = u.user_id
                           LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                           LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                           LEFT JOIN users admin_verifier ON s.admin_verified_by = admin_verifier.user_id
                           LEFT JOIN users branch_verifier ON s.branch_verified_by = branch_verifier.user_id
                           WHERE s.session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session) {
                error_log("StockTaking: Session not found for ID: $sessionId");
                return ['error' => 'Session not found'];
            }

            error_log("StockTaking: Found session, status: " . $session['session_status']);

            // Get all verifications
            $verificationsSql = "SELECT v.*, i.item_name, i.item_details
                                 FROM stock_taking_verifications v
                                 LEFT JOIN items i ON v.item_id = i.item_id
                                 WHERE v.session_id = :session_id
                                 ORDER BY v.status, v.unique_code";
            $verificationsStmt = $this->conn->prepare($verificationsSql);
            $verificationsStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $verificationsStmt->execute();
            $verifications = $verificationsStmt->fetchAll(PDO::FETCH_ASSOC);

            // Group by status
            $found = array_filter($verifications, function($v) { return $v['status'] === 'found'; });
            $missing = array_filter($verifications, function($v) { return $v['status'] === 'missing'; });
            $extra = array_filter($verifications, function($v) { return $v['status'] === 'extra'; });

            return [
                'session' => $session,
                'found_items' => $found,
                'missing_items' => $missing,
                'extra_items' => $extra,
                'summary' => [
                    'total_system' => $session['total_system_items'],
                    'total_found' => count($found),
                    'total_missing' => count($missing),
                    'total_extra' => count($extra)
                ]
            ];
        } catch (Exception $e) {
            error_log("Error getting session report: " . $e->getMessage());
            return ['error' => 'Database error: ' . $e->getMessage()];
        }
    }

    /**
     * Get all sessions for a branch
     *
     * @param int $branchId Branch ID
     * @return array Array of sessions
     */
    public function getBranchSessions($branchId) {
        try {
            $sql = "SELECT s.*,
                           u.username as auditor_name,
                           admin_user.username as admin_started_name,
                           branch_user.username as branch_started_name,
                           admin_verifier.username as admin_verified_name,
                           branch_verifier.username as branch_verified_name
                    FROM stock_taking_sessions s
                    JOIN users u ON s.auditor_id = u.user_id
                    LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                    LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                    LEFT JOIN users admin_verifier ON s.admin_verified_by = admin_verifier.user_id
                    LEFT JOIN users branch_verifier ON s.branch_verified_by = branch_verifier.user_id
                    WHERE s.branch_id = :branch_id
                    ORDER BY s.session_date DESC, s.created_at DESC";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':branch_id', $branchId, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting branch sessions: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Get sessions accessible to a user based on their role and branch
     *
     * @param int $userId User ID
     * @param string $userRole User role ('admin' or 'branch_manager')
     * @return array Array of accessible sessions
     */
    public function getUserSessions($userId, $userRole) {
        try {
            if ($userRole === 'admin') {
                // Admins can see all sessions
                $sql = "SELECT s.*,
                               b.branch_name,
                               u.username as auditor_name,
                               admin_user.username as admin_started_name,
                               branch_user.username as branch_started_name,
                               admin_verifier.username as admin_verified_name,
                               branch_verifier.username as branch_verified_name
                        FROM stock_taking_sessions s
                        JOIN branches b ON s.branch_id = b.branch_id
                        JOIN users u ON s.auditor_id = u.user_id
                        LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                        LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                        LEFT JOIN users admin_verifier ON s.admin_verified_by = admin_verifier.user_id
                        LEFT JOIN users branch_verifier ON s.branch_verified_by = branch_verifier.user_id
                        ORDER BY s.session_date DESC, s.created_at DESC";
                $stmt = $this->conn->prepare($sql);
            } else {
                // Branch managers can only see sessions for their branch
                $userBranch = $this->getUserBranch($userId);
                if (!$userBranch) {
                    return [];
                }

                $sql = "SELECT s.*,
                               b.branch_name,
                               u.username as auditor_name,
                               admin_user.username as admin_started_name,
                               branch_user.username as branch_started_name,
                               admin_verifier.username as admin_verified_name,
                               branch_verifier.username as branch_verified_name
                        FROM stock_taking_sessions s
                        JOIN branches b ON s.branch_id = b.branch_id
                        JOIN users u ON s.auditor_id = u.user_id
                        LEFT JOIN users admin_user ON s.admin_started_by = admin_user.user_id
                        LEFT JOIN users branch_user ON s.branch_started_by = branch_user.user_id
                        LEFT JOIN users admin_verifier ON s.admin_verified_by = admin_verifier.user_id
                        LEFT JOIN users branch_verifier ON s.branch_verified_by = branch_verifier.user_id
                        WHERE s.branch_id = :branch_id
                        ORDER BY s.session_date DESC, s.created_at DESC";
                $stmt = $this->conn->prepare($sql);
                $stmt->bindValue(':branch_id', $userBranch, PDO::PARAM_INT);
            }

            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting user sessions: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Cancel a stock taking session
     *
     * @param int $sessionId Session ID
     * @return bool Success status
     */
    public function cancelSession($sessionId) {
        try {
            $sql = "UPDATE stock_taking_sessions
                   SET session_status = 'cancelled', status = 'cancelled'
                   WHERE session_id = :session_id";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $result = $stmt->execute();

            if ($result && $this->logger) {
                $this->logger->log('STOCK_TAKING_CANCELLED', 'stock_taking',
                    "Cancelled stock taking session $sessionId",
                    $sessionId, 'stock_taking_sessions');
            }

            return $result;
        } catch (Exception $e) {
            error_log("Error cancelling session: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Get item quantity summary by item name for a session
     *
     * @param int $sessionId Session ID
     * @return array Array of item names with their quantities by status
     */
    public function getItemQuantitySummary($sessionId) {
        try {
            // Get session branch
            $sessionSql = "SELECT branch_id FROM stock_taking_sessions WHERE session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session) {
                return ['error' => 'Session not found'];
            }

            // Get all items for this branch with their verification status
            $sql = "SELECT
                        i.item_name,
                        GROUP_CONCAT(DISTINCT NULLIF(i.item_details, '') SEPARATOR '; ') AS item_details,
                        COUNT(*) as total_system_quantity,
                        SUM(CASE WHEN v.status = 'found' THEN 1 ELSE 0 END) as found_quantity,
                        SUM(CASE WHEN v.status = 'missing' THEN 1 ELSE 0 END) as missing_quantity,
                        SUM(CASE WHEN v.status = 'extra' THEN 1 ELSE 0 END) as extra_quantity
                    FROM items i
                    LEFT JOIN stock_taking_verifications v ON i.item_id = v.item_id AND v.session_id = :session_id
                    WHERE i.current_location_id = :branch_id
                    AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id NOT LIKE '%_VERIFIED_%')
                    GROUP BY i.item_name
                    ORDER BY i.item_name";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $stmt->bindValue(':branch_id', $session['branch_id'], PDO::PARAM_INT);
            $stmt->execute();

            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Calculate verified quantity (found + missing)
            foreach ($results as &$result) {
                $result['verified_quantity'] = ($result['found_quantity'] ?? 0) + ($result['missing_quantity'] ?? 0);
                $result['pending_quantity'] = ($result['total_system_quantity'] ?? 0) - ($result['verified_quantity'] ?? 0);
            }

            return $results;
        } catch (Exception $e) {
            error_log("Error getting item quantity summary: " . $e->getMessage());
            return ['error' => 'Database error: ' . $e->getMessage()];
        }
    }

    /**
     * Request a report update for a completed session
     *
     * @param int $sessionId Session ID
     * @param int $userId User ID requesting the update
     * @param string $reason Reason for the update
     * @param array $updateData Array of item updates (unique_code => new_status)
     * @return int|bool Update request ID on success, false on failure
     */
    public function requestReportUpdate($sessionId, $userId, $reason, $updateData) {
        try {
            // Verify session is completed
            $sessionSql = "SELECT session_status FROM stock_taking_sessions WHERE session_id = :session_id";
            $sessionStmt = $this->conn->prepare($sessionSql);
            $sessionStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $sessionStmt->execute();
            $session = $sessionStmt->fetch(PDO::FETCH_ASSOC);

            if (!$session || $session['session_status'] !== 'completed') {
                throw new Exception("Session is not completed or does not exist");
            }

            // Check if there's already a pending update request
            $checkSql = "SELECT update_id FROM stock_taking_report_updates
                        WHERE session_id = :session_id AND status = 'pending'";
            $checkStmt = $this->conn->prepare($checkSql);
            $checkStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $checkStmt->execute();

            if ($checkStmt->fetch()) {
                throw new Exception("There is already a pending update request for this session");
            }

            // Validate update data
            if (empty($updateData) || !is_array($updateData)) {
                throw new Exception("Update data is required");
            }

            // Insert update request
            $insertSql = "INSERT INTO stock_taking_report_updates
                         (session_id, requested_by, update_reason, update_data)
                         VALUES (:session_id, :requested_by, :update_reason, :update_data)";
            $insertStmt = $this->conn->prepare($insertSql);
            $insertStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $insertStmt->bindValue(':requested_by', $userId, PDO::PARAM_INT);
            $insertStmt->bindValue(':update_reason', $reason, PDO::PARAM_STR);
            $insertStmt->bindValue(':update_data', json_encode($updateData), PDO::PARAM_STR);

            if ($insertStmt->execute()) {
                $updateId = $this->conn->lastInsertId();

                if ($this->logger) {
                    $this->logger->log('STOCK_TAKING_UPDATE_REQUESTED', 'stock_taking',
                        "Report update requested for session $sessionId by user $userId",
                        $sessionId, 'stock_taking_sessions');
                }

                return $updateId;
            }

            return false;
        } catch (Exception $e) {
            error_log("Error requesting report update: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Approve a report update request
     *
     * @param int $updateId Update request ID
     * @param int $userId User ID approving
     * @param string $userRole User role ('admin', 'branch_manager', etc.)
     * @return bool Success status
     */
    public function approveReportUpdate($updateId, $userId, $userRole) {
        try {
            // Get update request
            $selectSql = "SELECT * FROM stock_taking_report_updates WHERE update_id = :update_id";
            $selectStmt = $this->conn->prepare($selectSql);
            $selectStmt->bindValue(':update_id', $updateId, PDO::PARAM_INT);
            $selectStmt->execute();
            $update = $selectStmt->fetch(PDO::FETCH_ASSOC);

            if (!$update || $update['status'] !== 'pending') {
                throw new Exception("Update request not found or not pending");
            }

            // Only admin can approve updates (warehouse, branch_manager, assistant can only request)
            if ($userRole !== 'admin') {
                throw new Exception("Only administrators can approve update requests");
            }

            // Check if admin already approved
            if ($update['admin_approved_by']) {
                throw new Exception("This update has already been approved");
            }

            // Update admin approval
            $updateSql = "UPDATE stock_taking_report_updates
                         SET admin_approved_by = :user_id, admin_approved_at = NOW(),
                             status = 'approved'
                         WHERE update_id = :update_id";
            $updateStmt = $this->conn->prepare($updateSql);
            $updateStmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $updateStmt->bindValue(':update_id', $updateId, PDO::PARAM_INT);

            if ($updateStmt->execute()) {
                // Admin approval is sufficient, apply the update immediately
                // Note: applyReportUpdate expects status to be 'pending', so we need to handle this differently
                return $this->applyApprovedUpdate($updateId);
            }

            return false;
        } catch (Exception $e) {
            error_log("Error approving report update: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Apply an approved report update (for already approved updates)
     *
     * @param int $updateId Update request ID
     * @return bool Success status
     */
    private function applyApprovedUpdate($updateId) {
        try {
            $this->conn->beginTransaction();

            // Get update request
            $selectSql = "SELECT * FROM stock_taking_report_updates WHERE update_id = :update_id";
            $selectStmt = $this->conn->prepare($selectSql);
            $selectStmt->bindValue(':update_id', $updateId, PDO::PARAM_INT);
            $selectStmt->execute();
            $update = $selectStmt->fetch(PDO::FETCH_ASSOC);

            if (!$update || $update['status'] !== 'approved') {
                throw new Exception("Update request not found or not approved");
            }

            $updateData = json_decode($update['update_data'], true);
            $sessionId = $update['session_id'];

            // Apply each update
            foreach ($updateData as $uniqueCode => $newStatus) {
                // Validate status
                $validStatuses = ['found', 'missing', 'extra'];
                if (!in_array($newStatus, $validStatuses)) {
                    throw new Exception("Invalid status: $newStatus");
                }

                // Update verification
                $updateSql = "UPDATE stock_taking_verifications
                             SET status = :status, verified_at = NOW()
                             WHERE session_id = :session_id AND unique_code = :unique_code";
                $updateStmt = $this->conn->prepare($updateSql);
                $updateStmt->bindValue(':status', $newStatus, PDO::PARAM_STR);
                $updateStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
                $updateStmt->bindValue(':unique_code', $uniqueCode, PDO::PARAM_STR);
                $updateStmt->execute();
            }

            // Update session totals
            $this->updateSessionTotals($sessionId);

            // Mark update as completed
            $completeSql = "UPDATE stock_taking_report_updates
                           SET status = 'completed', completed_at = NOW()
                           WHERE update_id = :update_id";
            $completeStmt = $this->conn->prepare($completeSql);
            $completeStmt->bindValue(':update_id', $updateId, PDO::PARAM_INT);
            $completeStmt->execute();

            $this->conn->commit();

            if ($this->logger) {
                $this->logger->log('STOCK_TAKING_UPDATE_COMPLETED', 'stock_taking',
                    "Report update $updateId applied to session $sessionId",
                    $sessionId, 'stock_taking_sessions');
            }

            return true;
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error applying report update: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Update session totals after changes
     *
     * @param int $sessionId Session ID
     */
    private function updateSessionTotals($sessionId) {
        try {
            // Calculate final counts
            $statsSql = "SELECT
                          COUNT(CASE WHEN status = 'found' THEN 1 END) as found_count,
                          COUNT(CASE WHEN status = 'missing' THEN 1 END) as missing_count,
                          COUNT(CASE WHEN status = 'extra' THEN 1 END) as extra_count
                         FROM stock_taking_verifications
                         WHERE session_id = :session_id";

            $statsStmt = $this->conn->prepare($statsSql);
            $statsStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $statsStmt->execute();
            $stats = $statsStmt->fetch(PDO::FETCH_ASSOC);

            // Update session
            $updateSql = "UPDATE stock_taking_sessions
                         SET total_found_items = :found,
                             total_missing_items = :missing,
                             total_extra_items = :extra
                         WHERE session_id = :session_id";

            $updateStmt = $this->conn->prepare($updateSql);
            $updateStmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $updateStmt->bindValue(':found', (int)($stats['found_count'] ?? 0), PDO::PARAM_INT);
            $updateStmt->bindValue(':missing', (int)($stats['missing_count'] ?? 0), PDO::PARAM_INT);
            $updateStmt->bindValue(':extra', (int)($stats['extra_count'] ?? 0), PDO::PARAM_INT);
            $updateStmt->execute();
        } catch (Exception $e) {
            error_log("Error updating session totals: " . $e->getMessage());
        }
    }

    /**
     * Get pending update requests for a session
     *
     * @param int $sessionId Session ID
     * @return array Array of pending update requests
     */
    public function getPendingUpdateRequests($sessionId) {
        try {
            $sql = "SELECT u.*,
                           r.username as requested_by_name,
                           a.username as admin_approved_name
                    FROM stock_taking_report_updates u
                    LEFT JOIN users r ON u.requested_by = r.user_id
                    LEFT JOIN users a ON u.admin_approved_by = a.user_id
                    WHERE u.session_id = :session_id AND u.status = 'pending'
                    ORDER BY u.requested_at DESC";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':session_id', $sessionId, PDO::PARAM_INT);
            $stmt->execute();

            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting pending update requests: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Check if a user can perform an action on a session
     *
     * @param int $sessionId Session ID
     * @param int $userId User ID
     * @param string $userRole User role
     * @param string $action Action to check ('start', 'preview', 'verify')
     * @return bool Whether the action is allowed
     */
	
	 
	 
	 
    public function canUserPerformAction($sessionId, $userId, $userRole, $action) {
        try {
            $status = $this->getSessionStatus($sessionId);
            if (isset($status['error'])) {
                return false;
            }

            switch ($action) {
                case 'start':
                    return $status['can_start'][$userRole];
                case 'preview':
                    return $status['can_preview'][$userRole];
                default:
                    return false;
            }
        } catch (Exception $e) {
            error_log("Error checking user action permission: " . $e->getMessage());
            return false;
        }
    }
	
	
	
	
	
}
?>