<?php
/**
 * Adaptiver Loader für Reifensätze
 * 
 * Features:
 * - Adaptive Lade-Strategien basierend auf Autohaus-Größe
 * - Intelligente Pagination
 * - Retry-Mechanismen
 * - Performance-Optimierung
 */

class AdaptiveLoader {
    private $autohausId;
    private $lastStrategy;
    private $retryCount = 0;
    private $maxRetries = 3;
    
    public function __construct($autohausId) {
        $this->autohausId = $autohausId;
    }
    
    /**
     * Lädt Reifensätze mit adaptiver Strategie
     */
    public function loadWheelsets($config) {
        $strategy = $this->selectStrategy($config);
        $this->lastStrategy = $strategy;
        
        error_log("Verwende Strategie: " . $strategy . " für Autohaus " . $this->autohausId);
        
        switch ($strategy) {
            case 'fast':
                return $this->loadFast($config);
            case 'balanced':
                return $this->loadBalanced($config);
            case 'thorough':
                return $this->loadThorough($config);
            case 'chunked':
                return $this->loadChunked($config);
            default:
                return $this->loadDefault($config);
        }
    }
    
    /**
     * Wählt optimale Lade-Strategie
     */
    private function selectStrategy($config) {
        $tier = $config['performance_tier'] ?? 'small';
        $lastCount = $config['last_wheelset_count'] ?? 0;
        
        if ($tier === 'large' || $lastCount > 1000) {
            return 'chunked';
        } elseif ($tier === 'medium' || $lastCount > 500) {
            return 'balanced';
        } elseif ($lastCount > 100) {
            return 'fast';
        } else {
            return 'thorough';
        }
    }
    
    /**
     * Schnelle Lade-Strategie (erste 10 Seiten)
     */
    private function loadFast($config) {
        $maxPages = min(10, $config['max_pages']);
        return $this->loadPages($config, 1, $maxPages, 15);
    }
    
    /**
     * Ausgewogene Lade-Strategie (erste 20 Seiten)
     */
    private function loadBalanced($config) {
        $maxPages = min(20, $config['max_pages']);
        return $this->loadPages($config, 1, $maxPages, 20);
    }
    
    /**
     * Gründliche Lade-Strategie (alle Seiten)
     */
    private function loadThorough($config) {
        return $this->loadPages($config, 1, $config['max_pages'], 30);
    }
    
    /**
     * Chunked Lade-Strategie (für sehr große Autohäuser)
     */
    private function loadChunked($config) {
        $chunkSize = 10;
        $allWheelsets = [];
        
        for ($startPage = 1; $startPage <= $config['max_pages']; $startPage += $chunkSize) {
            $endPage = min($startPage + $chunkSize - 1, $config['max_pages']);
            
            error_log("Lade Chunk: Seiten $startPage-$endPage");
            
            $chunkWheelsets = $this->loadPages($config, $startPage, $endPage, 15);
            $allWheelsets = array_merge($allWheelsets, $chunkWheelsets);
            
            // Kurze Pause zwischen Chunks
            usleep(500000); // 0.5 Sekunden
        }
        
        return $allWheelsets;
    }
    
    /**
     * Standard-Lade-Strategie
     */
    private function loadDefault($config) {
        return $this->loadPages($config, 1, $config['max_pages'], 20);
    }
    
    /**
     * Lädt spezifische Seiten
     */
    private function loadPages($config, $startPage, $endPage, $timeout) {
        $allWheelsets = [];
        $consecutiveEmptyPages = 0;
        
        // Setze Timeout
        set_time_limit($config['timeout']);
        
        $ch = $this->initializeCurl($config, $timeout);
        
        for ($page = $startPage; $page <= $endPage; $page++) {
            try {
                $pageWheelsets = $this->loadSinglePage($ch, $config, $page);
                
                if (empty($pageWheelsets)) {
                    $consecutiveEmptyPages++;
                    if ($consecutiveEmptyPages >= 3) {
                        error_log("3 aufeinanderfolgende leere Seiten, stoppe bei Seite $page");
                        break;
                    }
                } else {
                    $consecutiveEmptyPages = 0;
                    $allWheelsets = array_merge($allWheelsets, $pageWheelsets);
                    error_log("Seite $page: " . count($pageWheelsets) . " Reifensätze, Total: " . count($allWheelsets));
                }
                
                // Kurze Pause zwischen Requests
                usleep(100000); // 0.1 Sekunden
                
            } catch (Exception $e) {
                error_log("Fehler bei Seite $page: " . $e->getMessage());
                $this->retryCount++;
                
                if ($this->retryCount >= $this->maxRetries) {
                    error_log("Maximale Retry-Anzahl erreicht, stoppe");
                    break;
                }
                
                // Exponential backoff
                sleep(pow(2, $this->retryCount));
            }
        }
        
        curl_close($ch);
        return $allWheelsets;
    }
    
    /**
     * Initialisiert cURL mit optimalen Einstellungen
     */
    private function initializeCurl($config, $timeout) {
        $ch = curl_init();
        
        // Basis-Einstellungen
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
        
        // Cookie-Verwaltung
        curl_setopt($ch, CURLOPT_COOKIEJAR, sys_get_temp_dir() . '/resy_cookies_' . $this->autohausId . '.txt');
        curl_setopt($ch, CURLOPT_COOKIEFILE, sys_get_temp_dir() . '/resy_cookies_' . $this->autohausId . '.txt');
        
        // Headers
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language: de-DE,de;q=0.9,en;q=0.8',
            'Connection: keep-alive'
        ]);
        
        // Login durchführen
        $this->performLogin($ch, $config);
        
        return $ch;
    }
    
    /**
     * Führt Login durch
     */
    private function performLogin($ch, $config) {
        // Login-Seite laden
        curl_setopt($ch, CURLOPT_URL, $config['resy_base_url'] . '/index.php?m=login&a=login');
        curl_setopt($ch, CURLOPT_POST, false);
        $response = curl_exec($ch);
        
        if (curl_error($ch)) {
            throw new Exception('Login-Seite konnte nicht geladen werden: ' . curl_error($ch));
        }
        
        // Login-Daten senden
        $postData = [
            'FN' => 'login',
            'UserName' => $config['resy_username'],
            'Password' => $config['resy_password'],
            'button' => 'submit'
        ];
        
        curl_setopt($ch, CURLOPT_URL, $config['resy_base_url'] . '/index.php?m=login&a=login');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded',
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language: de-DE,de;q=0.9,en;q=0.8',
            'Referer: ' . $config['resy_base_url'] . '/index.php?m=login&a=login'
        ]);
        
        $loginResponse = curl_exec($ch);
        
        if (curl_error($ch)) {
            throw new Exception('Login fehlgeschlagen: ' . curl_error($ch));
        }
        
        // Prüfe Login-Erfolg
        if (strpos($loginResponse, 'Anmeldename') !== false) {
            throw new Exception('Login fehlgeschlagen - Login-Formular erkannt');
        }
        
        error_log("Login erfolgreich für Autohaus " . $this->autohausId);
    }
    
    /**
     * Lädt eine einzelne Seite
     */
    private function loadSinglePage($ch, $config, $page) {
        $searchUrl = $config['resy_base_url'] . '/index.php?m=wheelset&a=search';
        
        $postData = [
            'FN' => 'WheelsetSearch',
            'a' => 'search',
            'm' => 'wheelset',
            'KD_ID' => $config['resy_dealer_id'],
            'STATUS_ID' => '20', // eingelagert
            'Page' => $page,
            'button' => 'submit'
        ];
        
        curl_setopt($ch, CURLOPT_URL, $searchUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded',
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language: de-DE,de;q=0.9,en;q=0.8',
            'Referer: ' . $config['resy_base_url'] . '/index.php?m=wheelset&a=search'
        ]);
        
        $response = curl_exec($ch);
        
        if (curl_error($ch)) {
            throw new Exception('Fehler beim Laden der Seite ' . $page . ': ' . curl_error($ch));
        }
        
        // Parse die Antwort
        return $this->parsePageResponse($response);
    }
    
    /**
     * Parst die Antwort einer Seite
     */
    private function parsePageResponse($html) {
        $wheelsets = [];
        
        // Vereinfachte Parsing-Logik
        if (preg_match_all('/LGS_ID[^>]*>([^<]+)</', $html, $matches)) {
            $lgsData = $matches[1];
            $chunks = array_chunk($lgsData, 5);
            
            foreach ($chunks as $index => $chunk) {
                if ($index === 0) continue; // Überspringe Header
                
                if (count($chunk) >= 5) {
                    $wheelsets[] = [
                        'satznummer' => trim($chunk[0]),
                        'kennzeichen' => trim($chunk[1]),
                        'fahrzeug' => trim($chunk[2]),
                        'halter' => 'Unbekannt', // Vereinfacht
                        'eingangsdatum' => trim($chunk[4]),
                        'status' => 'eingelagert'
                    ];
                }
            }
        }
        
        return $wheelsets;
    }
    
    /**
     * Gibt die letzte verwendete Strategie zurück
     */
    public function getLastStrategy() {
        return $this->lastStrategy;
    }
}
?>

