# PDF Streaming Guide

## Overview

The session report system now supports direct PDF streaming to the frontend for immediate download, eliminating the need to save files to storage. This provides better performance and user experience.

## Backend Changes

### Modified Controller Method

The `generateSessionReport` method now supports two modes:

1. **Stream Mode** (`download: true`) - Streams PDF directly to frontend
2. **Storage Mode** (`download: false`) - Saves to storage and returns URL

### API Endpoint

```http
POST /api/sessions/report
Content-Type: application/json

{
  "sessions": [1, 2, 3],
  "download": true
}
```

### Response Types

#### Stream Response (download: true)
```http
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="session_report_SALAMANDA_2025-01-17_123456_3sessions.pdf"
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Expires: 0

[PDF Binary Data]
```

#### JSON Response (download: false)
```json
{
  "status": "success",
  "url": "http://localhost/storage/tmp/session_report_2025-01-17_123456.pdf",
  "data": {
    "total_sales": 1500000,
    "total_discount": 50000,
    "total_payments": 1450000,
    "items_count": 45,
    "sessions_count": 3,
    "transactions_count": 125,
    "performance": {
      "execution_time_ms": 245.67,
      "memory_usage_mb": 12.5,
      "data_points": {
        "sessions": 3,
        "transactions": 125,
        "items": 45,
        "categories": 8
      }
    }
  }
}
```

## Frontend Implementation

### Vue.js Component

A complete Vue.js component is provided in `frontend-examples/SessionReportDownload.vue` with:

- Session selection interface
- Download mode selection
- Progress indicators
- Error handling
- Success feedback

### Axios Service

A dedicated service class in `frontend-examples/sessionReportService.js` provides:

- Centralized API communication
- Error handling
- File download management
- Authentication support

## Usage Examples

### 1. Simple Download

```javascript
import sessionReportService from './sessionReportService.js'

// Download report for specific sessions
const sessionIds = [1, 2, 3]
const result = await sessionReportService.downloadReport(sessionIds)
console.log('Downloaded:', result.filename)
```

### 2. Generate Preview

```javascript
// Generate preview and get URL
const preview = await sessionReportService.generatePreview(sessionIds)
console.log('Preview URL:', preview.url)

// Download from preview URL
await sessionReportService.downloadFromUrl(preview.url)
```

### 3. Vue.js Composition API

```javascript
import { useSessionReport } from './usage-example.js'

export default {
  setup() {
    const { isLoading, error, successMessage, downloadReport } = useSessionReport()
    
    const handleDownload = async () => {
      await downloadReport([1, 2, 3])
    }
    
    return {
      isLoading,
      error,
      successMessage,
      handleDownload
    }
  }
}
```

### 4. React Hook

```javascript
import { useSessionReportReact } from './usage-example.js'

function SessionReportComponent() {
  const { isLoading, error, downloadReport } = useSessionReportReact()
  
  const handleDownload = async () => {
    await downloadReport([1, 2, 3])
  }
  
  return (
    <button onClick={handleDownload} disabled={isLoading}>
      {isLoading ? 'Downloading...' : 'Download Report'}
    </button>
  )
}
```

## API Reference

### SessionReportService

#### `downloadReport(sessionIds, filename?)`
Downloads PDF directly to user's device.

**Parameters:**
- `sessionIds` (Array): Array of session IDs
- `filename` (string, optional): Custom filename

**Returns:** Promise with result object

#### `generatePreview(sessionIds)`
Generates report and returns preview URL.

**Parameters:**
- `sessionIds` (Array): Array of session IDs

**Returns:** Promise with preview data

#### `downloadFromUrl(url, filename?)`
Downloads PDF from a given URL.

**Parameters:**
- `url` (string): PDF URL
- `filename` (string, optional): Custom filename

**Returns:** Promise with result object

#### `getSessions()`
Fetches available sessions.

**Returns:** Promise with sessions array

## Error Handling

### Common Errors

1. **Network Errors**
   ```javascript
   try {
     await sessionReportService.downloadReport(sessionIds)
   } catch (error) {
     if (error.message.includes('Network error')) {
       // Handle network issues
     }
   }
   ```

2. **Authentication Errors**
   ```javascript
   // Service automatically handles 401/403 errors
   if (error.message.includes('Authentication required')) {
     // Redirect to login
   }
   ```

3. **Server Errors**
   ```javascript
   if (error.message.includes('Server error')) {
     // Show retry option
   }
   ```

### Retry Logic

```javascript
import { downloadWithRetry } from './usage-example.js'

// Download with automatic retry
const result = await downloadWithRetry(sessionIds, 3)
```

## Performance Considerations

### 1. File Size Optimization

- PDFs are optimized for web delivery
- Font subsetting enabled
- Image compression applied
- DPI set to 150 for good quality/size balance

### 2. Memory Management

- Streaming prevents large memory usage
- Files are not stored on server (stream mode)
- Automatic cleanup of temporary files

### 3. Timeout Handling

- 30-second timeout for large reports
- Progress indicators for user feedback
- Graceful error handling

## Security Features

### 1. Authentication

```javascript
// Service automatically includes auth token
const token = localStorage.getItem('auth_token')
if (token) {
  config.headers.Authorization = `Bearer ${token}`
}
```

### 2. Input Validation

- Session IDs validated on backend
- File type restrictions
- Path traversal protection

### 3. Access Control

- User can only access their own sessions
- Role-based permissions enforced
- Audit logging for downloads

## Browser Compatibility

### Supported Browsers

- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+

### Required Features

- Blob API support
- URL.createObjectURL()
- Fetch API or XMLHttpRequest

### Fallback Support

```javascript
// Check for blob support
if (typeof Blob === 'undefined') {
  // Fallback to direct link
  window.open(url, '_blank')
} else {
  // Use blob download
  sessionReportService.downloadReport(sessionIds)
}
```

## Testing

### Unit Tests

```javascript
// Test download functionality
describe('SessionReportService', () => {
  it('should download PDF successfully', async () => {
    const result = await sessionReportService.downloadReport([1, 2, 3])
    expect(result.success).toBe(true)
  })
})
```

### Integration Tests

```javascript
// Test with real API
describe('PDF Download Integration', () => {
  it('should stream PDF correctly', async () => {
    const response = await fetch('/api/sessions/report', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        sessions: [1, 2, 3],
        download: true
      })
    })
    
    expect(response.headers.get('content-type')).toBe('application/pdf')
    expect(response.headers.get('content-disposition')).toContain('attachment')
  })
})
```

## Troubleshooting

### Common Issues

1. **Download Not Starting**
   - Check browser popup blocker
   - Verify blob support
   - Check network connectivity

2. **File Corrupted**
   - Verify response type is 'blob'
   - Check content-type header
   - Validate PDF generation

3. **Large File Timeout**
   - Increase timeout setting
   - Implement progress tracking
   - Consider chunked download

### Debug Mode

```javascript
// Enable debug logging
sessionReportService.api.interceptors.request.use(config => {
  console.log('Request:', config)
  return config
})

sessionReportService.api.interceptors.response.use(response => {
  console.log('Response:', response)
  return response
})
```

## Best Practices

### 1. User Experience

- Show loading indicators
- Provide progress feedback
- Handle errors gracefully
- Offer retry options

### 2. Performance

- Use appropriate timeouts
- Implement caching where possible
- Optimize PDF generation
- Monitor memory usage

### 3. Security

- Validate all inputs
- Implement proper authentication
- Log download activities
- Sanitize filenames

### 4. Error Handling

- Provide meaningful error messages
- Implement retry logic
- Log errors for debugging
- Offer alternative download methods

## Migration Guide

### From Storage-Based to Streaming

1. **Update API calls**
   ```javascript
   // Old way
   const response = await axios.post('/api/sessions/report', { sessions })
   window.open(response.data.url, '_blank')
   
   // New way
   await sessionReportService.downloadReport(sessions)
   ```

2. **Update error handling**
   ```javascript
   // Handle streaming errors
   try {
     await sessionReportService.downloadReport(sessions)
   } catch (error) {
     // Handle specific error types
   }
   ```

3. **Update UI components**
   - Replace URL-based downloads with streaming
   - Add progress indicators
   - Improve error messaging

## Conclusion

The PDF streaming functionality provides:

1. **Better Performance** - No server storage required
2. **Improved UX** - Immediate downloads
3. **Enhanced Security** - No temporary files
4. **Scalability** - Reduced server load
5. **Flexibility** - Multiple download modes

The implementation is production-ready with comprehensive error handling, security features, and browser compatibility. 