<?php
/**
 * Klasa PlaylistHistory - historia zmian playlist (audit log)
 */

class PlaylistHistory
{
    private Database $db;
    
    const ACTION_CREATED = 'created';
    const ACTION_UPDATED = 'updated';
    const ACTION_DELETED = 'deleted';
    const ACTION_CLONED = 'cloned';
    const ACTION_ACTIVATED = 'activated';
    const ACTION_DEACTIVATED = 'deactivated';
    
    public function __construct()
    {
        $this->db = Database::getInstance();
    }
    
    /**
     * Zapisz zmianę
     */
    public function log(int $playlistId, ?int $userId, string $action, ?string $fieldName = null, $oldValue = null, $newValue = null): int
    {
        $ip = $_SERVER['REMOTE_ADDR'] ?? null;
        
        // Konwertuj wartości do string
        if (is_array($oldValue)) $oldValue = json_encode($oldValue, JSON_UNESCAPED_UNICODE);
        if (is_array($newValue)) $newValue = json_encode($newValue, JSON_UNESCAPED_UNICODE);
        
        return $this->db->insert(
            "INSERT INTO playlist_history 
             (playlist_id, user_id, action, field_name, old_value, new_value, ip_address)
             VALUES (:playlist_id, :user_id, :action, :field_name, :old_value, :new_value, :ip)",
            [
                'playlist_id' => $playlistId,
                'user_id' => $userId,
                'action' => $action,
                'field_name' => $fieldName,
                'old_value' => $oldValue,
                'new_value' => $newValue,
                'ip' => $ip
            ]
        );
    }
    
    /**
     * Zapisz utworzenie playlisty
     */
    public function logCreated(int $playlistId, ?int $userId, array $data): void
    {
        $this->log($playlistId, $userId, self::ACTION_CREATED, 'all', null, $data);
    }
    
    /**
     * Zapisz aktualizację playlisty
     */
    public function logUpdated(int $playlistId, ?int $userId, array $oldData, array $newData): void
    {
        // Porównaj i zapisz tylko zmienione pola
        $fieldsToTrack = ['name', 'type', 'config_json', 'is_active', 'sort_order'];
        
        foreach ($fieldsToTrack as $field) {
            $oldVal = $oldData[$field] ?? null;
            $newVal = $newData[$field] ?? null;
            
            if ($oldVal !== $newVal) {
                // Dla config_json dekoduj do czytelnej formy
                if ($field === 'config_json') {
                    $oldVal = json_decode($oldVal, true);
                    $newVal = json_decode($newVal, true);
                }
                
                $this->log($playlistId, $userId, self::ACTION_UPDATED, $field, $oldVal, $newVal);
            }
        }
    }
    
    /**
     * Zapisz usunięcie playlisty
     */
    public function logDeleted(int $playlistId, ?int $userId, array $data): void
    {
        $this->log($playlistId, $userId, self::ACTION_DELETED, 'all', $data, null);
    }
    
    /**
     * Zapisz sklonowanie playlisty
     */
    public function logCloned(int $playlistId, ?int $userId, int $sourceId): void
    {
        $this->log($playlistId, $userId, self::ACTION_CLONED, 'source_id', null, $sourceId);
    }
    
    /**
     * Pobierz historię playlisty
     */
    public function getByPlaylistId(int $playlistId, int $limit = 50): array
    {
        return $this->db->fetchAll(
            "SELECT ph.*, u.username
             FROM playlist_history ph
             LEFT JOIN users u ON ph.user_id = u.id
             WHERE ph.playlist_id = :playlist_id
             ORDER BY ph.created_at DESC
             LIMIT :limit",
            ['playlist_id' => $playlistId, 'limit' => $limit]
        );
    }
    
    /**
     * Pobierz całą historię (dla admina)
     */
    public function getAll(int $limit = 100, int $offset = 0, ?int $userId = null, ?int $playlistId = null): array
    {
        $sql = "SELECT ph.*, u.username, p.name as playlist_name, d.mac as device_mac
                FROM playlist_history ph
                LEFT JOIN users u ON ph.user_id = u.id
                LEFT JOIN playlists p ON ph.playlist_id = p.id
                LEFT JOIN devices d ON p.device_id = d.id
                WHERE 1=1";
        
        $params = ['limit' => $limit, 'offset' => $offset];
        
        if ($userId) {
            $sql .= " AND ph.user_id = :user_id";
            $params['user_id'] = $userId;
        }
        
        if ($playlistId) {
            $sql .= " AND ph.playlist_id = :playlist_id";
            $params['playlist_id'] = $playlistId;
        }
        
        $sql .= " ORDER BY ph.created_at DESC LIMIT :limit OFFSET :offset";
        
        return $this->db->fetchAll($sql, $params);
    }
    
    /**
     * Zlicz historię
     */
    public function count(?int $userId = null, ?int $playlistId = null): int
    {
        $sql = "SELECT COUNT(*) as count FROM playlist_history WHERE 1=1";
        $params = [];
        
        if ($userId) {
            $sql .= " AND user_id = :user_id";
            $params['user_id'] = $userId;
        }
        
        if ($playlistId) {
            $sql .= " AND playlist_id = :playlist_id";
            $params['playlist_id'] = $playlistId;
        }
        
        $result = $this->db->fetchOne($sql, $params);
        return $result['count'] ?? 0;
    }
    
    /**
     * Statystyki zmian
     */
    public function getStats(int $days = 30, ?int $userId = null): array
    {
        $params = ['days' => $days];
        $userFilter = '';
        
        if ($userId) {
            $userFilter = 'AND user_id = :user_id';
            $params['user_id'] = $userId;
        }
        
        // Zmiany per dzień
        $perDay = $this->db->fetchAll(
            "SELECT date(created_at) as date, COUNT(*) as count
             FROM playlist_history 
             WHERE created_at > datetime('now', '-' || :days || ' days') {$userFilter}
             GROUP BY date(created_at)
             ORDER BY date ASC",
            $params
        );
        
        // Top użytkownicy
        $topUsers = $this->db->fetchAll(
            "SELECT ph.user_id, u.username, COUNT(*) as count
             FROM playlist_history ph
             LEFT JOIN users u ON ph.user_id = u.id
             WHERE ph.created_at > datetime('now', '-' || :days || ' days') {$userFilter}
             GROUP BY ph.user_id
             ORDER BY count DESC
             LIMIT 10",
            $params
        );
        
        // Top akcje
        $topActions = $this->db->fetchAll(
            "SELECT action, COUNT(*) as count
             FROM playlist_history 
             WHERE created_at > datetime('now', '-' || :days || ' days') {$userFilter}
             GROUP BY action
             ORDER BY count DESC",
            $params
        );
        
        return [
            'per_day' => $perDay,
            'top_users' => $topUsers,
            'top_actions' => $topActions
        ];
    }
    
    /**
     * Formatuj akcję do wyświetlenia
     */
    public static function formatAction(string $action): string
    {
        $labels = [
            self::ACTION_CREATED => 'Utworzono',
            self::ACTION_UPDATED => 'Zaktualizowano',
            self::ACTION_DELETED => 'Usunięto',
            self::ACTION_CLONED => 'Sklonowano',
            self::ACTION_ACTIVATED => 'Aktywowano',
            self::ACTION_DEACTIVATED => 'Dezaktywowano'
        ];
        
        return $labels[$action] ?? $action;
    }
    
    /**
     * Formatuj nazwę pola
     */
    public static function formatFieldName(string $field): string
    {
        $labels = [
            'name' => 'Nazwa',
            'type' => 'Typ',
            'config_json' => 'Konfiguracja',
            'is_active' => 'Status',
            'sort_order' => 'Kolejność',
            'all' => 'Wszystko',
            'source_id' => 'Źródło'
        ];
        
        return $labels[$field] ?? $field;
    }
}
