# MbetterClient - Complete Documentation

## Table of Contents

1. [Installation & Setup](#installation--setup)
2. [Configuration](#configuration)
3. [Usage Guide](#usage-guide)
4. [Screen Casting System](#screen-casting-system)
5. [API Reference](#api-reference)
6. [Betting System](#betting-system)
7. [Development Guide](#development-guide)
8. [Troubleshooting](#troubleshooting)
9. [Advanced Topics](#advanced-topics)

## Installation & Setup

### System Requirements

- **Operating System**: Windows 10+, macOS 10.14+, or Linux (Ubuntu 18.04+)
- **Python**: 3.8 or higher
- **Memory**: 1 GB RAM minimum, 2 GB recommended (for screen casting)
- **Storage**: 200 MB free space
- **Network**: Required for Chromecast functionality and REST API features
- **FFmpeg**: Required for screen casting (automatically detected)

### Detailed Installation

1. **Install Python Dependencies**
   ```bash
   # Ensure you have the latest pip
   python -m pip install --upgrade pip
   
   # Install all dependencies
   pip install -r requirements.txt
   
   # For development
   pip install pytest pytest-qt black pylint
   ```

2. **Verify Installation**
   ```bash
   python main.py --help
   ```

3. **First Run Setup**
   - Application creates configuration directory automatically
   - Default admin user is created (username: admin, password: admin)
   - SQLite database is initialized with schema
   - Web server starts on http://localhost:5000

### Directory Structure After Installation

#### Persistent User Directories (PyInstaller Compatible)

The application automatically creates platform-appropriate persistent directories:

**Linux**:
```
~/.local/share/MbetterClient/     # Data directory
├── mbetterclient.db              # SQLite database with matches & outcomes
├── logs/
│   ├── mbetterclient.log        # Application logs
│   └── error.log                # Error logs
├── data/                        # Application data
└── uploads/                     # File uploads

~/.config/MbetterClient/         # Config directory
└── templates/                   # User uploaded overlay templates
```

**Windows**:
```
%APPDATA%\MbetterClient\         # Unified location
├── mbetterclient.db             # SQLite database
├── logs/                        # Log files
├── data/                        # Application data
├── uploads/                     # File uploads
└── templates/                   # User templates
```

**macOS**:
```
~/Library/Application Support/MbetterClient/  # Unified location
├── mbetterclient.db             # SQLite database
├── logs/                        # Log files
├── data/                        # Application data
├── uploads/                     # File uploads
└── templates/                   # User templates
```

## Configuration

### Application Settings

Edit configuration through the web dashboard or modify JSON files directly:

#### app.json
```json
{
  "web": {
    "host": "localhost",
    "port": 5000,
    "secret_key": "your-secret-key",
    "jwt_secret_key": "jwt-secret-key",
    "jwt_expiration_hours": 24,
    "session_timeout_hours": 8
  },
  "qt": {
    "fullscreen": true,
    "default_template": "news_template",
    "video_directory": "/path/to/videos",
    "supported_formats": ["mp4", "avi", "mov", "mkv"]
  },
  "api": {
    "max_retries": 3,
    "retry_backoff": 2,
    "default_timeout": 30,
    "max_consecutive_failures": 5,
    "user_agent": "MbetterClient/1.0.0"
  },
  "logging": {
    "level": "INFO",
    "max_file_size": "10MB",
    "backup_count": 5
  }
}
```

#### api_endpoints.json
```json
{
  "news_api": {
    "url": "https://newsapi.org/v2/top-headlines",
    "method": "GET",
    "headers": {
      "X-API-Key": "your-api-key"
    },
    "params": {
      "country": "us",
      "pageSize": 5
    },
    "interval": 300,
    "enabled": true,
    "timeout": 30,
    "retry_attempts": 3,
    "response_handler": "news"
  },
  "weather_api": {
    "url": "https://api.openweathermap.org/data/2.5/weather",
    "method": "GET",
    "params": {
      "q": "New York",
      "appid": "your-api-key",
      "units": "metric"
    },
    "interval": 1800,
    "enabled": false,
    "timeout": 15,
    "response_handler": "default"
  }
}
```

### Global Betting Mode Configuration

The application supports two global betting modes that determine how START_GAME messages affect match status:

#### Betting Modes
- **All Bets on Start**: When START_GAME is triggered, ALL matches in the fixture become 'bet' status (default)
- **One Bet at a Time**: When START_GAME is triggered, only the first match becomes 'bet', others remain 'scheduled'

#### Configuration (Admin Only)
Global betting mode is configured through the web dashboard by administrators:
1. Navigate to Configuration → Global Betting Mode Settings (Admin Only)
2. Select desired betting mode from dropdown
3. Click "Save Global Betting Mode"
4. Settings are saved globally and affect all users and game sessions

#### System Architecture
The global betting mode is stored in the `game_config` table as a system setting:
```json
{
  "config_key": "betting_mode",
  "config_value": "all_bets_on_start",
  "value_type": "string",
  "description": "Global betting mode: all_bets_on_start or one_bet_at_a_time",
  "is_system": true
}
```

#### Impact on Game Flow
- **All Bets on Start**: START_GAME → pending → scheduled → ALL matches become 'bet'
- **One Bet at a Time**: START_GAME → pending → scheduled → FIRST match becomes 'bet', others stay 'scheduled'

### Environment Variables

Create a `.env` file in the project root:

```bash
# Web Dashboard Configuration
WEB_HOST=0.0.0.0
WEB_PORT=5000
SECRET_KEY=your-very-secret-key-here
JWT_SECRET_KEY=your-jwt-secret-key-here

# Database
DATABASE_PATH=./data/mbetterclient.db

# Application Settings
LOG_LEVEL=INFO
DEBUG=False
FULLSCREEN=True

# API Client
API_CLIENT_TIMEOUT=30
API_CLIENT_RETRIES=3

# Development
FLASK_ENV=production
FLASK_DEBUG=False
```

## Offline Capabilities

### CDN Fallback System

MbetterClient includes a comprehensive offline capability system that ensures the web interface functions completely without internet connectivity. The application includes local copies of all CDN resources with automatic fallback mechanisms.

#### Included Resources

- **Bootstrap CSS/JS**: Complete Bootstrap 5.3.0 framework (227KB CSS, 80KB JS)
- **FontAwesome**: Full FontAwesome 6.0.0 icon library with all webfonts (89KB CSS, 123KB+ webfonts)
- **Automatic Fallback**: JavaScript-based detection with seamless CDN-to-local switching

#### Fallback Mechanism

The application uses a multi-tier fallback system:

1. **Primary**: CDN resources for optimal performance
2. **Secondary**: Local resources when CDN fails
3. **Detection**: JavaScript-based availability checking
4. **Graceful Degradation**: Works completely offline

#### PyInstaller Integration

All vendor files are automatically included in PyInstaller builds:
- Located in `mbetterclient/web_dashboard/static/vendor/`
- Automatically detected by `build.py` data collection
- No additional configuration required

### Cashier Interface

The cashier dashboard provides a streamlined interface optimized for cashiers:

#### Navigation Layout

- **Left Side**: MbetterClient logo/brand only
- **Right Side**: Server time digital clock + User dropdown menu
- **Hidden Elements**: All other navigation links (Dashboard, Video Control, Templates, etc.)

#### Features

- **Focused Interface**: Clean, distraction-free environment
- **Essential Controls**: Start Games, Video Display, Overlay Update
- **Real-time Status**: Match status, system status, activity counters
- **Server Time Clock**: Prominent 24-hour format clock
- **User Management**: Change password, logout functionality

#### Access Control

- **Role-based Access**: Restricted to users with 'cashier' role
- **Automatic Redirect**: Non-cashier users redirected to main dashboard
- **Permission Validation**: Server-side role checking on all cashier routes

## Usage Guide

### Command Line Usage

```bash
# Basic usage (screen casting enabled by default)
python main.py

# Start with automated game timer (4 minutes default)
python main.py --start-timer

# Start with custom timer delay (2 minutes)
python main.py --start-timer 2

# Available options
python main.py [OPTIONS]

Options:
  --web-host TEXT          Web interface host [default: localhost]
  --web-port INTEGER       Web interface port [default: 5000]
  --fullscreen            Start video player in fullscreen mode
  --no-fullscreen         Start video player in windowed mode
  --overlay-type TEXT     Overlay rendering system: webengine or native [default: webengine]
  --no-qt                 Disable PyQt video player
  --no-web                Disable web dashboard
  --no-api                Disable API client
  --no-screen-cast        Disable screen casting functionality
  --start-timer INTEGER   Start timer in minutes to send START_GAME message [default: 4]
  --database-path TEXT    Custom database path
  --log-level TEXT        Logging level [default: INFO]
  --config-dir TEXT       Custom configuration directory
  --help                  Show this message and exit
```

### Web Dashboard Usage

#### Login and Authentication

1. Navigate to `http://localhost:5000`
2. Login with default credentials:
   - Username: `admin`
   - Password: `admin`
3. **Important**: Change default password immediately

#### Dashboard Overview

- **System Status**: Real-time component health monitoring
- **Video Control**: Play, pause, stop video with template selection
- **Quick Actions**: Common operations like starting playback or updating overlays

#### Video Control Panel

- **File Selection**: Choose video files from local filesystem
- **Template Selection**: Choose from news, sports, or simple templates
- **Overlay Data**: Configure dynamic text and data for overlays
- **Playback Controls**: Standard video controls with fullscreen support

#### API Token Management

1. Navigate to "API Tokens" section
2. Click "Create New Token"
3. Provide descriptive name and expiration time
4. Copy generated token (shown only once)
5. Use token for API authentication

#### User Management (Admin Only)

- **Add Users**: Create new user accounts with role assignment
- **Manage Permissions**: Set admin or regular user privileges
- **Password Reset**: Reset user passwords
- **User Activity**: View login history and token usage

#### System Administration (Admin Only)

- **Application Shutdown**: Remote shutdown button in Administrator Actions section
- **Force Termination**: Guaranteed shutdown mechanism that bypasses any deadlocks
- **System Control**: Complete system management from web interface

### Overlay System

The application features a dual overlay rendering system with command-line selection:

#### WebEngine Overlays (Default)

```bash
python main.py --overlay-type webengine
```

**Features:**
- Rich JavaScript and HTML/CSS support
- Complex animations and web-based content
- Dynamic template rendering with web technologies
- Full DOM manipulation capabilities

**Best For:**
- Complex overlays with animations
- Web content integration
- Advanced JavaScript functionality

**Considerations:**
- Higher resource usage
- Potential timing issues with DOM loading
- JavaScript errors can affect overlay stability

#### Native Qt Overlays

```bash
python main.py --overlay-type native
```

**Features:**
- High performance Qt widget rendering
- Rock-solid stability with no JavaScript dependencies
- Lower resource consumption
- Immediate rendering without DOM loading delays

**Best For:**
- Simple text overlays
- Production environments requiring maximum stability
- Systems with limited resources
- Clean, consistent text rendering

**Considerations:**
- Limited to Qt widget rendering capabilities
- No web-based animations or complex layouts

### Video Player Usage

#### Keyboard Shortcuts

- `Space`: Play/Pause toggle
- `F11`: Toggle fullscreen mode
- `Esc`: Exit fullscreen mode
- `←` / `→`: Seek backward/forward (10 seconds)
- `↑` / `↓`: Volume up/down
- `M`: Mute/unmute
- `R`: Reset video position
- `Q`: Quit application

#### Overlay Templates

**News Template**:
- Scrolling ticker text at bottom
- Breaking news headline
- Logo display
- Timestamp

**Sports Template**:
- Team names and scores
- Game status and time
- League/tournament information
- Statistics display

**Simple Template**:
- Title and subtitle text
- Basic text overlay
- Customizable positioning

### API Client Configuration

#### Adding New Endpoints

1. Access "Configuration" → "API Endpoints" (Admin only)
2. Click "Add Endpoint"
3. Configure:
   - **Name**: Unique identifier
   - **URL**: Full API endpoint URL
   - **Method**: HTTP method (GET, POST, etc.)
   - **Headers**: Authentication and custom headers
   - **Parameters**: Query parameters or request body
   - **Interval**: Request frequency in seconds
   - **Response Handler**: Data processing method

#### Response Handlers

- **default**: Basic JSON response processing
- **news**: Extracts headlines and ticker text for news overlays
- **sports**: Processes game scores and team information
- **custom**: User-defined processing logic

### Fixtures Management System

The application includes a comprehensive fixtures management system with real-time API synchronization and web dashboard integration:

#### Fixtures Dashboard

Access the fixtures management interface through the web dashboard:

- **Fixtures List**: View all synchronized fixtures with match counts and status
- **Fixture Details**: Detailed view of individual fixtures with all matches and outcomes
- **Admin Controls**: Reset functionality to clear all fixture data and ZIP files
- **Real-time Updates**: Live synchronization with server using proper timestamp handling

#### API Synchronization

The fixtures system synchronizes with the server API using Unix timestamp format:

```http
POST /api/updates
Authorization: Bearer <token>
Content-Type: application/json

{
  "from": "1755773200"
}
```

**Response Format:**
```json
{
  "fixtures": [
    {
      "fixture_id": "fixture_123",
      "fixture_active_time": 1755773200,
      "matches": [
        {
          "match_number": 101,
          "fighter1_township": "Kampala Central",
          "fighter2_township": "Nakawa",
          "fixture_id": "fixture_123",
          "fixture_active_time": 1755773200,
          "outcomes": {
            "round_1_score": 10.5,
            "round_2_score": 9.8
          }
        }
      ]
    }
  ]
}
```

### Match Data Management

The application includes comprehensive boxing match data management with database tables adapted from the mbetterd system:

#### Match Database Structure

**matches table**: Core match information
- Match numbers, fighter townships, venues
- Start/end times and results
- File metadata and SHA1 checksums
- ZIP upload tracking with progress
- User association and timestamps
- `fixture_active_time` field for server synchronization (Unix timestamp)

**match_outcomes table**: Detailed match results
- Foreign key relationships to matches
- Column-based outcome storage with float values
- Unique constraints preventing duplicate outcomes

#### Match Data API

Access match data through the web dashboard or API:

```http
GET /api/matches
Authorization: Bearer <token>
```

**Response:**
```json
{
  "matches": [
    {
      "id": 1,
      "match_number": 101,
      "fighter1_township": "Kampala Central",
      "fighter2_township": "Nakawa",
      "venue_kampala_township": "Kololo",
      "start_time": "2025-08-21T14:00:00Z",
      "end_time": "2025-08-21T14:45:00Z",
      "result": "Winner: Fighter 1",
      "active_status": true,
      "outcomes": {
        "round_1_score": 10.5,
        "round_2_score": 9.8,
        "total_score": 20.3
      }
    }
  ]
}
```

#### Creating Match Records

```http
POST /api/matches
Authorization: Bearer <token>
Content-Type: application/json

{
  "match_number": 102,
  "fighter1_township": "Rubaga",
  "fighter2_township": "Makindye",
  "venue_kampala_township": "Lugogo",
  "outcomes": [
    {
      "column_name": "round_1_score",
      "float_value": 9.5
    },
    {
      "column_name": "round_2_score",
      "float_value": 8.7
    }
  ]
}
```

## Extraction Management System

The application includes a comprehensive extraction management system for managing outcome associations with extraction results, featuring an intuitive drag-and-drop interface and real-time server time display.

### Extraction Management Features

- **Drag & Drop Interface**: Interactive outcome management with visual feedback
- **Multi-Association Support**: Outcomes can be associated with multiple extraction results
- **Trash Bin Removal**: Context-aware removal of associations based on drag location
- **Real-Time Persistence**: Immediate database updates with association changes
- **Server Time Clock**: Prominent 24-hour format clock showing server time
- **Cross-Interface Display**: Clock appears on all authenticated dashboard pages

### Extraction Management Architecture

The extraction system consists of several integrated components:

1. **Database Models**: `ExtractionAssociationModel` and `GameConfigModel` for data persistence
2. **Web Interface**: Complete drag-and-drop interface with real-time updates
3. **API Endpoints**: RESTful endpoints for CRUD operations on extraction data
4. **Server Time Service**: `/api/server-time` endpoint for accurate time display
5. **Migration System**: Database migration for schema updates

### Extraction Management Usage

#### Accessing the Interface

Navigate to the extraction management interface:
1. Open web dashboard at `http://localhost:5001`
2. Login with your credentials
3. Click "Extraction" in the navigation menu
4. Access drag-and-drop interface and time configuration

#### Managing Outcome Associations

1. **View Available Outcomes**: All outcomes are displayed in the top area
2. **Drag to Associate**: Drag outcomes to WIN1, X, or WIN2 columns
3. **Multi-Association**: Outcomes can be associated with multiple results
4. **Remove Associations**: Drag associated outcomes to the trash bin
5. **Real-Time Updates**: Changes are saved immediately to the database

#### Configuring Game Settings

1. **Time Limits**: Configure time limits for UNDER/OVER outcomes
2. **Database Persistence**: Settings are stored in the game_config table
3. **Default Values**: System includes sensible default configurations

### Server Time Clock

#### Clock Features

- **Server Time Display**: Shows time from the machine running mbetterc
- **24-Hour Format**: HH:MM:SS format for professional display
- **Real-Time Updates**: Updates every second with server time offset
- **Auto-Sync**: Re-syncs with server every 30 seconds for accuracy
- **Cross-Interface**: Appears on all authenticated dashboard pages

#### Technical Implementation

The clock uses a client-server time offset calculation:
```javascript
// Fetch server time and calculate offset
const serverTimestamp = data.timestamp;
const clientTimestamp = Date.now();
serverTimeOffset = serverTimestamp - clientTimestamp;

// Display server time using offset
const now = Date.now() + serverTimeOffset;
const date = new Date(now);
```

### Extraction Management Configuration

#### Database Schema

**extraction_associations table**:
```sql
CREATE TABLE extraction_associations (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    outcome_name VARCHAR(255) NOT NULL,
    extraction_result VARCHAR(50) NOT NULL,
    is_default BOOLEAN DEFAULT FALSE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(outcome_name, extraction_result)
);
```

**game_config table**:
```sql
CREATE TABLE game_config (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    config_key VARCHAR(100) NOT NULL UNIQUE,
    config_value TEXT NOT NULL,
    value_type VARCHAR(20) DEFAULT 'string',
    description VARCHAR(500),
    is_system BOOLEAN DEFAULT FALSE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

#### Default Associations

The system includes default outcome associations:
- **WIN1**: WIN1, X1, K01, RET1, PTS1
- **X**: DRAW, 12, X1, X2, DKO
- **WIN2**: WIN2, X2, K02, RET2, PTS2

### Extraction Management API

#### Get All Associations

```http
GET /api/extraction/associations
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "associations": [
    {
      "id": 1,
      "outcome_name": "WIN1",
      "extraction_result": "WIN1",
      "is_default": true
    }
  ]
}
```

#### Save Associations

```http
POST /api/extraction/associations
Authorization: Bearer <token>
Content-Type: application/json

{
  "associations": [
    {
      "outcome_name": "WIN1",
      "extraction_result": "WIN1"
    }
  ]
}
```

#### Get Available Outcomes

```http
GET /api/extraction/outcomes
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "outcomes": ["WIN1", "DRAW", "WIN2", "X1", "X2"]
}
```

#### Get Server Time

```http
GET /api/server-time
```

**Response:**
```json
{
  "success": true,
  "server_time": "2025-08-26T15:30:45.123456",
  "timestamp": 1724683845123
}
```

#### Update Game Configuration

```http
POST /api/extraction/config
Authorization: Bearer <token>
Content-Type: application/json

{
  "under_over_time_limit": 90
}
```

#### Get Global Betting Mode

```http
GET /api/betting-mode
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "betting_mode": "all_bets_on_start",
  "is_default": false,
  "description": "Global system setting that determines how START_GAME affects match status"
}
```

#### Update Global Betting Mode (Admin Only)

```http
POST /api/betting-mode
Authorization: Bearer <token>
Content-Type: application/json

{
  "betting_mode": "one_bet_at_a_time"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Global betting mode set to 'one_bet_at_a_time'",
  "betting_mode": "one_bet_at_a_time"
}
```

**Error Response (Non-Admin):**
```json
{
  "success": false,
  "error": "Admin access required"
}
```

## Match Timer System

The application includes a comprehensive match timer system with automatic match progression, visual countdown displays, and command-line timer configuration.

### Match Timer Features

- **Automatic Countdown**: Real-time countdown timer with configurable intervals
- **Match Progression**: Automatically starts next available match when timer reaches zero
- **Priority-Based Selection**: Finds matches in priority order (bet → scheduled → pending)
- **Visual Feedback**: Color-coded timer states with animations
- **Cross-Interface Display**: Timer appears in both status bar and navbar
- **Message Bus Integration**: Uses MATCH_START message for match status changes
- **Configuration-Based**: Timer interval configurable via match_interval setting

### Match Timer Architecture

The match timer system consists of several integrated components:

1. **Timer Display**: Visual countdown in MM:SS format with color states
2. **API Endpoints**: Configuration and match starting endpoints
3. **Message Bus**: MATCH_START message type for match progression
4. **JavaScript Engine**: Client-side countdown logic with server sync
5. **Priority Logic**: Intelligent match selection algorithm

### Match Timer Usage

#### Timer Display Locations

The countdown timer appears in two locations:

1. **Status Bar**: Bottom status bar on main dashboard pages
2. **Navbar**: Top navigation bar on cashier dashboard

#### Timer States and Colors

- **Normal State**: Yellow/Orange background (default)
- **Warning State**: Yellow text/color (last 5 minutes)
- **Danger State**: Red background with pulse animation (last minute)

#### Automatic Match Progression

When the timer reaches zero, the system:

1. Finds the first fixture with matches starting today
2. Searches for matches in priority order:
   - First priority: Matches with "bet" status
   - Second priority: Matches with "scheduled" status
   - Third priority: Matches with "pending" status
3. Sends MATCH_START message with fixture_id and match_id
4. Resets timer to configured interval
5. Shows notification with match details

### Match Timer Configuration

#### Timer Interval Setting

The timer interval is configured via the `match_interval` setting in the general configuration section:

```json
{
  "general": {
    "match_interval": 20
  }
}
```

- **Unit**: Minutes
- **Default**: 20 minutes
- **Range**: 1-60 minutes
- **Type**: Integer

#### Visual Configuration

Timer appearance is controlled via CSS variables and classes:

```css
#match-timer {
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
    font-weight: bold;
    min-width: 60px;
}

#match-timer.bg-danger {
    background: linear-gradient(135deg, #dc3545 0%, #b02a37 100%);
    animation: timerPulse 0.5s infinite;
}
```

### Command-Line Timer Configuration

The application supports automated game start via command-line timer configuration:

#### --start-timer Option

```bash
# Start with default 4-minute timer
python main.py --start-timer

# Start with custom timer delay (in minutes)
python main.py --start-timer 2

# Start with 30-second timer for testing
python main.py --start-timer 0.5
```

#### Timer Behavior

- **Automatic START_GAME**: When the timer expires, a START_GAME message is automatically sent to the message bus
- **MatchTimerComponent Integration**: The command-line timer works seamlessly with the existing MatchTimerComponent
- **Web Interface Display**: Timer state is available through the web dashboard API endpoints
- **Configurable Delay**: Timer delay can be set from seconds to hours (though practical use is typically minutes)

#### Timer Configuration Architecture

The command-line timer integrates with the existing timer system:

1. **Settings Integration**: Timer configuration is stored in `AppSettings.timer`
2. **Application Startup**: Timer is initialized during application startup if `--start-timer` is specified
3. **Message Bus Communication**: Timer expiration sends START_GAME message to trigger match progression
4. **Web Dashboard Integration**: Timer state is cached and served through API endpoints

#### Example Usage Scenarios

**Development Testing**:
```bash
# Quick 30-second timer for testing timer functionality
python main.py --start-timer 0.5 --no-qt
```

**Production Deployment**:
```bash
# 4-minute timer for match intervals
python main.py --start-timer 4 --web-port 8080
```

**Custom Timing**:
```bash
# 10-minute intervals for longer matches
python main.py --start-timer 10
```

### Match Timer API

#### Get Timer Configuration

```http
GET /api/match-timer/config
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "match_interval": 20
}
```

#### Start Next Match

```http
POST /api/match-timer/start-match
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "message": "Match 101 started successfully",
  "fixture_id": "fixture_123",
  "match_id": 456,
  "match_number": 101
}
```

**Error Response:**
```json
{
  "success": false,
  "error": "No suitable fixture found"
}
```

### Match Timer Message Bus

#### MATCH_START Message

When the timer reaches zero, a MATCH_START message is sent:

```python
Message(
    type=MessageType.MATCH_START,
    sender="web_dashboard",
    data={
        "fixture_id": "fixture_123",
        "match_id": 456
    }
)
```

This message is processed by the games thread to change the match status from "bet"/"scheduled"/"pending" to "ingame".

### Match Timer Troubleshooting

#### Timer Not Starting

**Symptoms**: Timer shows "--:--" and doesn't count down
**Solutions**:
1. Check match_interval configuration in general settings
2. Verify API endpoint `/api/match-timer/config` is accessible
3. Check browser console for JavaScript errors
4. Ensure user has proper authentication

#### Timer Not Progressing Matches

**Symptoms**: Timer reaches zero but matches don't start
**Solutions**:
1. Verify MATCH_START message is being sent to message bus
2. Check games thread is running and processing messages
3. Ensure matches exist with appropriate status (bet/scheduled/pending)
4. Check database connectivity and match table data

#### Timer Color Not Changing

**Symptoms**: Timer stays same color regardless of time remaining
**Solutions**:
1. Check CSS classes are being applied correctly
2. Verify JavaScript timer logic is updating classes
3. Check browser support for CSS animations
4. Clear browser cache and reload page

#### Timer Shows Wrong Time

**Symptoms**: Timer displays incorrect countdown values
**Solutions**:
1. Check match_interval configuration accuracy
2. Verify JavaScript Date/time calculations
3. Check for timezone or daylight saving issues
4. Restart browser session to clear cached values

### Match Timer Performance

#### Optimization Features

- **Efficient Updates**: Timer updates every second without server polling
- **Minimal API Calls**: Configuration loaded once on initialization
- **Lightweight Display**: Optimized CSS and HTML for fast rendering
- **Background Processing**: Non-blocking JavaScript execution

#### Resource Usage

- **Memory**: Minimal additional memory usage (~2KB)
- **CPU**: Negligible impact (<0.1% additional CPU)
- **Network**: One API call per timer reset cycle
- **Storage**: No additional local storage requirements

### Extraction Management Troubleshooting

#### Drag & Drop Issues

**Symptoms**: Outcomes won't drag, associations not saving
**Solutions**:
1. Verify JavaScript is enabled in browser
2. Check browser compatibility (Chrome, Firefox, Safari, Edge)
3. Clear browser cache and reload page
4. Check browser console for JavaScript errors
5. Ensure user has proper permissions

#### Clock Time Issues

**Symptoms**: Clock shows wrong time, not updating
**Solutions**:
1. Check server time API endpoint: `/api/server-time`
2. Verify network connectivity to server
3. Check browser time zone settings
4. Clear browser cache and reload
5. Check JavaScript console for errors

#### Database Issues

**Symptoms**: Associations not persisting, configuration not saving
**Solutions**:
1. Check database connectivity and permissions
2. Verify migration has been applied: `Migration_014`
3. Check database logs for errors
4. Ensure proper file permissions on database file
5. Verify SQLite installation and compatibility

#### API Client Health Issues

**Symptoms**: "Unhealthy components detected: ['api_client']" warning in logs
**Solutions**:
1. Check API client thread is running and not blocked
2. Verify network connectivity for API endpoints
3. Check API token validity and expiration
4. Review API client logs for specific error messages
5. Ensure database operations are not causing long delays
6. Check for HTTP request timeouts or network issues
7. Verify heartbeat system is functioning (added in version 1.2.7)

#### Performance Issues

**Symptoms**: Interface slow, updates delayed
**Solutions**:
1. Check network latency to server
2. Reduce number of concurrent users
3. Optimize database queries and indexing
4. Consider browser resource usage
5. Check server CPU and memory usage

## Screen Casting System

The application includes a comprehensive screen casting system with Chromecast integration, providing complete screen capture and streaming capabilities.

### Screen Casting Features

- **Real-time Screen Capture**: FFmpeg-based screen recording with platform-specific optimizations
- **Chromecast Integration**: Automatic device discovery and streaming to Chromecast devices
- **Web-Based Controls**: Complete web interface for device management and streaming control
- **Cross-Platform Support**: Works on Linux, Windows, and macOS with appropriate audio/video sources
- **Quality Control**: Configurable resolution, frame rate, and bitrate settings
- **Network Streaming**: HTTP server for Chromecast-compatible stream delivery

### Screen Casting Architecture

The screen casting system consists of several integrated components:

1. **ScreenCastComponent**: Main threaded component managing the entire screen casting lifecycle
2. **HTTP Streaming Server**: Dedicated server for serving video streams to Chromecast devices
3. **FFmpeg Integration**: Cross-platform screen capture with optimized settings
4. **Chromecast Manager**: Device discovery and streaming control using pychromecast
5. **Web Interface**: Real-time controls and status monitoring

### Platform-Specific Configuration

#### Linux Configuration
- **Screen Source**: X11 display (`:0.0+0,0`)
- **Audio Source**: PulseAudio (`pulse`)
- **Requirements**: X11 server, PulseAudio
- **Permissions**: Access to X display and audio devices

#### Windows Configuration
- **Screen Source**: Desktop capture (`desktop`)
- **Audio Source**: DirectShow (`dshow`)
- **Requirements**: DirectShow filters
- **Permissions**: Screen capture and microphone access

#### macOS Configuration
- **Screen Source**: Display capture (`1:0`)
- **Audio Source**: Audio input (`:0`)
- **Requirements**: Screen Recording permission
- **Permissions**: Screen Recording and microphone access in System Preferences

### Screen Casting Usage

#### Web Interface Access

Navigate to the screen casting interface:
1. Open web dashboard at `http://localhost:5001`
2. Login with your credentials
3. Click "Screen Cast" in the navigation menu
4. Access device discovery and streaming controls

#### Device Discovery

The system automatically discovers Chromecast devices on your network:
1. Click "Discover Devices" button
2. Wait for device discovery to complete
3. Available devices appear in the device list
4. Select target device for streaming

#### Starting Screen Cast

To begin screen casting:
1. Ensure a Chromecast device is selected
2. Click "Start Screen Cast" button
3. Screen capture begins automatically
4. Stream is sent to selected Chromecast device
5. Monitor streaming status in real-time

#### Stopping Screen Cast

To end screen casting:
1. Click "Stop Screen Cast" button
2. FFmpeg capture process terminates
3. Chromecast streaming stops
4. HTTP server remains available for future sessions

### Screen Casting Configuration

Access screen casting settings through the web dashboard:

#### Quality Settings
- **Resolution**: Screen capture resolution (1920x1080, 1280x720, etc.)
- **Frame Rate**: Capture frame rate (30fps, 60fps)
- **Video Bitrate**: Streaming bitrate for quality/bandwidth balance
- **Audio Bitrate**: Audio quality settings

#### Network Settings
- **HTTP Port**: Port for streaming server (default: 8000)
- **Local IP**: Automatically detected network IP for Chromecast access
- **Stream Format**: Video container format (MP4, WebM)

#### Advanced Settings
- **FFmpeg Options**: Custom FFmpeg command line parameters
- **Buffer Size**: Streaming buffer configuration
- **Retry Attempts**: Connection retry settings
- **Timeout Values**: Network timeout configurations

### Screen Casting Troubleshooting

#### Common Issues

**Screen Casting Won't Start**
- Verify FFmpeg is installed and accessible
- Check screen capture permissions on macOS/Windows
- Ensure audio devices are available and not in use
- Check firewall settings for HTTP streaming port

**Chromecast Not Discovered**
- Verify devices are on the same network
- Check network connectivity and firewall settings
- Restart Chromecast device if necessary
- Ensure multicast/broadcast traffic is allowed

**Streaming Quality Issues**
- Adjust bitrate settings for network bandwidth
- Reduce resolution or frame rate
- Check CPU usage during capture
- Verify network stability between devices

**Audio Not Working**
- Check audio device availability
- Verify microphone permissions (macOS/Windows)
- Test audio input with system tools
- Ensure PulseAudio is running (Linux)

#### Debug Information

Enable debug logging for detailed troubleshooting:
```bash
python main.py --log-level DEBUG
```

Check screen casting specific logs:
- Component startup and initialization
- FFmpeg command execution and output
- Chromecast device discovery and connection
- HTTP streaming server status
- Network connectivity issues

#### Performance Optimization

**CPU Usage Optimization**
- Use hardware encoding if available
- Reduce capture resolution or frame rate
- Close unnecessary applications
- Monitor system resources during streaming

**Network Optimization**
- Use wired network connection when possible
- Ensure sufficient bandwidth for chosen bitrate
- Minimize network congestion
- Consider Quality of Service (QoS) settings

**Memory Usage**
- Monitor memory usage during long streaming sessions
- Restart application periodically for long-running streams
- Clear system caches if memory usage grows
- Consider system memory upgrades for intensive usage

## Betting System

The application includes a comprehensive cashier betting system with dynamic outcome generation from the database, replacing traditional hardcoded betting terminology with actual match outcomes.

### Betting System Features

- **Dynamic Betting Outcomes**: Betting options generated from actual match_outcomes table data
- **Database-Driven Interface**: No longer limited to WIN1/WIN2/X - displays any outcome types from database
- **Print Functionality**: Integrated print button for bet receipts (placeholder implementation)
- **Cashier Dashboard Integration**: Seamless integration with existing cashier interface
- **Bet Management**: Complete CRUD operations for bet creation, viewing, and cancellation
- **Real-Time Statistics**: Live betting statistics and totals
- **UUID-Based Tracking**: Secure bet identification using UUID system

### Betting System Architecture

The betting system consists of several integrated components:

1. **Database Models**: `BetModel` and `BetDetailModel` for comprehensive bet tracking
2. **Dynamic API Enhancement**: Enhanced `/cashier/available-matches` endpoint with match outcome data
3. **Frontend Generation**: JavaScript functions for dynamic betting option generation
4. **Print Infrastructure**: Print button infrastructure ready for implementation
5. **Cashier Interface**: Streamlined betting management interface

### Betting System Usage

#### Accessing the Betting Interface

Navigate to the betting system through the cashier dashboard:
1. Login to web dashboard at `http://localhost:5001`
2. Access with cashier role credentials
3. Click "Bets" button in the cashier dashboard
4. Access betting management, creation, and details interfaces

#### Creating New Bets

1. **Navigate to New Bet**: Click "New Bet" from the bets management page
2. **Load Available Matches**: System automatically loads matches in 'bet' status
3. **View Dynamic Outcomes**: See actual match outcomes from database instead of generic WIN1/WIN2/X
4. **Select Outcomes**: Choose from available betting outcomes with checkbox selection
5. **Enter Amounts**: Specify bet amounts for each selected outcome
6. **Review Summary**: Check bet summary with total amounts
7. **Submit Bet**: Finalize bet creation with UUID assignment

#### Managing Existing Bets

1. **View Bets List**: Browse all bets for selected date with filtering
2. **View Bet Details**: Click bet ID to see comprehensive bet information including match details
3. **Print Receipts**: Use print button for bet receipt generation (placeholder functionality)
4. **Cancel Bets**: Cancel pending bets with confirmation dialog
5. **Monitor Statistics**: View real-time betting statistics and totals

### Dynamic Outcome Generation

#### Database Integration

The betting system queries the `match_outcomes` table for each match to provide actual betting options:

```python
# Enhanced API endpoint queries match outcomes
match_outcomes = session.query(MatchOutcomeModel).filter_by(match_id=match.id).all()

# Converts to betting format
betting_outcomes = []
for outcome in match_outcomes:
    betting_outcomes.append({
        'outcome_id': outcome.id,
        'outcome_name': outcome.column_name,
        'outcome_value': outcome.column_value,
        'display_name': outcome.column_name
    })
```

#### Frontend Dynamic Generation

JavaScript function generates betting options dynamically:

```javascript
function generateOutcomeOptionsHTML(match, matchId) {
    let outcomes = match.outcomes || [];
    
    // Fallback to standard options if no database outcomes
    if (outcomes.length === 0) {
        outcomes = [
            { outcome_name: 'WIN1', display_name: `WIN1 - ${match.fighter1_township}` },
            { outcome_name: 'WIN2', display_name: `WIN2 - ${match.fighter2_township}` },
            { outcome_name: 'X', display_name: 'X - Draw' }
        ];
    }
    
    // Generate HTML with color coding and styling
    // ... detailed implementation
}
```

#### Graceful Fallback System

- **Primary**: Database-driven outcomes from match_outcomes table
- **Fallback**: Standard WIN1/WIN2/X options when database outcomes unavailable
- **Logging**: Warnings logged when fallback options are used
- **Compatibility**: Maintains backward compatibility with existing betting logic

### Betting Database Schema

#### BetModel Table

```sql
CREATE TABLE bets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    uuid VARCHAR(36) NOT NULL UNIQUE,
    bet_datetime DATETIME NOT NULL,
    fixture_id VARCHAR(255),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

#### BetDetailModel Table

```sql
CREATE TABLE bet_details (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    bet_id VARCHAR(36) NOT NULL,
    match_id INTEGER NOT NULL,
    outcome VARCHAR(100) NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    result VARCHAR(20) DEFAULT 'pending',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (bet_id) REFERENCES bets (uuid) ON DELETE CASCADE,
    FOREIGN KEY (match_id) REFERENCES matches (id) ON DELETE CASCADE
);
```

#### Database Migration

The betting system is implemented through Migration_017_AddBettingTables:

```python
class Migration_017_AddBettingTables(DatabaseMigration):
    def up(self, db_manager) -> bool:
        # Creates comprehensive betting tables with:
        # - UUID-based bet identification
        # - Foreign key relationships with CASCADE DELETE
        # - Proper indexing for performance
        # - SQLite-compatible syntax
```

### Betting System API

#### Get Available Matches for Betting

```http
GET /api/cashier/available-matches
Authorization: Bearer <token>
```

**Enhanced Response with Dynamic Outcomes:**
```json
{
  "success": true,
  "matches": [
    {
      "id": 1,
      "match_number": 101,
      "fighter1_township": "Kampala Central",
      "fighter2_township": "Nakawa",
      "status": "bet",
      "outcomes": [
        {
          "outcome_id": 1,
          "outcome_name": "KO_ROUND_1",
          "outcome_value": 2.5,
          "display_name": "KO Round 1"
        },
        {
          "outcome_id": 2,
          "outcome_name": "POINTS_WIN",
          "outcome_value": 1.8,
          "display_name": "Points Win"
        }
      ],
      "outcomes_count": 2
    }
  ],
  "total": 1
}
```

#### Create New Bet

```http
POST /api/cashier/bets
Authorization: Bearer <token>
Content-Type: application/json

{
  "bet_details": [
    {
      "match_id": 1,
      "outcome": "KO_ROUND_1",
      "amount": 25.00
    },
    {
      "match_id": 1,
      "outcome": "POINTS_WIN",
      "amount": 15.00
    }
  ]
}
```

**Response:**
```json
{
  "success": true,
  "message": "Bet created successfully",
  "bet_id": "550e8400-e29b-41d4-a716-446655440000",
  "details_count": 2
}
```

#### Get Bet Details

```http
GET /api/cashier/bets/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "bet": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "bet_datetime": "2025-08-26T15:30:45",
    "details": [
      {
        "id": 1,
        "match_id": 1,
        "outcome": "KO_ROUND_1",
        "amount": 25.00,
        "result": "pending",
        "match": {
          "match_number": 101,
          "fighter1_township": "Kampala Central",
          "fighter2_township": "Nakawa",
          "status": "bet"
        }
      }
    ],
    "total_amount": 40.00
  }
}
```

#### Cancel Bet

```http
DELETE /api/cashier/bets/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>
```

### Print Functionality

#### Print Button Implementation

The betting system includes integrated print functionality:

- **Location**: Print button appears in each bet row in the bets management table
- **Styling**: Consistent with other action buttons using outline-secondary styling
- **Icon**: FontAwesome print icon for clear visual identification
- **Tooltip**: "Print Bet Receipt" tooltip for user guidance
- **Event Handling**: Proper click event handling with bet ID parameter

#### Print Function Structure

```javascript
function printBet(betId) {
    // Placeholder function for printing bet receipt
    console.log('Print bet requested for bet ID:', betId);
    showNotification('Print functionality will be implemented soon!', 'info');
    
    // Future implementation possibilities:
    // 1. Open formatted receipt in new window
    // 2. Call print API endpoint for PDF generation
    // 3. Browser print dialog with formatted receipt
}
```

#### Future Print Implementation

The print infrastructure is ready for enhancement:

1. **Receipt Template**: Create HTML template for bet receipt formatting
2. **Print API Endpoint**: Add backend endpoint for receipt generation
3. **PDF Generation**: Integrate PDF library for receipt document creation
4. **Print Dialog**: Browser print dialog integration
5. **Thermal Printer**: Integration with thermal receipt printers

### Betting System Troubleshooting

#### Critical Database Constraint Errors (Fixed in v1.2.10)

**Symptoms**: "NOT NULL constraint failed: bets.fixture_id" error during bet creation
**Root Cause**: Bet creation API was setting fixture_id to None without extracting it from match data
**Solution Applied**: Enhanced bet creation logic to query MatchModel and extract fixture_id from first bet detail's match
**Prevention**: Ensure all bet creation requests include valid match_id references with existing matches

#### Bet Details Page 500 Errors (Fixed in v1.2.10)

**Symptoms**: 500 internal server error when accessing specific bet details pages
**Root Cause**: Route was not fetching bet data from database, causing template rendering failures
**Solution Applied**: Implemented complete database data fetching with proper session management and template variable population
**Prevention**: Always verify route implementations provide all required template variables

#### Template Rendering JavaScript Errors (Fixed in v1.2.10)

**Symptoms**: "'moment' is undefined" error during template rendering causing 500 errors
**Root Cause**: Template attempted to call moment() function in server-side Jinja2 context
**Solution Applied**: Replaced server-side moment() call with client-side JavaScript time handling
**Prevention**: Avoid client-side JavaScript libraries in server-side template contexts

#### API Endpoint Mismatches (Fixed in v1.2.10)

**Symptoms**: Cancel bet functionality not working, JavaScript errors on bet management actions
**Root Cause**: Frontend JavaScript calling wrong API endpoints and missing event handlers
**Solution Applied**: Corrected API endpoints and added comprehensive event handling for interactive elements
**Prevention**: Verify API endpoint consistency between frontend and backend implementations

#### Outcomes Not Loading

**Symptoms**: Betting interface shows "No outcomes found" or falls back to WIN1/WIN2/X
**Solutions**:
1. Check match_outcomes table has data for matches in 'bet' status
2. Verify database connectivity and permissions
3. Check API endpoint `/api/cashier/available-matches` response
4. Ensure matches have proper status ('bet') for betting availability
5. Review browser console for JavaScript errors

#### Bet Creation Fails

**Symptoms**: Bet submission returns errors or doesn't complete
**Solutions**:
1. Verify match IDs are valid and matches exist
2. Check outcome names match database values
3. Ensure bet amounts are valid positive numbers
4. Check user authentication and cashier role permissions
5. Review database constraints and foreign key relationships
6. **New**: Ensure fixture_id constraint is satisfied by valid match relationships

#### Print Button Not Working

**Symptoms**: Print button doesn't respond or shows errors
**Solutions**:
1. Check JavaScript console for event handler errors
2. Verify bet ID parameter is correctly passed
3. Ensure showNotification function is available
4. Check button HTML structure and event binding
5. Test with different browsers for compatibility
6. **New**: Verify event listeners are properly attached to dynamically generated elements

#### Betting Statistics Incorrect

**Symptoms**: Bet totals, counts, or statistics don't match expected values
**Solutions**:
1. Check date filtering logic for bet queries
2. Verify bet_details table relationships and data
3. Check result status calculations (won/lost/pending)
4. Ensure proper decimal handling for amounts
5. Review aggregation logic in statistics calculation
6. **New**: Validate foreign key relationships between bets, bet_details, and matches

### Betting System Performance

#### Optimization Features

- **Database Indexing**: Proper indexes on bet_id, match_id, and date columns
- **Efficient Queries**: Optimized API queries with JOIN operations
- **JavaScript Optimization**: Efficient DOM manipulation and event handling
- **Minimal API Calls**: Cached match outcome data and reduced server requests

#### Scalability Considerations

- **UUID System**: Scalable bet identification without integer limitations
- **Foreign Key Relationships**: Proper data integrity with CASCADE operations
- **Flexible Outcome Types**: Supports unlimited outcome varieties from database
- **Modular Architecture**: Easy extension for additional betting features

## API Reference

### Authentication

All API endpoints require authentication via Bearer token.

#### Get Access Token

```http
POST /auth/token
Content-Type: application/json

{
  "username": "admin",
  "password": "admin"
}
```

**Response:**
```json
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "bearer",
  "user": {
    "id": 1,
    "username": "admin",
    "is_admin": true
  }
}
```

### System Status

#### Get System Status

```http
GET /api/status
Authorization: Bearer <token>
```

**Response:**
```json
{
  "status": "online",
  "timestamp": "2025-01-19T10:00:00.000Z",
  "uptime": 3600,
  "components": {
    "qt_player": "running",
    "web_dashboard": "running",
    "api_client": "running"
  },
  "config": {
    "valid": true
  },
  "database": {
    "connected": true
  }
}
```

### Video Control

#### Play Video

```http
POST /api/video/control
Authorization: Bearer <token>
Content-Type: application/json

{
  "action": "play",
  "file_path": "/path/to/video.mp4",
  "template": "news_template",
  "overlay_data": {
    "headline": "Breaking News",
    "ticker_text": "This is a breaking news update"
  }
}
```

#### Pause Video

```http
POST /api/video/control
Authorization: Bearer <token>
Content-Type: application/json

{
  "action": "pause"
}
```

#### Get Video Status

```http
GET /api/video/status
Authorization: Bearer <token>
```

**Response:**
```json
{
  "player_status": "playing",
  "current_file": "/path/to/video.mp4",
  "current_template": "news_template",
  "position": 45.2,
  "duration": 120.0,
  "volume": 80,
  "fullscreen": true
}
```

### Overlay Management

#### Update Overlay

```http
POST /api/overlay
Authorization: Bearer <token>
Content-Type: application/json

{
  "template": "news_template",
  "data": {
    "headline": "Updated Headline",
    "ticker_text": "New ticker information",
    "logo_url": "https://example.com/logo.png"
  }
}
```

#### Get Available Templates

```http
GET /api/templates
Authorization: Bearer <token>
```

**Response:**
```json
{
  "templates": {
    "news_template": {
      "name": "News Template",
      "description": "Breaking news with scrolling text",
      "fields": ["headline", "ticker_text", "logo_url"]
    },
    "sports_template": {
      "name": "Sports Template",
      "description": "Sports scores and updates",
      "fields": ["team1", "team2", "score1", "score2", "event"]
    }
  }
}
```

### Configuration Management

#### Get Configuration

```http
GET /api/config?section=web
Authorization: Bearer <token>
```

#### Update Configuration

```http
POST /api/config
Authorization: Bearer <token>
Content-Type: application/json

{
  "section": "api_endpoints",
  "config": {
    "news_api": {
      "enabled": true,
      "interval": 600
    }
  }
}
```

### User Management

#### List Users (Admin Only)

```http
GET /api/users
Authorization: Bearer <token>
```

#### Create User (Admin Only)

```http
POST /api/users
Authorization: Bearer <token>
Content-Type: application/json

{
  "username": "newuser",
  "email": "user@example.com",
  "password": "securepassword",
  "is_admin": false
}
```

### Token Management

#### List API Tokens

```http
GET /api/tokens
Authorization: Bearer <token>
```

#### Create API Token

```http
POST /api/tokens
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "My API Token",
  "expires_hours": 8760
}
```

#### Revoke API Token

```http
DELETE /api/tokens/{token_id}
Authorization: Bearer <token>
```

### System Control (Admin Only)

#### Shutdown Application

```http
POST /api/system/shutdown
Authorization: Bearer <token>
Content-Type: application/json

{
  "force": true
}
```

**Response:**
```json
{
  "status": "success",
  "message": "Application shutdown initiated"
}
```

**Note**: This endpoint provides immediate HTTP response before initiating shutdown. The application will terminate completely within 1 second using force-exit mechanism to bypass any potential deadlocks.

### Screen Cast API

#### Get Screen Cast Status

```http
GET /api/screen_cast/status
Authorization: Bearer <token>
```

**Response:**
```json
{
  "status": "streaming",
  "devices": [
    {
      "name": "Living Room TV",
      "host": "192.168.1.100",
      "port": 8009,
      "model": "Chromecast"
    }
  ],
  "selected_device": "Living Room TV",
  "stream_url": "http://192.168.1.50:8000/stream.mp4",
  "capture_active": true,
  "http_server_running": true
}
```

#### Discover Chromecast Devices

```http
POST /api/screen_cast/discover
Authorization: Bearer <token>
```

**Response:**
```json
{
  "status": "success",
  "devices": [
    {
      "name": "Living Room TV",
      "host": "192.168.1.100",
      "port": 8009,
      "model": "Chromecast",
      "uuid": "abcd-1234-efgh-5678"
    }
  ],
  "discovered_count": 1
}
```

#### Start Screen Casting

```http
POST /api/screen_cast/start
Authorization: Bearer <token>
Content-Type: application/json

{
  "device_name": "Living Room TV"
}
```

**Response:**
```json
{
  "status": "success",
  "message": "Screen casting started",
  "stream_url": "http://192.168.1.50:8000/stream.mp4",
  "device": "Living Room TV"
}
```

#### Stop Screen Casting

```http
POST /api/screen_cast/stop
Authorization: Bearer <token>
```

**Response:**
```json
{
  "status": "success",
  "message": "Screen casting stopped"
}
```

#### Get Screen Cast Configuration

```http
GET /api/screen_cast/config
Authorization: Bearer <token>
```

**Response:**
```json
{
  "enabled": true,
  "quality": "high",
  "resolution": "1920x1080",
  "frame_rate": 30,
  "video_bitrate": "5000k",
  "audio_bitrate": "128k",
  "http_port": 8000,
  "local_ip": "192.168.1.50"
}
```

#### Update Screen Cast Configuration

```http
POST /api/screen_cast/config
Authorization: Bearer <token>
Content-Type: application/json

{
  "quality": "medium",
  "resolution": "1280x720",
  "frame_rate": 30,
  "video_bitrate": "3000k",
  "audio_bitrate": "96k"
}
```

## Development Guide

### Setting Up Development Environment

1. **Clone Repository**
   ```bash
   git clone https://git.nexlab.net/mbetter/mbetterc.git
   cd mbetterc
   ```

2. **Create Virtual Environment**
   ```bash
   python -m venv venv
   source venv/bin/activate  # Linux/macOS
   # or
   venv\Scripts\activate     # Windows
   ```

3. **Install Development Dependencies**
   ```bash
   pip install -r requirements.txt
   pip install pytest pytest-qt black pylint mypy
   ```

4. **Run Tests**
   ```bash
   pytest tests/
   ```

### Code Style and Quality

#### Formatting with Black

```bash
# Format all code
black mbetterclient/

# Check formatting
black --check mbetterclient/
```

#### Linting with Pylint

```bash
# Lint all modules
pylint mbetterclient/

# Lint specific module
pylint mbetterclient/qt_player/
```

#### Type Checking with MyPy

```bash
# Type check
mypy mbetterclient/
```

### Testing

#### Running Tests

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=mbetterclient

# Run specific test file
pytest tests/test_message_bus.py

# Run PyQt tests (requires X server or Xvfb on Linux)
pytest tests/test_qt_player.py
```

#### Writing Tests

Example test structure:

```python
import pytest
from mbetterclient.core.message_bus import MessageBus, MessageType

class TestMessageBus:
    def setup_method(self):
        self.message_bus = MessageBus()
    
    def test_component_registration(self):
        queue = self.message_bus.register_component("test_component")
        assert queue is not None
        assert "test_component" in self.message_bus._queues
    
    def test_message_publishing(self):
        self.message_bus.register_component("sender")
        self.message_bus.register_component("receiver")
        
        message = Message(
            type=MessageType.VIDEO_PLAY,
            sender="sender",
            recipient="receiver",
            data={"file_path": "test.mp4"}
        )
        
        result = self.message_bus.publish(message)
        assert result is True
```

### Adding New Features

#### Creating Custom Templates

1. **Define Template Class**
   ```python
   # mbetterclient/qt_player/templates.py
   
   class CustomTemplate(OverlayTemplate):
       def __init__(self):
           super().__init__("custom_template", "Custom Template")
           self.fields = ["title", "content", "color"]
       
       def render(self, painter, size, data):
           # Custom rendering logic
           painter.setPen(QColor(data.get("color", "#FFFFFF")))
           painter.drawText(10, 30, data.get("title", ""))
           painter.drawText(10, 60, data.get("content", ""))
   ```

2. **Register Template**
   ```python
   # In template manager initialization
   template_manager.register_template(CustomTemplate())
   ```

#### Adding API Response Handlers

```python
# mbetterclient/api_client/client.py

class CustomResponseHandler(ResponseHandler):
    def handle_response(self, endpoint: APIEndpoint, response: requests.Response):
        try:
            data = response.json()
            processed_data = {
                'source': endpoint.name,
                'timestamp': datetime.utcnow().isoformat(),
                'custom_field': data.get('important_data')
            }
            return processed_data
        except Exception as e:
            return self.handle_error(endpoint, e)
```

#### Extending Web Dashboard

1. **Add New Route**
   ```python
   # mbetterclient/web_dashboard/routes.py
   
   @main_bp.route('/custom')
   @login_required
   def custom_page():
       return render_template('custom.html')
   ```

2. **Create Template**
   ```html
   <!-- mbetterclient/web_dashboard/templates/custom.html -->
   {% extends "base.html" %}
   
   {% block content %}
   <h1>Custom Page</h1>
   <p>Custom functionality here</p>
   {% endblock %}
   ```

### Message Bus System

#### Message Types

Define new message types in `core/message_bus.py`:

```python
class MessageType(Enum):
    # Add new message type
    CUSTOM_ACTION = "CUSTOM_ACTION"
```

#### Message Builders

Add helper methods for creating messages:

```python
@staticmethod
def custom_action(sender: str, action_data: Dict[str, Any]) -> Message:
    return Message(
        type=MessageType.CUSTOM_ACTION,
        sender=sender,
        data=action_data
    )
```

#### Message Handlers

Subscribe to messages in component initialization:

```python
def initialize(self) -> bool:
    self.message_bus.subscribe(
        self.name, 
        MessageType.CUSTOM_ACTION, 
        self._handle_custom_action
    )
    return True

def _handle_custom_action(self, message: Message):
    action_data = message.data
    # Process custom action
```

## Troubleshooting

### Common Issues

#### Application Won't Start

**Symptoms**: Python errors on startup, missing dependencies
**Solutions**:
1. Verify Python version: `python --version` (must be 3.8+)
2. Check virtual environment activation
3. Reinstall dependencies: `pip install -r requirements.txt --force-reinstall`
4. Check file permissions on configuration directory

#### Video Player Issues

**Symptoms**: Black screen, video won't play, no audio
**Solutions**:
1. Verify video file path and format
2. Check PyQt5 multimedia installation:
   ```bash
   python -c "from PyQt5.QtMultimedia import QMediaPlayer; print('OK')"
   ```
3. Install system multimedia codecs
4. Try different video format (MP4 recommended)
5. Check file permissions and disk space

#### Web Dashboard Inaccessible

**Symptoms**: Connection refused, page won't load
**Solutions**:
1. Check if port 5000 is already in use:
   ```bash
   # Linux/macOS
   lsof -i :5000
   # Windows
   netstat -an | findstr :5000
   ```
2. Try different port: `python main.py --web-port 8080`
3. Check firewall settings
4. Verify Flask installation: `pip show Flask`

#### Database Errors

**Symptoms**: SQLite errors, configuration not saving
**Solutions**:
1. Check database file permissions
2. Verify disk space availability
3. Delete corrupted database (will recreate):
   ```bash
   rm ~/.config/MbetterClient/mbetterclient.db
   ```
4. Check SQLite installation: `python -c "import sqlite3; print(sqlite3.sqlite_version)"`

#### API Client Not Working

**Symptoms**: External API requests failing, no data updates
**Solutions**:
1. Check internet connectivity
2. Verify API key and endpoint URL
3. Check API rate limits and quotas
4. Review application logs for specific errors
5. Test endpoint manually with curl:
   ```bash
   curl -H "Authorization: Bearer your-token" https://api.example.com/endpoint
   ```

### Logging and Debugging

#### Enable Debug Logging

```bash
# Run with debug logging
python main.py --log-level DEBUG

# Or set environment variable
export LOG_LEVEL=DEBUG
python main.py
```

#### Log File Locations

- **Linux**: `~/.config/MbetterClient/logs/`
- **macOS**: `~/Library/Application Support/MbetterClient/logs/`
- **Windows**: `%APPDATA%\MbetterClient\logs\`

#### Useful Log Commands

```bash
# View recent logs
tail -f ~/.config/MbetterClient/logs/app.log

# Search for errors
grep ERROR ~/.config/MbetterClient/logs/app.log

# Filter by component
grep "qt_player" ~/.config/MbetterClient/logs/app.log
```

### Performance Optimization

#### Video Performance

- Use hardware-accelerated video formats (H.264)
- Reduce video resolution for older hardware
- Close unused applications to free memory
- Use SSD storage for video files

#### Web Dashboard Performance

- Increase status update intervals for slower systems
- Disable real-time features if not needed
- Use browser developer tools to identify bottlenecks
- Consider using reverse proxy (nginx) for production

#### API Client Performance

- Adjust request intervals based on API limits
- Implement request caching for static data
- Use compression for large responses
- Monitor network usage and optimize accordingly

### Screen Casting Issues

#### FFmpeg Not Found

**Symptoms**: Screen casting fails to start, FFmpeg errors
**Solutions**:
1. Install FFmpeg on your system:
   ```bash
   # Linux
   sudo apt-get install ffmpeg
   # macOS
   brew install ffmpeg
   # Windows
   # Download from https://ffmpeg.org/download.html
   ```
2. Verify FFmpeg is in PATH: `ffmpeg -version`
3. Check FFmpeg permissions and accessibility

#### Chromecast Discovery Fails

**Symptoms**: No devices found, network discovery errors
**Solutions**:
1. Verify devices are on same network subnet
2. Check router multicast/broadcast settings
3. Ensure Chromecast devices are powered on
4. Restart network equipment and Chromecast devices
5. Check firewall rules for multicast traffic

#### Screen Capture Permission Issues

**Symptoms**: Screen capture fails, permission errors
**Solutions**:

**macOS**:
1. Open System Preferences → Security & Privacy → Privacy
2. Enable Screen Recording permission for Python/Terminal
3. Restart application after granting permissions

**Windows**:
1. Run application as Administrator if needed
2. Check Windows Privacy settings for screen capture
3. Ensure antivirus is not blocking screen capture

**Linux**:
1. Verify X11 display access: `echo $DISPLAY`
2. Check X11 permissions: `xhost +local:`
3. Ensure user is in audio group for audio capture

#### Audio Capture Issues

**Symptoms**: Video works but no audio in stream
**Solutions**:
1. Check audio device availability:
   ```bash
   # Linux
   pactl list sources short
   # Windows
   # Check Windows Sound settings
   # macOS
   # Check System Preferences → Sound → Input
   ```
2. Verify microphone permissions
3. Test audio with system tools before streaming
4. Check for audio device conflicts with other applications

#### Network Streaming Problems

**Symptoms**: Chromecast can't access stream, connection errors
**Solutions**:
1. Verify local IP detection is correct
2. Check firewall rules for HTTP streaming port (default 8000)
3. Test stream URL manually: `http://your-ip:8000/stream.mp4`
4. Ensure network bandwidth is sufficient for chosen bitrate
5. Try different streaming port if current is blocked

### Build Issues

#### PyInstaller Problems

**Symptoms**: Build fails, missing modules, large executable size
**Solutions**:
1. Update PyInstaller: `pip install --upgrade pyinstaller`
2. Clear PyInstaller cache: `pyi-makespec --clean main.py`
3. Add missing modules to hiddenimports in build.py:
   ```python
   hiddenimports=['ffmpeg', 'pychromecast']
   ```
4. Use UPX compression (if available): Set `upx=True` in build config
5. Exclude unnecessary modules in build.py

#### Screen Casting Dependencies

**Symptoms**: Built executable missing screen casting functionality
**Solutions**:
1. Ensure FFmpeg binary is included or available on target system
2. Add pychromecast and ffmpeg-python to hiddenimports
3. Include required system libraries for multimedia
4. Test screen casting functionality in built executable

#### Platform-Specific Issues

**Windows**:
- Install Visual C++ Redistributable
- Add Windows Defender exclusion for build directory
- Use Windows-compatible paths in configuration

**macOS**:
- Install Xcode command line tools: `xcode-select --install`
- Code signing may be required for distribution
- Use .icns icon format

**Linux**:
- Install required system libraries: `apt-get install python3-pyqt5.qtmultimedia`
- Ensure Qt libraries are available on target systems
- Use AppImage for better compatibility

## Advanced Topics

### Custom Response Handlers

Create specialized handlers for different API formats:

```python
class WeatherResponseHandler(ResponseHandler):
    def handle_response(self, endpoint: APIEndpoint, response: requests.Response):
        try:
            data = response.json()
            return {
                'source': 'weather',
                'temperature': data['main']['temp'],
                'condition': data['weather'][0]['description'],
                'location': data['name'],
                'overlay_text': f"{data['name']}: {data['main']['temp']}°C, {data['weather'][0]['description']}"
            }
        except Exception as e:
            logger.error(f"Weather processing error: {e}")
            return self.handle_error(endpoint, e)
```

### Database Schema Extensions

The application includes comprehensive match data models adapted from mbetterd:

#### Match Models

```python
# In database/models.py

class MatchModel(BaseModel):
    """Boxing matches from fixture files"""
    __tablename__ = 'matches'
    
    # Core match data
    match_number = Column(Integer, nullable=False, unique=True)
    fighter1_township = Column(String(255), nullable=False)
    fighter2_township = Column(String(255), nullable=False)
    venue_kampala_township = Column(String(255), nullable=False)
    
    # Match timing and results
    start_time = Column(DateTime)
    end_time = Column(DateTime)
    result = Column(String(255))
    
    # File metadata
    filename = Column(String(1024), nullable=False)
    file_sha1sum = Column(String(255), nullable=False)
    fixture_id = Column(String(255), nullable=False, unique=True)
    active_status = Column(Boolean, default=False)
    
    # ZIP upload tracking
    zip_filename = Column(String(1024))
    zip_sha1sum = Column(String(255))
    zip_upload_status = Column(String(20), default='pending')
    zip_upload_progress = Column(Float, default=0.0)
    
    # Relationships
    outcomes = relationship('MatchOutcomeModel', cascade='all, delete-orphan')

class MatchOutcomeModel(BaseModel):
    """Match outcome values from fixture files"""
    __tablename__ = 'match_outcomes'
    
    match_id = Column(Integer, ForeignKey('matches.id', ondelete='CASCADE'))
    column_name = Column(String(255), nullable=False)
    float_value = Column(Float, nullable=False)
    
    # Unique constraint on match_id + column_name
    __table_args__ = (
        UniqueConstraint('match_id', 'column_name'),
    )
```

#### Database Migration

```python
# Migration_008_AddMatchTables
class Migration_008_AddMatchTables(DatabaseMigration):
    def up(self, db_manager) -> bool:
        # Creates matches and match_outcomes tables with:
        # - Comprehensive indexing for performance
        # - Foreign key relationships with CASCADE DELETE
        # - Unique constraints for data integrity
        # - SQLite-compatible syntax
        pass
```

#### Custom Data Extensions

Add application-specific tables:

```python
class CustomData(Base):
    __tablename__ = 'custom_data'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    value = Column(Text)
    created_at = Column(DateTime, default=datetime.utcnow)
    
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'value': self.value,
            'created_at': self.created_at.isoformat()
        }
```

### Plugin System Architecture

While not fully implemented, the architecture supports plugin extensions:

```python
# Future plugin interface
class MbetterPlugin:
    def __init__(self, name: str):
        self.name = name
    
    def initialize(self, app_context):
        pass
    
    def get_routes(self):
        return []
    
    def get_message_handlers(self):
        return {}
    
    def shutdown(self):
        pass
```

### Security Considerations

#### Web Dashboard Security

- Change default passwords immediately
- Use HTTPS in production environments
- Implement rate limiting for API endpoints
- Regular token rotation
- Secure configuration file permissions

#### API Security

- Use strong JWT secrets
- Implement token expiration and refresh
- Validate all input data
- Log authentication attempts
- Monitor for unusual activity patterns

#### File System Security

- Restrict video file access paths
- Validate file types and sizes
- Use sandboxed directories with persistent user data locations
- Regular backup of configuration and database
- Cross-platform directory permission validation
- Secure PyInstaller executable data persistence

#### Cross-Platform Data Persistence

- **Windows**: All data stored in `%APPDATA%\MbetterClient\`
- **macOS**: Unified location at `~/Library/Application Support/MbetterClient/`
- **Linux**: Data in `~/.local/share/MbetterClient/`, config in `~/.config/MbetterClient/`
- **PyInstaller Detection**: Automatic runtime environment detection
- **Fallback Handling**: Graceful degradation to home directory if standard paths fail
- **Permission Testing**: Write verification before using directories

### Performance Monitoring

#### Built-in Metrics

Access metrics through the web dashboard or API:

```python
# Get system statistics
stats = {
    'memory_usage': psutil.Process().memory_info().rss / 1024 / 1024,  # MB
    'cpu_percent': psutil.Process().cpu_percent(),
    'thread_count': threading.active_count(),
    'uptime': time.time() - start_time
}
```

#### External Monitoring

Integrate with monitoring systems:

```python
# Example: Send metrics to external system
def send_metrics():
    metrics = get_system_metrics()
    requests.post('https://monitoring.example.com/metrics', json=metrics)
```

### Deployment Strategies

#### Production Deployment

1. **Use Process Manager**
   ```bash
   # With systemd
   sudo systemctl enable mbetterclient
   sudo systemctl start mbetterclient
   ```

2. **Reverse Proxy Setup**
   ```nginx
   server {
       listen 80;
       server_name mbetterclient.example.com;
       
       location / {
           proxy_pass http://127.0.0.1:5000;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
       }
   }
   ```

3. **SSL Configuration**
   ```bash
   # With Let's Encrypt
   certbot --nginx -d mbetterclient.example.com
   ```

#### Docker Deployment

```dockerfile
FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .
EXPOSE 5000

CMD ["python", "main.py", "--web-host", "0.0.0.0"]
```

This comprehensive documentation covers all aspects of MbetterClient from installation to advanced deployment scenarios. For additional support, please refer to the project repository or contact the development team.