# Data Models

## 4.1 Core Models

### User Model
```php
class User extends Authenticatable
{
    protected $fillable = [
        'name', 'email', 'password', 'phone', 'date_of_birth',
        'gender', 'nationality', 'profile_image', 'payment_status',
        'must_change_password', 'otp_code', 'otp_expires_at'
    ];

    protected $hidden = ['password', 'remember_token'];

    // Relationships
    public function teams() { return $this->hasMany(Team::class, 'captain_id'); }
    public function tournaments() { return $this->hasMany(Tournament::class, 'organizer_id'); }
    public function payments() { return $this->hasMany(Payment::class); }
    public function roles() { return $this->belongsToMany(Role::class); }
    public function player() { return $this->hasOne(Player::class); }
}
```

### Tournament Model
```php
class Tournament extends Model
{
    protected $fillable = [
        'name', 'slug', 'description', 'location', 'venue',
        'organizer', 'contact_email', 'contact_phone', 'website',
        'type', 'status', 'start_date', 'end_date',
        'registration_start', 'registration_end',
        'max_participants', 'min_participants',
        'auto_accept_registrations', 'registration_status',
        'game_title', 'game_version', 'format', 'team_size',
        'rounds', 'matches_per_round', 'bracket_settings',
        'stream_url', 'youtube_url', 'twitch_url',
        'is_streamed', 'is_featured', 'entry_fee',
        'prize_pool', 'prize_distribution', 'currency',
        'sponsor_info', 'rewards', 'total_participants',
        'total_matches', 'completed_matches',
        'average_match_duration', 'tournament_stats',
        'banner_image', 'logo_image', 'social_links',
        'announcement', 'visibility', 'allow_spectators',
        'require_approval', 'enable_two_tier_approval',
        'first_approver_id', 'second_approver_id',
        'approval_settings', 'admin_notes', 'metadata',
        'rules', 'settings', 'published_at', 'completed_at', 'cancelled_at'
    ];

    // Relationships
    public function brackets() { return $this->hasMany(Bracket::class); }
    public function gameMatches() { return $this->hasMany(GameMatch::class); }
    public function teams() { return $this->belongsToMany(Team::class); }
    public function organizer() { return $this->belongsTo(User::class, 'organizer_id'); }
}
```

## 4.2 User Management

### Role Model
```php
class Role extends Model
{
    protected $fillable = ['name', 'display_name', 'description', 'is_active'];

    public function users() { return $this->belongsToMany(User::class); }
    public function permissions() { return $this->belongsToMany(Permission::class); }
}
```

### Permission Model
```php
class Permission extends Model
{
    protected $fillable = ['name', 'display_name', 'description', 'category'];

    public function roles() { return $this->belongsToMany(Role::class); }
}
```

### User Roles
- **Super Admin**: Full system access
- **Admin**: Tournament and user management
- **Organizer**: Tournament management
- **Team Manager**: Team and player management
- **Player**: Player profile management
- **Referee**: Match management
- **Official**: Tournament operations

## 4.3 Tournament Management

### Bracket Model
```php
class Bracket extends Model
{
    protected $fillable = [
        'tournament_id', 'name', 'type', 'rounds', 'structure',
        'seeding', 'is_active', 'current_round', 'status'
    ];

    public function tournament() { return $this->belongsTo(Tournament::class); }
    public function gameMatches() { return $this->hasMany(GameMatch::class); }
}
```

### GameMatch Model
```php
class GameMatch extends Model
{
    protected $fillable = [
        'tournament_id', 'bracket_id', 'round', 'match_number',
        'team1_id', 'team2_id', 'player1_id', 'player2_id',
        'status', 'match_type', 'scheduled_at', 'started_at',
        'completed_at', 'team1_score', 'team2_score',
        'winner_id', 'winning_team_id', 'referee_id',
        'venue', 'notes', 'metadata'
    ];

    public function tournament() { return $this->belongsTo(Tournament::class); }
    public function bracket() { return $this->belongsTo(Bracket::class); }
    public function team1() { return $this->belongsTo(Team::class, 'team1_id'); }
    public function team2() { return $this->belongsTo(Team::class, 'team2_id'); }
    public function winner() { return $this->belongsTo(Team::class, 'winner_id'); }
}
```

## 4.4 Team Management

### Team Model
```php
class Team extends Model
{
    protected $fillable = [
        'name', 'description', 'logo', 'captain_id', 'status',
        'founded_year', 'location', 'contact_email', 'contact_phone',
        'website', 'social_links', 'achievements', 'statistics'
    ];

    public function captain() { return $this->belongsTo(User::class, 'captain_id'); }
    public function players() { return $this->hasMany(Player::class); }
    public function teamOfficials() { return $this->hasMany(TeamOfficial::class); }
    public function tournaments() { return $this->belongsToMany(Tournament::class); }
    public function formations() { return $this->hasMany(Formation::class); }
}
```

### Player Model
```php
class Player extends Model
{
    protected $fillable = [
        'user_id', 'team_id', 'jersey_number', 'position',
        'height', 'weight', 'preferred_foot', 'date_of_birth',
        'nationality', 'id_number', 'phone', 'email',
        'emergency_contact', 'medical_conditions', 'profile_image',
        'id_front_image', 'id_back_image', 'status', 'otp_verified',
        'otp_code', 'otp_expires_at', 'digital_id_generated',
        'statistics', 'achievements'
    ];

    public function user() { return $this->belongsTo(User::class); }
    public function team() { return $this->belongsTo(Team::class); }
    public function matches() { return $this->hasMany(GameMatch::class, 'player1_id'); }
}
```

### TeamOfficial Model
```php
class TeamOfficial extends Model
{
    protected $fillable = [
        'team_id', 'name', 'email', 'phone', 'position',
        'id_number', 'id_front_image', 'id_back_image',
        'status', 'otp_verified', 'otp_code', 'otp_expires_at'
    ];

    public function team() { return $this->belongsTo(Team::class); }
}
```

## 4.5 Player Management

### Formation Model
```php
class Formation extends Model
{
    protected $fillable = [
        'team_id', 'name', 'formation_data', 'is_default',
        'description', 'tactics', 'player_positions'
    ];

    public function team() { return $this->belongsTo(Team::class); }
}
```

### Player Statistics
```php
// Player statistics structure
'statistics' => [
    'matches_played' => 0,
    'goals_scored' => 0,
    'assists' => 0,
    'yellow_cards' => 0,
    'red_cards' => 0,
    'clean_sheets' => 0,
    'saves' => 0,
    'tackles' => 0,
    'passes_completed' => 0,
    'pass_accuracy' => 0.0
]
```

## 4.6 Match Management

### Match Statuses
- **scheduled**: Match is scheduled
- **live**: Match is in progress
- **completed**: Match is finished
- **cancelled**: Match was cancelled
- **postponed**: Match was postponed

### Match Types
- **team**: Team vs team match
- **individual**: Player vs player match
- **group**: Group stage match
- **knockout**: Elimination match
- **final**: Final match

### Match Results
```php
// Match result structure
'result' => [
    'team1_score' => 2,
    'team2_score' => 1,
    'winner_id' => 1,
    'winning_team_id' => 1,
    'penalty_shootout' => false,
    'extra_time' => false,
    'overtime' => false
]
```

## 4.7 Payment System

### Payment Model
```php
class Payment extends Model
{
    protected $fillable = [
        'user_id', 'team_id', 'payment_method', 'amount',
        'currency', 'reference_number', 'checkout_request_id',
        'merchant_request_id', 'status', 'paid_at',
        'failure_reason', 'description', 'payment_data'
    ];

    public function user() { return $this->belongsTo(User::class); }
    public function team() { return $this->belongsTo(Team::class); }
}
```

### Payment Statuses
- **pending**: Payment initiated
- **processing**: Payment in progress
- **completed**: Payment successful
- **failed**: Payment failed
- **cancelled**: Payment cancelled
- **refunded**: Payment refunded

### Payment Methods
- **mpesa**: M-Pesa STK Push
- **bank_transfer**: Bank transfer
- **cash**: Cash payment
- **card**: Credit/debit card

## 4.8 Media Management

### Media Model
```php
class Media extends Model
{
    protected $fillable = [
        'filename', 'original_name', 'mime_type', 'size',
        'path', 'url', 'alt_text', 'title', 'description',
        'collection', 'metadata', 'is_public'
    ];

    // Relationships
    public function tournaments() { return $this->morphedByMany(Tournament::class, 'mediable'); }
    public function teams() { return $this->morphedByMany(Team::class, 'mediable'); }
    public function players() { return $this->morphedByMany(Player::class, 'mediable'); }
}
```

### Media Types
- **image**: Image files (jpg, png, gif, webp)
- **document**: Document files (pdf, doc, docx)
- **video**: Video files (mp4, avi, mov)
- **audio**: Audio files (mp3, wav, aac)

---

## Model Relationships Summary

### Primary Relationships
```
User (1) ──┐
           ├── (1) Teams (1) ──┐
           │                  ├── (M) Players
           │                  ├── (M) TeamOfficials
           │                  └── (M) Formations
           │
           ├── (M) Tournaments
           │
           └── (M) Payments

Tournament (1) ──┐
                 ├── (M) Brackets
                 ├── (M) GameMatches
                 └── (M) Teams (M) ──┐
                                    └── (M) Players
```

### Secondary Relationships
```
Media (M) ──┐
            ├── (M) Tournaments
            ├── (M) Teams
            └── (M) Players

Role (M) ──┐
           └── (M) Users

Permission (M) ──┐
                 └── (M) Roles
```

---

## Next Steps

- [API Documentation](05_API_Documentation.md) - API endpoints and usage
- [Database](12_Database.md) - Database schema and migrations
- [Business Logic](10_Business_Logic.md) - Service layer implementation
- [Security](11_Security.md) - Security and authorization
