<?php
/**
 * Klasa DataExport - eksport danych do CSV
 */

class DataExport
{
    private Database $db;
    
    public function __construct()
    {
        $this->db = Database::getInstance();
    }
    
    /**
     * Eksportuj użytkowników do CSV
     */
    public function exportUsers(?array $currentUser = null): string
    {
        // Pobierz dane
        if ($currentUser && $currentUser['role'] === 'reseller') {
            $users = $this->db->fetchAll(
                "SELECT u.id, u.username, u.role, u.device_limit, u.playlist_limit,
                        u.is_active, u.created_at, u.last_login, u.login_count,
                        (SELECT COUNT(*) FROM devices WHERE user_id = u.id) as devices_count,
                        (SELECT COUNT(*) FROM playlists p JOIN devices d ON p.device_id = d.id WHERE d.user_id = u.id) as playlists_count
                 FROM users u
                 WHERE u.parent_id = :parent_id
                 ORDER BY u.username",
                ['parent_id' => $currentUser['id']]
            );
        } else {
            $users = $this->db->fetchAll(
                "SELECT u.id, u.username, u.role, u.device_limit, u.playlist_limit,
                        u.max_users, u.max_devices, u.max_playlists,
                        u.is_active, u.created_at, u.last_login, u.login_count,
                        u.api_calls_count, p.username as parent_name,
                        (SELECT COUNT(*) FROM devices WHERE user_id = u.id) as devices_count,
                        (SELECT COUNT(*) FROM playlists pl JOIN devices d ON pl.device_id = d.id WHERE d.user_id = u.id) as playlists_count
                 FROM users u
                 LEFT JOIN users p ON u.parent_id = p.id
                 ORDER BY u.username"
            );
        }
        
        // Nagłówki
        $headers = [
            'ID', 'Użytkownik', 'Rola', 'Limit urządzeń', 'Limit playlist',
            'Aktywny', 'Utworzony', 'Ostatnie logowanie', 'Liczba logowań',
            'Urządzenia', 'Playlisty'
        ];
        
        if (!$currentUser || $currentUser['role'] === 'admin') {
            $headers = array_merge($headers, ['Reseller', 'Max userów', 'Max urządzeń', 'Max playlist', 'API calls']);
        }
        
        return $this->generateCsv($headers, $users);
    }
    
    /**
     * Eksportuj urządzenia do CSV
     */
    public function exportDevices(?array $currentUser = null, ?int $userId = null): string
    {
        $sql = "SELECT d.id, d.mac, d.code, d.name, d.is_blocked, d.created_at, d.updated_at,
                       d.api_calls_count, d.api_last_call, d.last_ip,
                       u.username as owner,
                       (SELECT COUNT(*) FROM playlists WHERE device_id = d.id) as playlists_count
                FROM devices d
                JOIN users u ON d.user_id = u.id";
        
        $params = [];
        
        if ($userId) {
            $sql .= " WHERE d.user_id = :user_id";
            $params['user_id'] = $userId;
        } elseif ($currentUser && $currentUser['role'] === 'reseller') {
            $sql .= " WHERE d.user_id IN (SELECT id FROM users WHERE parent_id = :parent_id OR id = :parent_id2)";
            $params['parent_id'] = $currentUser['id'];
            $params['parent_id2'] = $currentUser['id'];
        } elseif ($currentUser && $currentUser['role'] === 'user') {
            $sql .= " WHERE d.user_id = :user_id";
            $params['user_id'] = $currentUser['id'];
        }
        
        $sql .= " ORDER BY d.created_at DESC";
        
        $devices = $this->db->fetchAll($sql, $params);
        
        $headers = [
            'ID', 'MAC', 'Kod', 'Nazwa', 'Właściciel', 'Zablokowane',
            'Utworzone', 'Zaktualizowane', 'Playlisty', 'API calls', 'Ostatnie API', 'Ostatnie IP'
        ];
        
        return $this->generateCsv($headers, $devices);
    }
    
    /**
     * Eksportuj playlisty do CSV
     */
    public function exportPlaylists(?array $currentUser = null, ?int $deviceId = null): string
    {
        $sql = "SELECT p.id, p.name, p.type, p.is_active, p.sort_order,
                       p.created_at, p.updated_at, p.config_json,
                       d.mac as device_mac, d.name as device_name,
                       u.username as owner
                FROM playlists p
                JOIN devices d ON p.device_id = d.id
                JOIN users u ON d.user_id = u.id";
        
        $params = [];
        
        if ($deviceId) {
            $sql .= " WHERE p.device_id = :device_id";
            $params['device_id'] = $deviceId;
        } elseif ($currentUser && $currentUser['role'] === 'reseller') {
            $sql .= " WHERE d.user_id IN (SELECT id FROM users WHERE parent_id = :parent_id OR id = :parent_id2)";
            $params['parent_id'] = $currentUser['id'];
            $params['parent_id2'] = $currentUser['id'];
        } elseif ($currentUser && $currentUser['role'] === 'user') {
            $sql .= " WHERE d.user_id = :user_id";
            $params['user_id'] = $currentUser['id'];
        }
        
        $sql .= " ORDER BY p.created_at DESC";
        
        $playlists = $this->db->fetchAll($sql, $params);
        
        // Przetwórz config_json
        foreach ($playlists as &$p) {
            $config = json_decode($p['config_json'], true);
            unset($p['config_json']);
            
            // Dodaj pola z config w zależności od typu
            switch ($p['type']) {
                case 'xtream':
                    $p['host'] = $config['host'] ?? '';
                    $p['port'] = $config['port'] ?? '';
                    $p['username'] = $config['username'] ?? '';
                    $p['password'] = $config['password'] ?? '';
                    $p['mac_stalker'] = '';
                    break;
                case 'm3u':
                    $p['host'] = $config['url'] ?? '';
                    $p['port'] = '';
                    $p['username'] = '';
                    $p['password'] = '';
                    $p['mac_stalker'] = '';
                    break;
                case 'stalker':
                    $p['host'] = $config['server_url'] ?? $config['url'] ?? '';
                    $p['port'] = '';
                    $p['username'] = $config['mac_address'] ?? $config['mac'] ?? '';
                    $p['password'] = $config['serial_number'] ?? $config['token'] ?? '';
                    $p['mac_stalker'] = $config['mac_address'] ?? $config['mac'] ?? '';
                    break;
                default:
                    $p['host'] = '';
                    $p['port'] = '';
                    $p['username'] = '';
                    $p['password'] = '';
                    $p['mac_stalker'] = '';
            }
        }
        
        $headers = [
            'ID', 'Nazwa', 'Typ', 'Aktywna', 'Kolejność',
            'Utworzona', 'Zaktualizowana',
            'MAC urządzenia', 'Nazwa urządzenia', 'Właściciel',
            'Host/URL', 'Port', 'Użytkownik', 'Hasło', 'MAC (Stalker)'
        ];
        
        return $this->generateCsv($headers, $playlists);
    }
    
    /**
     * Eksportuj historię logowań do CSV
     */
    public function exportLoginHistory(?int $userId = null, int $days = 30): string
    {
        $sql = "SELECT lh.id, u.username, lh.ip_address, lh.browser, lh.os, lh.device_type,
                       lh.country, lh.city, lh.success, lh.failure_reason, lh.created_at
                FROM login_history lh
                JOIN users u ON lh.user_id = u.id
                WHERE lh.created_at > datetime('now', '-' || :days || ' days')";
        
        $params = ['days' => $days];
        
        if ($userId) {
            $sql .= " AND lh.user_id = :user_id";
            $params['user_id'] = $userId;
        }
        
        $sql .= " ORDER BY lh.created_at DESC";
        
        $history = $this->db->fetchAll($sql, $params);
        
        // Przekonwertuj success na tekst
        foreach ($history as &$h) {
            $h['success'] = $h['success'] ? 'Tak' : 'Nie';
        }
        
        $headers = [
            'ID', 'Użytkownik', 'IP', 'Przeglądarka', 'System', 'Typ urządzenia',
            'Kraj', 'Miasto', 'Sukces', 'Powód błędu', 'Data'
        ];
        
        return $this->generateCsv($headers, $history);
    }
    
    /**
     * Eksportuj logi API do CSV
     */
    public function exportApiLogs(int $days = 30): string
    {
        $sql = "SELECT al.id, d.mac, d.name as device_name, u.username,
                       al.endpoint, al.ip_address, al.playlists_count, al.created_at
                FROM api_logs al
                LEFT JOIN devices d ON al.device_id = d.id
                LEFT JOIN users u ON d.user_id = u.id
                WHERE al.created_at > datetime('now', '-' || :days || ' days')
                ORDER BY al.created_at DESC";
        
        $logs = $this->db->fetchAll($sql, ['days' => $days]);
        
        $headers = [
            'ID', 'MAC', 'Urządzenie', 'Właściciel', 'Endpoint', 'IP', 'Playlisty', 'Data'
        ];
        
        return $this->generateCsv($headers, $logs);
    }
    
    /**
     * Eksportuj historię zmian playlist do CSV
     */
    public function exportPlaylistHistory(?int $playlistId = null, int $days = 30): string
    {
        $sql = "SELECT ph.id, p.name as playlist_name, d.mac as device_mac, u.username,
                       ph.action, ph.field_name, ph.old_value, ph.new_value, 
                       ph.ip_address, ph.created_at
                FROM playlist_history ph
                LEFT JOIN playlists p ON ph.playlist_id = p.id
                LEFT JOIN devices d ON p.device_id = d.id
                LEFT JOIN users u ON ph.user_id = u.id
                WHERE ph.created_at > datetime('now', '-' || :days || ' days')";
        
        $params = ['days' => $days];
        
        if ($playlistId) {
            $sql .= " AND ph.playlist_id = :playlist_id";
            $params['playlist_id'] = $playlistId;
        }
        
        $sql .= " ORDER BY ph.created_at DESC";
        
        $history = $this->db->fetchAll($sql, $params);
        
        $headers = [
            'ID', 'Playlista', 'MAC', 'Użytkownik', 'Akcja', 'Pole',
            'Stara wartość', 'Nowa wartość', 'IP', 'Data'
        ];
        
        return $this->generateCsv($headers, $history);
    }
    
    /**
     * Generuj CSV
     */
    private function generateCsv(array $headers, array $data): string
    {
        $output = fopen('php://temp', 'r+');
        
        // BOM dla Excel (UTF-8)
        fwrite($output, "\xEF\xBB\xBF");
        
        // Nagłówki - pełna sygnatura fputcsv dla PHP 8.1+
        fputcsv($output, $headers, ';', '"', '\\');
        
        // Dane
        foreach ($data as $row) {
            $values = [];
            foreach ($row as $value) {
                // Konwertuj wartości
                if (is_bool($value)) {
                    $value = $value ? 'Tak' : 'Nie';
                } elseif ($value === null) {
                    $value = '';
                } elseif (is_array($value)) {
                    $value = json_encode($value, JSON_UNESCAPED_UNICODE);
                }
                $values[] = $value;
            }
            fputcsv($output, $values, ';', '"', '\\');
        }
        
        rewind($output);
        $csv = stream_get_contents($output);
        fclose($output);
        
        return $csv;
    }
    
    /**
     * Wyślij CSV jako plik do pobrania
     */
    public function downloadCsv(string $csv, string $filename): void
    {
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Length: ' . strlen($csv));
        header('Cache-Control: no-cache, no-store, must-revalidate');
        header('Pragma: no-cache');
        header('Expires: 0');
        
        echo $csv;
        exit;
    }
}
