# Struktura Projektu Meme Battle - System Statystyk

## 📂 Struktura katalogów

```
meme_compare/
│
├── 📄 index.php                    # Główna strona głosowania
├── 📄 ranking.php                  # Lista rankingowa memów
├── 📄 upload.php                   # Upload nowych memów + detekcja duplikatów
├── 📄 meme_stats.php              # ⭐ NOWE: Statystyki pojedynczego mema
├── 📄 vote.php                    # Logika głosowania + zapis do battles
├── 📄 admin.php                   # Panel administracyjny
│
├── 📄 db.php                      # Połączenie z bazą + tworzenie tabel
├── 📄 functions.php               # Funkcje pomocnicze + nowe funkcje stats
│
├── 📄 update_existing_db.php      # ⭐ NOWE: Skrypt aktualizacji bazy
├── 📄 db_migrate.php              # ⭐ NOWE: Migracja CLI
│
├── 📄 memes.db                    # Baza danych SQLite
├── 📄 php.ini                     # Konfiguracja PHP
├── 📄 run.bat                     # Skrypt uruchamiający (Windows)
│
├── 📁 meme/                       # Folder z obrazkami memów
├── 📁 uploads/                    # Folder tymczasowy
├── 📁 sessions/                   # Sesje PHP
│
├── 📁 assets/
│   ├── 📁 css/
│   │   └── style.css
│   └── 📁 js/
│       └── mobile-menu.js
│
└── 📚 Dokumentacja:
    ├── README.md                  # Główny README
    ├── CHANGELOG.md               # ⭐ NOWE: Podsumowanie zmian
    ├── STATS_DOCUMENTATION.md     # ⭐ NOWE: Szczegółowa dokumentacja
    ├── TESTING_GUIDE.md           # ⭐ NOWE: Przewodnik testowania
    ├── implementation_plan.md     # Oryginalny plan
    └── implementation_stats.md    # ⭐ NOWE: Plan systemu statystyk
```

## 🗄️ Schemat bazy danych

```
┌─────────────────────────────────────────────────────────────┐
│                      MEMES.DB (SQLite)                      │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────┐
│        memes            │
├─────────────────────────┤
│ id (PK)                 │◄─────────┐
│ filename                │          │
│ file_hash (SHA-256)     │          │ FK
│ rating                  │          │
│ wins                    │          │
│ losses                  │          │
│ created_at              │          │
└─────────────────────────┘          │
                                     │
         ┌───────────────────────────┼──────────────────┐
         │                           │                  │
         │                           │                  │
┌────────▼──────────────┐   ┌────────▼────────────┐    │
│      battles          │   │   rating_history    │    │
├───────────────────────┤   ├─────────────────────┤    │
│ id (PK)               │   │ id (PK)             │    │
│ winner_id (FK) ───────┼───┤ meme_id (FK)        │◄───┘
│ loser_id (FK) ────────┼───┤ rating              │
│ winner_rating_before  │   │ rank_position       │
│ winner_rating_after   │   │ recorded_at         │
│ loser_rating_before   │   └─────────────────────┘
│ loser_rating_after    │
│ battle_date           │
└───────────────────────┘

Indeksy:
• idx_memes_hash
• idx_battles_winner
• idx_battles_loser
• idx_battles_date
• idx_rating_history_meme
• idx_rating_history_date
```

## 🔄 Przepływ danych

### 1️⃣ Upload Mema
```
Użytkownik → upload.php
                ↓
         Oblicz SHA-256 hash
                ↓
      checkDuplicateByHash()
                ↓
        Duplikat? ──YES→ Błąd: "Plik już istnieje"
                ↓ NO
         Zapisz plik
                ↓
    INSERT INTO memes (filename, file_hash)
                ↓
    INSERT INTO rating_history (initial)
                ↓
            Sukces!
```

### 2️⃣ Głosowanie
```
Użytkownik → vote.php
                ↓
    Pobierz rating Winner & Loser
                ↓
       calculateElo() → Nowe ratingi
                ↓
    ┌────────────────────────┐
    │ UPDATE memes (rating)  │
    │ recordBattle()         │ ← Zapisz do battles
    │ updateRatingHistory()  │ ← 2x (winner + loser)
    └────────────────────────┘
                ↓
         Return JSON
                ↓
    Odśwież stronę
```

### 3️⃣ Wyświetlanie Statystyk
```
Użytkownik → meme_stats.php?id=X
                ↓
    ┌─────────────────────────────┐
    │ SELECT FROM memes           │
    │ getMemeHistory()            │ ← rating_history
    │ getMemeBattles()            │ ← battles + JOINs
    └─────────────────────────────┘
                ↓
    Przygotuj dane do Chart.js
                ↓
    Renderuj wykres + tabelę
```

## 📝 Kluczowe funkcje w `functions.php`

```php
// Oryginalne funkcje:
calculateElo($ratingA, $ratingB, $scoreA, $k)  // Algorytm ELO
getRandomPair($db)                              // Losowa para memów
getLeaderboard($db, $limit)                     // Top ranking

// ⭐ NOWE funkcje statystyk:
calculateFileHash($filepath)                    // SHA-256 hash
checkDuplicateByHash($db, $hash)               // Wykryj duplikat
recordBattle($db, ...)                         // Zapisz pojedynek
updateRatingHistory($db, $memeId, $rating)     // Historia ratingu
getMemeHistory($db, $memeId, $limit)           // Pobierz historię
getMemeBattles($db, $memeId, $limit)           // Pobierz pojedynki
```

## 🎨 Strony użytkownika

```
┌─────────────┐
│  index.php  │ ← Głosowanie (VS)
└──────┬──────┘
       │
┌──────▼────────┐
│ ranking.php   │ ← Tabela rankingowa
└──────┬────────┘
       │
       │  [Kliknij "Zobacz"]
       │
┌──────▼─────────────┐
│ meme_stats.php     │ ← ⭐ Statystyki mema
│                    │   • Wykres ratingu
│                    │   • Historia walk
│                    │   • Win/Loss ratio
└────────────────────┘
```

## 🔐 Bezpieczeństwo

```
✅ Prepared Statements      (SQL Injection)
✅ htmlspecialchars()        (XSS)
✅ Type casting (int)        (Type Juggling)
✅ File type validation      (Upload Security)
✅ SHA-256 hashing          (Integrity)
✅ Foreign Keys CASCADE      (Data Integrity)
```

## ⚡ Optymalizacje wydajności

```
🚀 Indeksy na:
   • file_hash (UNIQUE lookups)
   • winner_id, loser_id (JOINs)
   • battle_date (Sorting)
   • meme_id (History queries)
   
🚀 LIMIT w zapytaniach:
   • getMemeHistory($limit = 50)
   • getMemeBattles($limit = 20)
   • getLeaderboard($limit = 50)

🚀 Lazy Loading:
   • Wykres tylko gdy >1 wpis
   • Chart.js CDN (cache)
```

## 🛠️ Narzędzia deweloperskie

```
📊 Testowanie:
   • TESTING_GUIDE.md
   • test_integrity.php (do utworzenia)
   • test_battles.php (do utworzenia)

📚 Dokumentacja:
   • STATS_DOCUMENTATION.md (pełna dokumentacja SQL)
   • CHANGELOG.md (lista zmian)
   • README.md (quick start)

🔧 Maintenance:
   • update_existing_db.php (migracja danych)
   • db_migrate.php (CLI migration)
```

## 📈 Metryki systemu

Po implementacji system śledzi:
- ✅ **~100%** memów z unikalnymi hashami
- ✅ **~100%** pojedynków zapisanych
- ✅ **2 wpisy** w rating_history na pojedynek
- ✅ **0** duplikatów możliwych do uploadu
- ✅ **∞** historia pojedynków (bez limitu)
- ✅ **Chart.js** wizualizacja zmian

## 🎯 Przykładowe dane

```sql
-- Przykładowy rekord w battles:
INSERT INTO battles VALUES (
    1,                  -- id
    5,                  -- winner_id
    12,                 -- loser_id
    1245,               -- winner_rating_before
    1258,               -- winner_rating_after (+13)
    1189,               -- loser_rating_before
    1176,               -- loser_rating_after (-13)
    '2026-01-05 11:30:45'  -- battle_date
);

-- Przykładowy rekord w rating_history:
INSERT INTO rating_history VALUES (
    42,                 -- id
    5,                  -- meme_id
    1258,               -- rating
    3,                  -- rank_position
    '2026-01-05 11:30:45'  -- recorded_at
);
```
