<?php
/**
 * ProductLogger - Centralized logging system for product-related activities
 * Provides comprehensive audit trail for all product management operations
 */

class ProductLogger {
    private $conn;
    private $userId;
    private $userName;
    private $userRole;
    private $ipAddress;
    private $userAgent;
    private $sessionId;
    
    public function __construct($database, $user = null) {
        $this->conn = $database;
        
        if ($user) {
            $this->userId = $user['id'];
            $this->userName = $user['name'] ?? $user['username'] ?? 'Unknown';
            $this->userRole = $user['role'] ?? 'user';
        }
        
        $this->ipAddress = $_SERVER['REMOTE_ADDR'] ?? null;
        $this->userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        $this->sessionId = session_id() ?: null;
    }
    
    /**
     * Log product creation
     */
    public function logProductCreate($productId, $productData) {
        return $this->log([
            'activity_type' => 'product_create',
            'product_id' => $productId,
            'action_description' => "Created product: {$productData['name']} ({$productData['product_code']})",
            'new_values' => json_encode($productData),
            'severity' => 'medium',
            'tags' => json_encode(['product', 'create', 'catalog'])
        ]);
    }
    
    /**
     * Log product updates
     */
    public function logProductUpdate($productId, $oldData, $newData) {
        $changes = $this->getChanges($oldData, $newData);
        $changeDescription = $this->formatChanges($changes);
        
        return $this->log([
            'activity_type' => 'product_update',
            'product_id' => $productId,
            'action_description' => "Updated product: {$newData['name']} - {$changeDescription}",
            'old_values' => json_encode($oldData),
            'new_values' => json_encode($newData),
            'severity' => 'medium',
            'tags' => json_encode(['product', 'update', 'catalog'])
        ]);
    }
    
    /**
     * Log product deletion
     */
    public function logProductDelete($productId, $productData) {
        return $this->log([
            'activity_type' => 'product_delete',
            'product_id' => $productId,
            'action_description' => "Deleted product: {$productData['name']} ({$productData['product_code']})",
            'old_values' => json_encode($productData),
            'severity' => 'high',
            'tags' => json_encode(['product', 'delete', 'catalog'])
        ]);
    }
    
    /**
     * Log product status changes
     */
    public function logProductStatusChange($productId, $productName, $oldStatus, $newStatus) {
        $statusText = $newStatus ? 'activated' : 'deactivated';
        
        return $this->log([
            'activity_type' => 'product_status_change',
            'product_id' => $productId,
            'action_description' => "Product {$statusText}: {$productName}",
            'old_values' => json_encode(['is_active' => $oldStatus]),
            'new_values' => json_encode(['is_active' => $newStatus]),
            'severity' => 'medium',
            'tags' => json_encode(['product', 'status', 'catalog'])
        ]);
    }
    
    /**
     * Log category operations
     */
    public function logCategoryCreate($categoryId, $categoryData) {
        return $this->log([
            'activity_type' => 'category_create',
            'category_id' => $categoryId,
            'action_description' => "Created category: {$categoryData['name']}",
            'new_values' => json_encode($categoryData),
            'severity' => 'medium',
            'tags' => json_encode(['category', 'create'])
        ]);
    }
    
    public function logCategoryUpdate($categoryId, $oldData, $newData) {
        $changes = $this->getChanges($oldData, $newData);
        $changeDescription = $this->formatChanges($changes);
        
        return $this->log([
            'activity_type' => 'category_update',
            'category_id' => $categoryId,
            'action_description' => "Updated category: {$newData['name']} - {$changeDescription}",
            'old_values' => json_encode($oldData),
            'new_values' => json_encode($newData),
            'severity' => 'medium',
            'tags' => json_encode(['category', 'update'])
        ]);
    }
    
    public function logCategoryDelete($categoryId, $categoryData) {
        return $this->log([
            'activity_type' => 'category_delete',
            'category_id' => $categoryId,
            'action_description' => "Deleted category: {$categoryData['name']}",
            'old_values' => json_encode($categoryData),
            'severity' => 'high',
            'tags' => json_encode(['category', 'delete'])
        ]);
    }
    
    /**
     * Log pricing operations
     */
    public function logPricingUpdate($productId, $productName, $pricingData) {
        return $this->log([
            'activity_type' => 'pricing_update',
            'product_id' => $productId,
            'action_description' => "Updated pricing for: {$productName}",
            'new_values' => json_encode($pricingData),
            'severity' => 'medium',
            'tags' => json_encode(['pricing', 'update'])
        ]);
    }
    
    /**
     * Log stock operations
     */
    public function logStockAdjustment($productId, $productName, $oldStock, $newStock, $reason = '') {
        $change = $newStock - $oldStock;
        $changeText = $change > 0 ? "increased by {$change}" : "decreased by " . abs($change);
        
        return $this->log([
            'activity_type' => 'stock_adjustment',
            'product_id' => $productId,
            'action_description' => "Stock {$changeText} for: {$productName}" . ($reason ? " - {$reason}" : ""),
            'old_values' => json_encode(['total_stock' => $oldStock]),
            'new_values' => json_encode(['total_stock' => $newStock]),
            'severity' => 'medium',
            'tags' => json_encode(['stock', 'adjustment'])
        ]);
    }
    
    public function logStockReservation($productId, $productName, $quantity, $registrationId) {
        return $this->log([
            'activity_type' => 'stock_reservation',
            'product_id' => $productId,
            'registration_id' => $registrationId,
            'action_description' => "Reserved {$quantity} units of: {$productName}",
            'new_values' => json_encode(['quantity' => $quantity, 'registration_id' => $registrationId]),
            'severity' => 'low',
            'tags' => json_encode(['stock', 'reservation'])
        ]);
    }
    
    public function logStockConfirmation($productId, $productName, $quantity, $registrationId) {
        return $this->log([
            'activity_type' => 'stock_confirmation',
            'product_id' => $productId,
            'registration_id' => $registrationId,
            'action_description' => "Confirmed {$quantity} units of: {$productName}",
            'new_values' => json_encode(['quantity' => $quantity, 'registration_id' => $registrationId]),
            'severity' => 'medium',
            'tags' => json_encode(['stock', 'confirmation'])
        ]);
    }
    
    /**
     * Log purchase operations
     */
    public function logPurchaseStatusChange($registrationId, $productName, $oldStatus, $newStatus) {
        return $this->log([
            'activity_type' => 'purchase_update',
            'registration_id' => $registrationId,
            'action_description' => "Purchase status changed from {$oldStatus} to {$newStatus} for: {$productName}",
            'old_values' => json_encode(['status' => $oldStatus]),
            'new_values' => json_encode(['status' => $newStatus]),
            'severity' => 'medium',
            'tags' => json_encode(['purchase', 'status'])
        ]);
    }
    
    /**
     * Log bulk operations
     */
    public function logBulkOperation($operationType, $affectedCount, $description) {
        return $this->log([
            'activity_type' => 'bulk_operation',
            'action_description' => $description,
            'affected_count' => $affectedCount,
            'severity' => 'high',
            'tags' => json_encode(['bulk', $operationType])
        ]);
    }
    
    /**
     * Core logging method
     */
    private function log($data) {
        try {
            $sql = "INSERT INTO product_activity_log (
                activity_type, product_id, category_id, pricing_id, registration_id,
                user_id, user_name, user_role, action_description, old_values, new_values,
                ip_address, user_agent, session_id, affected_count, severity, tags
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            $stmt = $this->conn->prepare($sql);
            return $stmt->execute([
                $data['activity_type'],
                $data['product_id'] ?? null,
                $data['category_id'] ?? null,
                $data['pricing_id'] ?? null,
                $data['registration_id'] ?? null,
                $this->userId,
                $this->userName,
                $this->userRole,
                $data['action_description'],
                $data['old_values'] ?? null,
                $data['new_values'] ?? null,
                $this->ipAddress,
                $this->userAgent,
                $this->sessionId,
                $data['affected_count'] ?? 1,
                $data['severity'] ?? 'medium',
                $data['tags'] ?? null
            ]);
        } catch (Exception $e) {
            error_log("ProductLogger Error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get recent activities
     */
    public function getRecentActivities($limit = 50, $filters = []) {
        $sql = "SELECT * FROM recent_product_activities WHERE 1=1";
        $params = [];
        
        if (!empty($filters['activity_type'])) {
            $sql .= " AND activity_type = ?";
            $params[] = $filters['activity_type'];
        }
        
        if (!empty($filters['product_id'])) {
            $sql .= " AND product_id = ?";
            $params[] = $filters['product_id'];
        }
        
        if (!empty($filters['user_id'])) {
            $sql .= " AND user_id = ?";
            $params[] = $filters['user_id'];
        }
        
        if (!empty($filters['severity'])) {
            $sql .= " AND severity = ?";
            $params[] = $filters['severity'];
        }
        
        if (!empty($filters['date_from'])) {
            $sql .= " AND created_at >= ?";
            $params[] = $filters['date_from'];
        }
        
        if (!empty($filters['date_to'])) {
            $sql .= " AND created_at <= ?";
            $params[] = $filters['date_to'];
        }
        
        $sql .= " ORDER BY created_at DESC LIMIT ?";
        $params[] = $limit;
        
        $stmt = $this->conn->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Helper methods
     */
    private function getChanges($oldData, $newData) {
        $changes = [];
        foreach ($newData as $key => $value) {
            if (!isset($oldData[$key]) || $oldData[$key] != $value) {
                $changes[$key] = [
                    'old' => $oldData[$key] ?? null,
                    'new' => $value
                ];
            }
        }
        return $changes;
    }
    
    private function formatChanges($changes) {
        $formatted = [];
        foreach ($changes as $field => $change) {
            $formatted[] = "{$field}: '{$change['old']}' → '{$change['new']}'";
        }
        return implode(', ', $formatted);
    }
}
