<?php
/**
 * FavMasToKey - Traitement des favoris
 */

// Définir la constante pour inclure les fichiers
define('FAVMASTOKEY', true);

// Forcer les en-têtes JSON dès le début pour éviter tout conflit
header('Content-Type: application/json');

// Activer la capture d'erreurs
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    echo json_encode([
        'success' => false,
        'message' => "Erreur PHP: $errstr (ligne $errline dans $errfile)",
    ]);
    exit;
});

try {
    // Inclure les fichiers requis
    require_once 'includes/config.php';
    require_once 'includes/functions.php';

    // Vérifier que la requête est en POST
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(405);
        echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
        exit;
    }

    // Vérifier que l'utilisateur est authentifié
    if (!isset($_SESSION['misskey_token']) || empty($_SESSION['misskey_token'])) {
        http_response_code(401);
        echo json_encode(['success' => false, 'message' => 'Non authentifié']);
        exit;
    }

    // Récupérer l'instance Misskey
    $misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
    if (empty($misskey_instance)) {
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Instance Misskey non définie']);
        exit;
    }

    // Récupérer le token d'accès
    $token = $_SESSION['misskey_token'];

    // Récupérer les données envoyées
    $input_data = file_get_contents('php://input');
    $input = json_decode($input_data, true);
    
    if (!$input || !isset($input['batch']) || !is_array($input['batch'])) {
        http_response_code(400);
        echo json_encode([
            'success' => false, 
            'message' => 'Données invalides',
            'debug' => [
                'received' => $input_data ? substr($input_data, 0, 200) . '...' : 'Aucune donnée reçue'
            ]
        ]);
        exit;
    }

    $receivedParams = [
        'tortoiseMode' => isset($input['tortoiseMode']) ? $input['tortoiseMode'] : 'non défini',
        'slowMode' => isset($input['slowMode']) ? $input['slowMode'] : 'non défini',
        'delaySeconds' => isset($input['delaySeconds']) ? $input['delaySeconds'] : 'non défini'
    ];
    error_log("Paramètres reçus dans process.php: " . json_encode($receivedParams));

    // Récupérer le lot à traiter
    $batch = $input['batch'];
    $currentIndex = isset($input['currentIndex']) ? (int)$input['currentIndex'] : 0;
    $totalItems = isset($input['totalItems']) ? (int)$input['totalItems'] : count($batch);
    $slowMode = isset($input['slowMode']) ? (bool)$input['slowMode'] : false;
    $tortoiseMode = isset($input['tortoiseMode']) ? (bool)$input['tortoiseMode'] : false;
    $delaySeconds = isset($input['delaySeconds']) ? (int)$input['delaySeconds'] : 30;

    error_log("Paramètres après conversion: slowMode=" . ($slowMode ? 'true' : 'false') . 
    ", tortoiseMode=" . ($tortoiseMode ? 'true' : 'false') . 
    ", delaySeconds=" . $delaySeconds);

    // Ajuster le délai entre les requêtes selon le mode et la valeur personnalisée
    if ($tortoiseMode) {
        $delayMs = $delaySeconds * 1000; // Convertir en millisecondes (délai tortue - 60-300 secondes)
        error_log("Utilisation du mode tortue avec délai: " . $delayMs . "ms");
    } else if ($slowMode) {
        $delayMs = $delaySeconds * 1000; // Convertir en millisecondes (délai lent - 10-60 secondes)
        error_log("Utilisation du mode lent avec délai: " . $delayMs . "ms");
    } else {
        $delayMs = $config['delay_between_requests']; // Délai normal (3000ms par défaut)
        error_log("Utilisation du mode normal avec délai: " . $delayMs . "ms");
    }

    // Résultats du traitement
    $results = [];

    // Traiter chaque URL du lot
    foreach ($batch as $index => $url) {
        // Extraire les informations de l'URL
        $urlParts = parse_url($url);
        
        // Vérifier que l'URL est valide
        if (!$urlParts || !isset($urlParts['host']) || !isset($urlParts['path'])) {
            $results[] = [
                'status' => 'error',
                'message' => "URL invalide: $url",
                'error_type' => 'invalid_url'
            ];
            continue;
        }
        
        // Ajouter un log pour déboguer
        error_log("Recherche de l'URL: " . $url . " sur l'instance: " . $misskey_instance);
        
        // Rechercher la note sur Misskey à partir de l'URL
        $searchResult = search_federated_note($misskey_instance, $url, $token);
        
        // Vérifier si la recherche a réussi ET si les données contiennent un ID valide
        if ($searchResult['success'] && isset($searchResult['data']) && !empty($searchResult['data'])) {
            // Vérifier et extraire l'ID de manière sécurisée
            if (isset($searchResult['data']['id']) && !empty($searchResult['data']['id'])) {
                $noteId = $searchResult['data']['id'];
                
                // Vérifier d'abord si la note est déjà favorite pour économiser une requête API
                $favoriteCheckResult = check_if_favorited($misskey_instance, $noteId, $token);
                
                if ($favoriteCheckResult['success'] && $favoriteCheckResult['is_favorited']) {
                    // La note est déjà dans les favoris
                    $results[] = [
                        'status' => 'info',
                        'message' => "Déjà dans vos favoris: $url",
                        'error_type' => 'already_favorited'
                    ];
                } else {
                    // La note n'est pas encore dans les favoris ou la vérification a échoué
                    // Dans le cas d'échec, nous essayons quand même d'ajouter la note
                    $favoriteResult = add_to_favorites($misskey_instance, $noteId, $token);
                    
                    if ($favoriteResult['success']) {
                        $results[] = [
                            'status' => 'success',
                            'message' => "Ajouté aux favoris: $url"
                        ];
                    } else {
                        // Vérifier si c'est une erreur de "déjà ajouté aux favoris"
                        $errorMessage = isset($favoriteResult['data']['error']['message']) 
                            ? $favoriteResult['data']['error']['message'] 
                            : (isset($favoriteResult['message']) ? $favoriteResult['message'] : 'Erreur inconnue');
                        
                        // Extraire le code d'erreur si disponible
                        $errorCode = isset($favoriteResult['data']['error']['code']) 
                            ? $favoriteResult['data']['error']['code'] 
                            : '';
                        
                        // Déterminer le type d'erreur
                        $errorType = 'api_error';
                        if (strpos($errorMessage, 'already') !== false) {
                            $errorType = 'already_favorited';
                        } elseif (strpos($errorMessage, 'rate limit') !== false || strpos($errorMessage, 'limit exceeded') !== false || $errorCode == 'RATE_LIMIT_EXCEEDED') {
                            $errorType = 'rate_limit';
                        } elseif (strpos($errorMessage, 'permission') !== false || $errorCode == 'NO_PERMISSION') {
                            $errorType = 'permission_denied';
                        }
                        
                        if ($errorType === 'already_favorited') {
                            $results[] = [
                                'status' => 'info',
                                'message' => "Déjà dans vos favoris: $url",
                                'error_type' => $errorType
                            ];
                        } else if ($errorType === 'rate_limit') {
                            $message = "Limite d'API atteinte pour: $url. ";
                            if ($tortoiseMode) {
                                $message .= "Essayez d'augmenter le délai ou attendez quelques minutes.";
                            } else if ($slowMode) {
                                $message .= "Activez le mode tortue.";
                            } else {
                                $message .= "Activez le mode ultra-lent ou le mode tortue.";
                            }
                            
                            $results[] = [
                                'status' => 'warning',
                                'message' => $message,
                                'error_type' => $errorType,
                                'details' => $errorMessage
                            ];
                        } else {
                            $results[] = [
                                'status' => 'error',
                                'message' => "Erreur lors de l'ajout aux favoris: $errorMessage",
                                'error_type' => $errorType,
                                'details' => $errorCode ? "Code: $errorCode" : ""
                            ];
                        }
                    }
                }
            } else {
                // L'ID est manquant ou vide dans la réponse
                $dataKeys = is_array($searchResult['data']) ? array_keys($searchResult['data']) : ['non_array'];
                $results[] = [
                    'status' => 'error',
                    'message' => "Note trouvée mais sans ID valide: $url",
                    'error_type' => 'invalid_response',
                    'details' => "Clés disponibles: " . implode(', ', $dataKeys)
                ];
                
                // Log pour déboguer
                error_log("Structure de données reçue: " . json_encode($searchResult['data']));
            }
        } else {
            // Note non trouvée ou erreur de recherche
            $errorMessage = isset($searchResult['message']) ? $searchResult['message'] : "Publication introuvable";
            $errorCode = isset($searchResult['error_code']) ? $searchResult['error_code'] : '';
            $httpCode = isset($searchResult['http_code']) ? $searchResult['http_code'] : '';
            
            // Déterminer le type d'erreur
            $errorType = 'not_found';
            if (strpos($errorMessage, 'rate limit') !== false || $httpCode == 429 || 
                (isset($searchResult['data']['error']) && 
                 (isset($searchResult['data']['error']['code']) && $searchResult['data']['error']['code'] == 'RATE_LIMIT_EXCEEDED'))) {
                $errorType = 'rate_limit';
                if ($tortoiseMode) {
                    $errorMessage = "Limite d'API atteinte malgré le mode tortue. Essayez d'augmenter le délai ou attendez quelques minutes.";
                } else if ($slowMode) {
                    $errorMessage = "Limite d'API atteinte. Activez le mode tortue ou attendez quelques minutes.";
                } else {
                    $errorMessage = "Limite d'API atteinte. Activez le mode ultra-lent ou le mode tortue.";
                }
            } elseif ($httpCode >= 500) {
                $errorType = 'server_error';
                $errorMessage = "L'instance Misskey rencontre des problèmes. Statut HTTP: $httpCode";
            } elseif ($httpCode == 401 || $httpCode == 403) {
                $errorType = 'auth_error';
                $errorMessage = "Problème d'authentification ou de permission. Vérifiez votre token.";
            } elseif ($httpCode == 0) {
                $errorType = 'network_error';
                $errorMessage = "Problème de connexion réseau. Vérifiez votre connectivité.";
            }
            
            $results[] = [
                'status' => $errorType == 'rate_limit' ? 'warning' : 'error',
                'message' => "Publication non trouvée sur le réseau fédéré: $url ($errorMessage)",
                'error_type' => $errorType,
                'details' => $httpCode ? "HTTP: $httpCode" : ""
            ];
            
            // Ajouter des infos de debug
            if (isset($searchResult['data']) && is_array($searchResult['data'])) {
                error_log("Données reçues pour URL $url: " . json_encode($searchResult['data']));
            }
        }
        
        // Pause pour éviter le rate limiting - utilise le délai approprié selon le mode
        usleep($delayMs * 1000);
    }

    // Si au moins une erreur de rate limit a été détectée, suggérer le mode approprié
    $hasRateLimitErrors = false;
    foreach ($results as $result) {
        if (isset($result['error_type']) && $result['error_type'] === 'rate_limit') {
            $hasRateLimitErrors = true;
            break;
        }
    }

    // Déterminer les suggestions à faire à l'utilisateur
    $suggestions = [
        'use_slow_mode' => $hasRateLimitErrors && !$slowMode && !$tortoiseMode,
        'use_tortoise_mode' => $hasRateLimitErrors && $slowMode && !$tortoiseMode,
        'increase_delay' => $hasRateLimitErrors && ($slowMode || $tortoiseMode) && $delaySeconds < ($tortoiseMode ? 300 : 60)
    ];

    // Renvoyer les résultats
    echo json_encode([
        'success' => true,
        'results' => $results,
        'progress' => [
            'current' => $currentIndex + count($batch),
            'total' => $totalItems,
            'percentage' => round((($currentIndex + count($batch)) / $totalItems) * 100, 2)
        ],
        'suggestions' => $suggestions,
        'config' => [
            'slow_mode' => $slowMode,
            'tortoise_mode' => $tortoiseMode,
            'delay_seconds' => $delaySeconds
        ]
    ]);

} catch (Exception $e) {
    // Capturer toutes les exceptions et renvoyer un message d'erreur formaté en JSON
    echo json_encode([
        'success' => false,
        'message' => 'Exception: ' . $e->getMessage(),
        'file' => $e->getFile(),
        'line' => $e->getLine()
    ]);
}