# LiveComponents DevTools & Debugging Guide

Umfassender Leitfaden für Debugging und Development Tools für LiveComponents.

## Table of Contents

1. [Debug Mode](#debug-mode)
2. [Component State Inspection](#component-state-inspection)
3. [Request/Response Debugging](#requestresponse-debugging)
4. [Performance Profiling](#performance-profiling)
5. [Common Debugging Scenarios](#common-debugging-scenarios)
6. [Browser DevTools Integration](#browser-devtools-integration)
7. [Server-Side Logging](#server-side-logging)
8. [Testing & Development Helpers](#testing--development-helpers)
9. [Troubleshooting Workflows](#troubleshooting-workflows)
10. [Production Debugging](#production-debugging)

---

## Debug Mode

### Enabling Debug Mode

```php
use App\Framework\LiveComponents\Config\LiveComponentsConfig;

// In your configuration (e.g., config/livecomponents.php)
return new LiveComponentsConfig(
    debug: true,  // Enable debug mode
    enableDevTools: true,  // Enable DevTools helpers
    logLevel: 'debug'  // Verbose logging
);
```

### Debug Mode Features

**Automatic Features When Enabled:**

1. **Verbose Logging**: All component lifecycle events logged
2. **State Snapshots**: Before/after state changes captured
3. **Performance Metrics**: Render times, action execution times
4. **Error Context**: Enhanced error messages with full state dump
5. **Request/Response Logging**: All AJAX requests/responses logged

### Environment-Based Configuration

```php
// config/livecomponents.php
use App\Framework\Core\Environment;
use App\Framework\Config\EnvKey;

return new LiveComponentsConfig(
    debug: $container->get(Environment::class)->get(EnvKey::APP_ENV) === 'development',
    enableDevTools: $container->get(Environment::class)->get(EnvKey::APP_ENV) !== 'production',
    logLevel: match ($container->get(Environment::class)->get(EnvKey::APP_ENV)) {
        'production' => 'error',
        'staging' => 'warning',
        'development' => 'debug',
        default => 'info'
    }
);
```

---

## Component State Inspection

### Server-Side State Inspection

```php
use App\Framework\LiveComponents\Debug\StateInspector;

final readonly class ShoppingCartComponent implements LiveComponentContract
{
    public function __construct(
        private StateInspector $stateInspector  // Injected when debug=true
    ) {}

    #[Action]
    public function addItem(CartItem $item): ShoppingCartState
    {
        // Capture state before action
        $this->stateInspector->captureSnapshot('before_add_item', $this->state);

        $newState = $this->state->addItem($item);

        // Capture state after action
        $this->stateInspector->captureSnapshot('after_add_item', $newState);

        // Analyze state diff
        $diff = $this->stateInspector->diff($this->state, $newState);
        $this->stateInspector->log('State changed', [
            'action' => 'addItem',
            'changes' => $diff,
            'item_count_before' => count($this->state->items),
            'item_count_after' => count($newState->items)
        ]);

        return $newState;
    }
}
```

### Client-Side State Inspection

```javascript
// Access component state from browser console
const component = window.LiveComponents.get('shopping-cart:main');

// Current state
console.log('Current State:', component.state);

// State history (when debug=true)
console.log('State History:', component._debugStateHistory);

// Last action result
console.log('Last Action:', component._lastAction);

// Component metadata
console.log('Component Info:', {
    id: component.id,
    name: component.name,
    version: component.version,
    renderCount: component._renderCount,
    actionCount: component._actionCount
});
```

### State Snapshots

```php
// Automatic snapshots during development
final readonly class StateSnapshot
{
    public function __construct(
        public string $label,
        public ComponentData $state,
        public float $timestamp,
        public ?string $triggeredBy = null,  // Action name or event
        public ?array $metadata = null
    ) {}
}

// Usage
$inspector->captureSnapshot('cart_loaded', $this->state, metadata: [
    'user_id' => $userId,
    'session_id' => $sessionId,
    'item_count' => count($this->state->items)
]);

// Retrieve snapshots
$snapshots = $inspector->getSnapshots($componentId);

// Compare snapshots
$diff = $inspector->compareSnapshots($snapshot1, $snapshot2);
```

---

## Request/Response Debugging

### Server-Side Request Logging

```php
use App\Framework\LiveComponents\Debug\RequestLogger;

final readonly class LiveComponentsRequestLogger
{
    public function logRequest(
        string $componentId,
        string $action,
        array $parameters,
        ComponentData $stateBefore,
        ComponentData $stateAfter,
        float $executionTime
    ): void {
        $this->logger->debug('LiveComponent Action', [
            'component_id' => $componentId,
            'action' => $action,
            'parameters' => $parameters,
            'execution_time_ms' => round($executionTime * 1000, 2),
            'state_diff' => $this->calculateDiff($stateBefore, $stateAfter),
            'timestamp' => microtime(true)
        ]);
    }
}
```

### Client-Side Network Debugging

```javascript
// Enable detailed network logging
window.LiveComponents.setDebug(true);

// Network request interceptor (when debug=true)
window.LiveComponents.onRequest((request) => {
    console.group(`📤 LiveComponent Request: ${request.action}`);
    console.log('Component:', request.componentId);
    console.log('Action:', request.action);
    console.log('Parameters:', request.parameters);
    console.log('State Hash:', request.stateHash);
    console.groupEnd();
});

window.LiveComponents.onResponse((response) => {
    console.group(`📥 LiveComponent Response: ${response.action}`);
    console.log('Duration:', `${response.duration}ms`);
    console.log('State Updated:', response.stateChanged);
    console.log('Fragments:', response.fragments?.length || 0);
    console.log('Errors:', response.errors || 'None');
    console.groupEnd();
});

window.LiveComponents.onError((error) => {
    console.group(`❌ LiveComponent Error: ${error.action}`);
    console.error('Message:', error.message);
    console.error('Component:', error.componentId);
    console.error('Stack:', error.stack);
    console.groupEnd();
});
```

### Browser DevTools Network Panel

**Request Inspection:**

```
POST /livecomponent/action
Headers:
  X-LiveComponent: true
  X-Component-Id: shopping-cart:main
  X-Action: addItem
  X-State-Hash: a1b2c3d4e5f6

Request Payload:
{
  "item": {
    "id": "prod-123",
    "name": "Product Name",
    "price": 2999,
    "quantity": 1
  }
}

Response:
{
  "success": true,
  "stateHash": "f6e5d4c3b2a1",
  "fragments": [
    {
      "selector": "#cart-items",
      "html": "<div class='cart-item'>...</div>"
    },
    {
      "selector": "#cart-total",
      "html": "<span>€29.99</span>"
    }
  ],
  "meta": {
    "executionTime": 23.45,
    "cacheHit": false,
    "fragmentCount": 2
  }
}
```

---

## Performance Profiling

### Server-Side Performance Metrics

```php
use App\Framework\LiveComponents\Performance\ComponentProfiler;

final readonly class PerformanceProfiler
{
    public function profileAction(
        string $componentId,
        string $action,
        callable $actionHandler
    ): ProfilingResult {
        $startTime = microtime(true);
        $startMemory = memory_get_usage(true);

        // Execute action
        $result = $actionHandler();

        $endTime = microtime(true);
        $endMemory = memory_get_usage(true);

        return new ProfilingResult(
            componentId: $componentId,
            action: $action,
            executionTime: Duration::fromSeconds($endTime - $startTime),
            memoryUsed: $endMemory - $startMemory,
            peakMemory: memory_get_peak_usage(true),
            result: $result
        );
    }
}

// Usage in component
#[Action]
public function processPayment(PaymentRequest $request): ComponentData
{
    return $this->profiler->profileAction(
        $this->id->toString(),
        'processPayment',
        fn() => $this->executePayment($request)
    )->result;
}
```

### Component Lifecycle Profiling

```php
final readonly class LifecycleProfiler
{
    public function profileRender(LiveComponentContract $component): RenderProfile
    {
        $metrics = [
            'template_load' => $this->measureTemplateLoad($component),
            'state_serialization' => $this->measureStateSerialization($component),
            'html_generation' => $this->measureHtmlGeneration($component),
            'dom_manipulation' => $this->measureDomManipulation($component)
        ];

        return new RenderProfile(
            componentId: $component->id,
            totalTime: array_sum($metrics),
            breakdown: $metrics,
            cacheHit: $this->wasCached($component)
        );
    }
}
```

### Client-Side Performance Metrics

```javascript
// Performance API integration
const performanceObserver = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (entry.name.startsWith('livecomponent:')) {
            console.log('Performance Entry:', {
                name: entry.name,
                duration: `${entry.duration.toFixed(2)}ms`,
                startTime: entry.startTime,
                type: entry.entryType
            });
        }
    }
});

performanceObserver.observe({ entryTypes: ['measure'] });

// Measure action execution
performance.mark('livecomponent:action:start');
await component.call('addItem', { item });
performance.mark('livecomponent:action:end');

performance.measure(
    'livecomponent:action:addItem',
    'livecomponent:action:start',
    'livecomponent:action:end'
);
```

### Render Performance Tracking

```javascript
// Track rendering performance
class RenderPerformanceTracker {
    trackRender(componentId, metrics) {
        const entry = {
            componentId,
            timestamp: Date.now(),
            domPatchTime: metrics.domPatchTime,
            fragmentCount: metrics.fragmentCount,
            bytesReceived: metrics.bytesReceived,
            cacheHit: metrics.cacheHit
        };

        // Store in IndexedDB for analysis
        this.storeMetric(entry);

        // Warn on slow renders
        if (metrics.domPatchTime > 100) {
            console.warn(`Slow render detected: ${componentId}`, metrics);
        }
    }

    getAverageRenderTime(componentId) {
        const entries = this.getMetrics(componentId);
        return entries.reduce((sum, e) => sum + e.domPatchTime, 0) / entries.length;
    }
}
```

---

## Common Debugging Scenarios

### Scenario 1: Action Not Triggering

**Symptoms:** Button click doesn't trigger action

**Debug Steps:**

```javascript
// 1. Check if component is registered
const component = window.LiveComponents.get('shopping-cart:main');
console.log('Component exists:', !!component);

// 2. Check action attribute
const button = document.querySelector('[data-action="addItem"]');
console.log('Action attribute:', button?.dataset.action);
console.log('Component ID attribute:', button?.dataset.componentId);

// 3. Check event listeners
console.log('Event listeners:', getEventListeners(button));

// 4. Enable verbose logging
window.LiveComponents.setDebug(true);

// 5. Try manual action call
component.call('addItem', { item: testItem })
    .then(result => console.log('Manual call success:', result))
    .catch(error => console.error('Manual call failed:', error));
```

**Common Fixes:**
- Missing `data-component-id` attribute
- Incorrect action name (case-sensitive)
- Component not initialized (check initialization order)
- JavaScript errors preventing event binding

### Scenario 2: State Not Updating

**Symptoms:** Server returns success but UI doesn't update

**Debug Steps:**

```php
// Server-side: Verify state change
#[Action]
public function addItem(CartItem $item): ShoppingCartState
{
    $oldState = $this->state;
    $newState = $this->state->addItem($item);

    // Debug logging
    error_log("Old item count: " . count($oldState->items));
    error_log("New item count: " . count($newState->items));
    error_log("State changed: " . ($oldState !== $newState ? 'yes' : 'no'));

    return $newState;
}
```

```javascript
// Client-side: Track state updates
window.LiveComponents.onStateChange((event) => {
    console.log('State changed:', {
        componentId: event.componentId,
        oldHash: event.oldHash,
        newHash: event.newHash,
        changed: event.oldHash !== event.newHash
    });
});
```

**Common Fixes:**
- State object not immutable (modifying instead of returning new instance)
- Missing fragments in response
- DomPatcher not applying changes (check selectors)
- Cache preventing updates (clear cache)

### Scenario 3: Memory Leaks

**Symptoms:** Browser memory grows over time

**Debug Steps:**

```javascript
// Heap snapshot comparison
// 1. Take baseline snapshot
console.log('Taking baseline snapshot...');
// Use Chrome DevTools > Memory > Take snapshot

// 2. Perform actions
for (let i = 0; i < 100; i++) {
    await component.call('addItem', { item: generateTestItem(i) });
}

// 3. Take second snapshot
console.log('Taking second snapshot...');
// Compare snapshots in DevTools

// Check component cleanup
window.addEventListener('beforeunload', () => {
    console.log('Active components:', window.LiveComponents.getAll());
    console.log('Event listeners:', window.LiveComponents._eventListeners.size);
});
```

**Common Fixes:**
- Event listeners not cleaned up on component destroy
- DOM references held in closures
- Polling not stopped on unmount
- Large state objects not garbage collected

### Scenario 4: CSRF Token Mismatch

**Symptoms:** 403 Forbidden on action calls

**Debug Steps:**

```javascript
// Check CSRF token presence
const form = document.querySelector('form');
const csrfToken = form.querySelector('[name="_csrf_token"]')?.value;
console.log('CSRF Token in form:', csrfToken);

// Check request headers
window.LiveComponents.onRequest((request) => {
    console.log('CSRF Token in request:', request.headers['X-CSRF-Token']);
});

// Check session token
fetch('/api/csrf-token')
    .then(r => r.json())
    .then(data => console.log('Current session CSRF:', data.token));
```

**Common Fixes:**
- Token not included in request (check middleware)
- Token expired (implement rotation)
- Session cleared (re-authenticate)
- Token not matching session (clear cookies and refresh)

### Scenario 5: Rate Limiting Issues

**Symptoms:** Actions suddenly fail with 429 Too Many Requests

**Debug Steps:**

```javascript
// Track rate limit headers
window.LiveComponents.onResponse((response) => {
    if (response.status === 429) {
        console.error('Rate Limited:', {
            retryAfter: response.headers['Retry-After'],
            limit: response.headers['X-RateLimit-Limit'],
            remaining: response.headers['X-RateLimit-Remaining'],
            reset: response.headers['X-RateLimit-Reset']
        });
    }
});

// Monitor action frequency
let actionCount = 0;
let startTime = Date.now();

window.LiveComponents.onRequest(() => {
    actionCount++;
    const elapsed = (Date.now() - startTime) / 1000;
    const rate = actionCount / elapsed;

    console.log(`Action rate: ${rate.toFixed(2)} req/sec`);

    if (rate > 5) {
        console.warn('High action rate detected - may trigger rate limiting');
    }
});
```

**Common Fixes:**
- Implement debouncing for user actions
- Increase rate limits for legitimate use cases
- Add exponential backoff on 429 responses
- Batch multiple actions into single request

---

## Browser DevTools Integration

### Console Helpers

```javascript
// Global debug helpers (available in console)

// Get component by ID
lc('shopping-cart:main')  // Shorthand for window.LiveComponents.get()

// List all components
lc.all()

// Component state
lc.state('shopping-cart:main')

// Component history
lc.history('shopping-cart:main')

// Trigger action manually
lc.call('shopping-cart:main', 'addItem', { item: testItem })

// Enable/disable debug mode
lc.debug(true)  // Enable
lc.debug(false) // Disable

// Performance stats
lc.stats('shopping-cart:main')

// Clear component cache
lc.clearCache('shopping-cart:main')
```

### React DevTools Style Inspector

```javascript
// Component tree visualization
window.LiveComponents.inspect()
// Logs component hierarchy:
/*
shopping-cart:main
├── cart-item:item-1
├── cart-item:item-2
└── cart-total:main
*/

// Component details
window.LiveComponents.inspectComponent('shopping-cart:main')
// Logs:
/*
Component: shopping-cart:main
State: { items: [...], total: 2999 }
Actions: [addItem, removeItem, updateQuantity]
Events: [itemAdded, itemRemoved]
Polling: { enabled: true, interval: 5000ms }
Cache: { enabled: true, ttl: 300s, hits: 23, misses: 5 }
Performance: { avgRenderTime: 15ms, actionCount: 47 }
*/
```

---

## Server-Side Logging

### Structured Logging

```php
use App\Framework\LiveComponents\Logging\ComponentLogger;
use Psr\Log\LogLevel;

final readonly class ComponentLogger
{
    public function logAction(
        string $componentId,
        string $action,
        array $context = []
    ): void {
        $this->logger->log(LogLevel::INFO, 'LiveComponent action executed', [
            'component_id' => $componentId,
            'action' => $action,
            'user_id' => $context['user_id'] ?? null,
            'session_id' => $context['session_id'] ?? null,
            'execution_time_ms' => $context['execution_time'] ?? null,
            'timestamp' => time()
        ]);
    }

    public function logError(
        string $componentId,
        string $action,
        \Throwable $error,
        array $context = []
    ): void {
        $this->logger->log(LogLevel::ERROR, 'LiveComponent action failed', [
            'component_id' => $componentId,
            'action' => $action,
            'error_message' => $error->getMessage(),
            'error_class' => get_class($error),
            'stack_trace' => $error->getTraceAsString(),
            'state_snapshot' => $context['state'] ?? null,
            'parameters' => $context['parameters'] ?? null
        ]);
    }
}
```

### Action Audit Log

```php
final readonly class ActionAuditLogger
{
    public function logActionExecution(
        ActionExecution $execution
    ): void {
        $this->auditLog->write([
            'event' => 'livecomponent.action',
            'component_id' => $execution->componentId,
            'action' => $execution->action,
            'user_id' => $execution->userId,
            'ip_address' => $execution->ipAddress,
            'user_agent' => $execution->userAgent,
            'parameters' => $this->sanitizeParameters($execution->parameters),
            'success' => $execution->success,
            'error' => $execution->error?->getMessage(),
            'execution_time_ms' => $execution->executionTime->toMilliseconds(),
            'timestamp' => $execution->timestamp->format('Y-m-d H:i:s')
        ]);
    }

    private function sanitizeParameters(array $parameters): array
    {
        // Remove sensitive data from logs
        $sanitized = $parameters;

        foreach (['password', 'token', 'api_key', 'secret'] as $sensitive) {
            if (isset($sanitized[$sensitive])) {
                $sanitized[$sensitive] = '[REDACTED]';
            }
        }

        return $sanitized;
    }
}
```

### Log Aggregation Queries

```bash
# Find slow actions (Elasticsearch/Kibana query)
GET /livecomponents-logs/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "event": "livecomponent.action" } },
        { "range": { "execution_time_ms": { "gte": 100 } } }
      ]
    }
  },
  "aggs": {
    "slow_actions": {
      "terms": {
        "field": "action.keyword",
        "size": 10
      },
      "aggs": {
        "avg_time": { "avg": { "field": "execution_time_ms" } }
      }
    }
  }
}

# Find error patterns
GET /livecomponents-logs/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "success": false } }
      ]
    }
  },
  "aggs": {
    "error_types": {
      "terms": { "field": "error_class.keyword" }
    },
    "affected_components": {
      "terms": { "field": "component_id.keyword" }
    }
  }
}
```

---

## Testing & Development Helpers

### Pest Testing Helpers

```php
use function Pest\LiveComponents\mountComponent;
use function Pest\LiveComponents\callAction;

// Mount component with debug enabled
it('debugs component state changes', function () {
    $component = mountComponent('shopping-cart:main', [
        'items' => [],
        'total' => 0
    ], debug: true);  // Enable debug mode

    // Call action with debug output
    $result = callAction($component, 'addItem', [
        'item' => ['id' => '1', 'name' => 'Test', 'price' => 1000]
    ], debug: true);

    // Debug output automatically logged:
    /*
    [DEBUG] Action: addItem
    [DEBUG] Before State: {"items":[],"total":0}
    [DEBUG] Parameters: {"item":{"id":"1","name":"Test","price":1000}}
    [DEBUG] After State: {"items":[...],"total":1000}
    [DEBUG] Execution Time: 2.34ms
    */

    expect($result['state']['total'])->toBe(1000);
});
```

### Mock State Inspector

```php
// Create mock state inspector for testing
final readonly class MockStateInspector implements StateInspector
{
    private array $snapshots = [];
    private array $logs = [];

    public function captureSnapshot(string $label, ComponentData $state, ?array $metadata = null): void
    {
        $this->snapshots[] = new StateSnapshot($label, $state, microtime(true), metadata: $metadata);
    }

    public function getSnapshots(string $componentId): array
    {
        return array_filter(
            $this->snapshots,
            fn($s) => str_starts_with($s->label, $componentId)
        );
    }

    public function log(string $message, array $context = []): void
    {
        $this->logs[] = ['message' => $message, 'context' => $context, 'time' => microtime(true)];
    }

    public function getLogs(): array
    {
        return $this->logs;
    }
}

// Use in tests
it('captures state snapshots during action', function () {
    $inspector = new MockStateInspector();
    $component = new ShoppingCartComponent(
        id: ComponentId::fromString('cart:test'),
        state: new ShoppingCartState([], 0),
        stateInspector: $inspector
    );

    $component->addItem(new CartItem('1', 'Test', 1000));

    $snapshots = $inspector->getSnapshots('cart:test');
    expect($snapshots)->toHaveCount(2)  // before and after
        ->and($inspector->getLogs())->toContain(fn($log) => $log['message'] === 'State changed');
});
```

---

## Troubleshooting Workflows

### Workflow 1: Component Not Rendering

```
1. Check component registration
   → Verify #[LiveComponent] attribute present
   → Check component name matches template usage

2. Check initialization
   → Console: window.LiveComponents.get('component:id')
   → Should return component instance

3. Verify template
   → Check render() method returns correct template path
   → Verify template file exists
   → Check template syntax

4. Check state
   → Verify state class is readonly
   → Check constructor parameters
   → Ensure state serializable

5. Server logs
   → Check for component registration errors
   → Look for template loading errors
   → Verify DI container bindings
```

### Workflow 2: Action Fails Silently

```
1. Enable debug mode
   → Set debug: true in config
   → Check browser console for errors

2. Network inspection
   → DevTools > Network > Filter: livecomponent
   → Check request payload
   → Verify response status (200/403/429/500)

3. Server-side debugging
   → Add error_log() in action method
   → Check action parameter types match
   → Verify return type is ComponentData

4. State validation
   → Ensure new state is returned (not modified)
   → Check state is serializable
   → Verify no circular references

5. Security checks
   → CSRF token present and valid
   → Rate limit not exceeded
   → Authentication/authorization passed
```

### Workflow 3: Performance Degradation

```
1. Measure baseline
   → Use Performance API to measure render times
   → Track action execution times
   → Monitor network request sizes

2. Identify bottleneck
   → Profile component lifecycle
   → Check database query count (N+1 problems)
   → Verify cache effectiveness

3. Optimize rendering
   → Enable fragment rendering
   → Implement component caching with varyBy
   → Use SWR for non-critical updates

4. Reduce network overhead
   → Enable request batching
   → Compress responses (gzip)
   → Implement polling backoff

5. Server-side optimization
   → Add database indexes
   → Optimize queries (eager loading)
   → Implement query result caching
   → Use Redis for session storage
```

---

## Production Debugging

### Safe Production Debugging

```php
// Enable debug mode for specific users only
final readonly class DebugModeManager
{
    public function isDebugEnabledForUser(?string $userId): bool
    {
        if (!$userId) {
            return false;
        }

        // Allow debug mode for admin users
        if ($this->userService->isAdmin($userId)) {
            return true;
        }

        // Allow debug mode via feature flag
        if ($this->featureFlags->isEnabled('livecomponents-debug', $userId)) {
            return true;
        }

        return false;
    }
}

// Conditional debug logging
$config = new LiveComponentsConfig(
    debug: $this->debugManager->isDebugEnabledForUser($currentUserId),
    enableDevTools: false,  // Never enable in production
    logLevel: 'error'  // Only log errors in production
);
```

### Production Error Tracking

```php
use App\Framework\ErrorReporting\ErrorReporter;

final readonly class ProductionErrorHandler
{
    public function __construct(
        private ErrorReporter $errorReporter  // e.g., Sentry, Rollbar
    ) {}

    public function handleActionError(
        string $componentId,
        string $action,
        \Throwable $error,
        array $context
    ): void {
        $this->errorReporter->captureException($error, [
            'tags' => [
                'component' => 'livecomponents',
                'component_id' => $componentId,
                'action' => $action
            ],
            'extra' => [
                'user_id' => $context['user_id'] ?? null,
                'session_id' => $context['session_id'] ?? null,
                'state_hash' => $context['state_hash'] ?? null,
                'parameters' => $this->sanitize($context['parameters'] ?? [])
            ],
            'fingerprint' => [
                $componentId,
                $action,
                get_class($error)
            ]
        ]);
    }
}
```

### Production Monitoring

```php
// Metrics collection for production monitoring
final readonly class ProductionMetricsCollector
{
    public function recordActionExecution(
        string $componentId,
        string $action,
        float $executionTime,
        bool $success
    ): void {
        // StatsD/Prometheus metrics
        $this->metrics->increment('livecomponents.action.count', [
            'component' => $componentId,
            'action' => $action,
            'success' => $success ? 'true' : 'false'
        ]);

        $this->metrics->timing('livecomponents.action.duration', $executionTime, [
            'component' => $componentId,
            'action' => $action
        ]);
    }

    public function recordCacheHit(string $componentId, bool $hit): void
    {
        $this->metrics->increment('livecomponents.cache.' . ($hit ? 'hit' : 'miss'), [
            'component' => $componentId
        ]);
    }
}
```

### Feature Flags for Debugging

```php
// Use feature flags to enable debugging features safely
final readonly class FeatureFlagDebugger
{
    public function shouldEnableVerboseLogging(string $componentId): bool
    {
        return $this->featureFlags->isEnabled("debug:verbose:{$componentId}");
    }

    public function shouldCaptureSnapshots(string $componentId): bool
    {
        return $this->featureFlags->isEnabled("debug:snapshots:{$componentId}");
    }

    public function shouldProfilePerformance(string $componentId): bool
    {
        return $this->featureFlags->isEnabled("debug:profiling:{$componentId}");
    }
}

// Usage in component
#[Action]
public function processPayment(PaymentRequest $request): ComponentData
{
    if ($this->debugger->shouldCaptureSnapshots($this->id->toString())) {
        $this->stateInspector->captureSnapshot('before_payment', $this->state);
    }

    $result = $this->paymentService->process($request);

    if ($this->debugger->shouldCaptureSnapshots($this->id->toString())) {
        $this->stateInspector->captureSnapshot('after_payment', $this->state);
    }

    return $result;
}
```

---

## Summary

### Quick Reference

**Enable Debug Mode:**
```php
new LiveComponentsConfig(debug: true, enableDevTools: true, logLevel: 'debug')
```

**Client-Side Debugging:**
```javascript
window.LiveComponents.setDebug(true);
lc('component:id').state;  // Inspect state
lc.call('component:id', 'action', params);  // Manual action
```

**Server-Side Debugging:**
```php
$this->stateInspector->captureSnapshot('label', $state);
$this->logger->debug('Action executed', $context);
```

**Performance Profiling:**
```javascript
performance.mark('start');
await action();
performance.mark('end');
performance.measure('action', 'start', 'end');
```

**Production Monitoring:**
```php
$this->errorReporter->captureException($error, $context);
$this->metrics->timing('action.duration', $time);
```

### Best Practices

1. **Development**: Enable debug mode and DevTools
2. **Staging**: Enable selective debug for specific users
3. **Production**: Disable debug, use error reporting and metrics
4. **Logging**: Use structured logging with proper context
5. **Performance**: Profile regularly, set performance budgets
6. **Security**: Never log sensitive data (passwords, tokens)
7. **Monitoring**: Set up alerts for error rates and slow actions
8. **Testing**: Use debug helpers in Pest tests

### Resources

- **Browser DevTools**: Chrome/Firefox/Edge Developer Tools
- **Error Tracking**: Sentry, Rollbar, Bugsnag
- **Metrics**: StatsD, Prometheus, Datadog
- **Logging**: ELK Stack, Graylog, Splunk
- **Profiling**: Blackfire, Tideways, XHProf
- **Testing**: Pest, PHPUnit, Playwright

This guide covers debugging workflows, tools, and best practices for developing and maintaining LiveComponents in development, staging, and production environments.
