import axios from 'axios';
import Member from '../models/Member.js';
import MemberTransferConfig from '../models/MemberTransferConfig.js';
import { checkAccess, getUserByToken } from '../utils/userUtils.js';
import { encryptData, decryptData } from '../utils/encrypt.js';
import { devLog, infoLog, errorLog } from '../utils/logger.js';

class MemberTransferService {
    /**
     * Überträgt nur aktive Mitglieder mit testMembership = false an einen externen Endpoint
     * 
     * @param {string} userToken - User Token für Authentifizierung
     * @param {number} clubId - Club ID
     * @param {Object} config - Übertragungskonfiguration
     * @param {string} config.loginEndpoint - Login-Endpoint URL
     * @param {string} config.loginFormat - Format für Login (json, form-data, x-www-form-urlencoded)
     * @param {Object} config.loginCredentials - Login-Daten (z.B. { username: '...', password: '...' })
     * @param {string} config.transferEndpoint - Übertragungs-Endpoint URL
     * @param {string} config.transferMethod - HTTP-Methode (POST, PUT, GET)
     * @param {string} config.transferFormat - Format für Übertragung (json, xml, form-data, x-www-form-urlencoded)
     * @param {string} config.transferTemplate - Template mit Platzhaltern (z.B. '{"name": "{{firstName}} {{lastName}}", "email": "{{email}}"}')
     * @param {boolean} config.useBulkMode - Wenn true, werden alle Mitglieder in einem Bulk-Request übertragen (als {members: [...]})
     * @returns {Promise<Object>} Ergebnis der Übertragung
     */
    async transferMembers(userToken, clubId, config) {
        try {
            await checkAccess(userToken, clubId);

            // 1. Alle Mitglieder (ohne Test-Mitglieder) laden.
            // Die aktive Selektion erfolgt explizit in der Validierung, damit
            // ausgeschlossene inaktive Mitglieder transparent gemeldet werden.
            const members = await Member.findAll({
                where: {
                    clubId: clubId,
                    testMembership: false
                }
            });

            if (members.length === 0) {
                return {
                    status: 200,
                    response: {
                        success: true,
                        message: 'Keine Mitglieder zum Übertragen gefunden',
                        transferred: 0,
                        errors: []
                    }
                };
            }

            // 2. Mitglieder validieren und filtern
            const validMembers = [];
            const invalidMembers = [];
            
            for (const member of members) {
                const validationErrors = [];

                if (!member.active) {
                    validationErrors.push('Mitglied ist inaktiv');
                }
                
                // Pflichtfelder prüfen
                if (!member.firstName || member.firstName.trim() === '') {
                    validationErrors.push('Vorname ist erforderlich');
                }
                
                if (!member.lastName || member.lastName.trim() === '') {
                    validationErrors.push('Nachname ist erforderlich');
                }
                
                // Geburtsdatum prüfen (wird als geburtsdatum im Template verwendet)
                const birthDate = this.formatBirthDate(member.birthDate);
                if (!birthDate || birthDate.trim() === '') {
                    validationErrors.push('Geburtsdatum ist erforderlich');
                }
                
                if (validationErrors.length > 0) {
                    invalidMembers.push({
                        member: {
                            id: member.id,
                            firstName: member.firstName || '',
                            lastName: member.lastName || ''
                        },
                        errors: validationErrors
                    });
                } else {
                    validMembers.push(member);
                }
            }
            
            // Wenn keine gültigen Mitglieder vorhanden sind
            if (validMembers.length === 0) {
                const errorMessages = invalidMembers.map(inv => {
                    const name = `${inv.member.firstName} ${inv.member.lastName}`.trim() || `ID: ${inv.member.id}`;
                    return `${name}: ${inv.errors.join(', ')}`;
                }).join('\n');
                
                return {
                    status: 400,
                    response: {
                        success: false,
                        message: 'Keine gültigen Mitglieder zum Übertragen gefunden',
                        error: `Alle ${members.length} Mitglieder haben fehlende Pflichtfelder:\n${errorMessages}`,
                        transferred: 0,
                        total: members.length,
                        invalidMembers: invalidMembers,
                        errors: []
                    }
                };
            }
            
            // Logge gefilterte Mitglieder
            if (invalidMembers.length > 0) {
                infoLog(`[transferMembers] ${invalidMembers.length} Mitglieder wurden aufgrund fehlender Pflichtfelder ausgeschlossen`);
                invalidMembers.forEach(inv => {
                    const name = `${inv.member.firstName} ${inv.member.lastName}`.trim() || `ID: ${inv.member.id}`;
                    infoLog(`[transferMembers] Ausgeschlossen: ${name} - ${inv.errors.join(', ')}`);
                });
            }

            // 3. Login durchführen
            let authToken = null;
            let sessionCookie = null;

            // Server und Endpoints: Wenn vollständige URLs übergeben wurden, behalten wir sie
            // Ansonsten kombinieren wir Server + relativen Pfad aus gespeicherter Konfiguration
            let loginEndpointUrl = config.loginEndpoint;
            let transferEndpointUrl = config.transferEndpoint;
            let loginCredentials = config.loginCredentials;
            let savedConfig = null;
            
            // Wenn relative Pfade verwendet werden, Server aus gespeicherter Konfiguration holen
            if ((config.loginEndpoint && !config.loginEndpoint.startsWith('http')) || 
                (config.transferEndpoint && !config.transferEndpoint.startsWith('http')) ||
                config.useBulkMode) {
                savedConfig = await MemberTransferConfig.findOne({
                    where: { clubId }
                });
            }
            
            if (config.loginEndpoint && !config.loginEndpoint.startsWith('http') && savedConfig) {
                if (savedConfig.server) {
                    // Server + relativen Pfad kombinieren
                    loginEndpointUrl = savedConfig.server.replace(/\/$/, '') + '/' + config.loginEndpoint.replace(/^\//, '');
                    
                    // Login-Credentials aus gespeicherter Konfiguration laden, falls vorhanden
                    // WICHTIG: Nur wenn keine Credentials übergeben wurden ODER wenn übergebene Credentials leer sind
                    if (!loginCredentials || Object.keys(loginCredentials).length === 0) {
                        // Endpoint-Vergleich: Normalisiere beide für Vergleich (entferne führende/schließende Slashes)
                        const normalizedConfigEndpoint = config.loginEndpoint.replace(/^\/|\/$/g, '');
                        const normalizedSavedEndpoint = savedConfig.loginEndpoint?.replace(/^\/|\/$/g, '') || '';
                        
                        if (normalizedSavedEndpoint === normalizedConfigEndpoint || !savedConfig.loginEndpoint) {
                            const savedCredentials = savedConfig.getLoginCredentials();
                            if (savedCredentials && Object.keys(savedCredentials).length > 0) {
                                infoLog('[transferMembers] Verwende gespeicherte Login-Credentials');
                                loginCredentials = savedCredentials;
                            }
                        }
                    }
                }
            }
            
            // Auch wenn vollständige URLs verwendet werden, gespeicherte Credentials verwenden falls keine übergeben
            if (config.loginEndpoint && config.loginEndpoint.startsWith('http')) {
                if (!loginCredentials || Object.keys(loginCredentials).length === 0) {
                    // Versuche gespeicherte Konfiguration zu finden (falls noch nicht geladen)
                    if (!savedConfig) {
                        savedConfig = await MemberTransferConfig.findOne({
                            where: { clubId }
                        });
                    }
                    if (savedConfig) {
                        // Versuche Endpoint zu vergleichen (normalisiert)
                        const normalizedConfigEndpoint = config.loginEndpoint.replace(/\/$/, '').toLowerCase();
                        const savedEndpointFull = savedConfig.loginEndpoint 
                            ? (savedConfig.server?.replace(/\/$/, '') + '/' + savedConfig.loginEndpoint.replace(/^\//, '')).replace(/\/$/, '').toLowerCase()
                            : null;
                        
                        // Wenn Endpoints übereinstimmen ODER wenn kein Endpoint in gespeicherter Config
                        if (savedEndpointFull === normalizedConfigEndpoint || !savedConfig.loginEndpoint) {
                            const savedCredentials = savedConfig.getLoginCredentials();
                            if (savedCredentials && Object.keys(savedCredentials).length > 0) {
                                infoLog('[transferMembers] Verwende gespeicherte Login-Credentials (vollständige URL)');
                                loginCredentials = savedCredentials;
                            }
                        }
                    }
                }
            }
            
            // Fallback: Wenn immer noch keine Credentials, versuche aus gespeicherter Config zu laden
            if (config.loginEndpoint && (!loginCredentials || Object.keys(loginCredentials).length === 0)) {
                if (!savedConfig) {
                    savedConfig = await MemberTransferConfig.findOne({
                        where: { clubId }
                    });
                }
                if (savedConfig) {
                    const savedCredentials = savedConfig.getLoginCredentials();
                    if (savedCredentials && Object.keys(savedCredentials).length > 0) {
                        infoLog('[transferMembers] Fallback: Verwende gespeicherte Login-Credentials');
                        loginCredentials = savedCredentials;
                    }
                }
            }
            
            if (config.transferEndpoint && !config.transferEndpoint.startsWith('http')) {
                // Versuche gespeicherte Konfiguration zu finden (falls noch nicht geladen)
                if (!savedConfig) {
                    savedConfig = await MemberTransferConfig.findOne({
                        where: { clubId }
                    });
                }
                if (savedConfig && savedConfig.server) {
                    // Server + relativen Pfad kombinieren
                    transferEndpointUrl = savedConfig.server.replace(/\/$/, '') + '/' + config.transferEndpoint.replace(/^\//, '');
                }
            }
            
            // Bulk-Wrapper-Template aus gespeicherter Konfiguration laden, falls nicht übergeben
            if (!config.bulkWrapperTemplate && config.useBulkMode && savedConfig) {
                config.bulkWrapperTemplate = savedConfig.bulkWrapperTemplate;
            }

            // Prüfe ob Login-Credentials vorhanden sind und nicht leer
            // Filtere leere Strings/Leerzeichen heraus
            if (loginCredentials && Object.keys(loginCredentials).length > 0) {
                // Prüfe ob alle Werte nicht-leer sind (nach Trimmen)
                const hasValidCredentials = Object.values(loginCredentials).some(
                    value => value && typeof value === 'string' && value.trim().length > 0
                );
                
                if (!hasValidCredentials) {
                    infoLog('[transferMembers] Login-Credentials enthalten nur leere Werte');
                    loginCredentials = null;
                }
            }
            
                    // Debug-Logging für Login-Credentials (auch in Prod)
            if (loginEndpointUrl) {
                if (loginCredentials && Object.keys(loginCredentials).length > 0) {
                    infoLog('[transferMembers] Login-Credentials gefunden:', Object.keys(loginCredentials));
                    // Logge nur die Keys, nicht die Werte (Sicherheit)
                    infoLog('[transferMembers] Login-Endpoint:', loginEndpointUrl);
                    infoLog('[transferMembers] Login-Format:', config.loginFormat || 'json');
                    
                    // Mapping: Wenn "username" vorhanden ist, aber kein "email", verwende "username" als "email"
                    // Viele APIs erwarten "email" statt "username"
                    if (loginCredentials.username && !loginCredentials.email) {
                        infoLog('[transferMembers] Mappe "username" zu "email" für Login');
                        loginCredentials.email = loginCredentials.username;
                        // Entferne username, falls email erwartet wird
                        // delete loginCredentials.username; // Auskommentiert, falls beide benötigt werden
                    }
                } else {
                    infoLog('[transferMembers] WARNUNG: Keine Login-Credentials gefunden!');
                    infoLog('[transferMembers] loginEndpointUrl:', loginEndpointUrl);
                    infoLog('[transferMembers] config.loginEndpoint:', config.loginEndpoint);
                    infoLog('[transferMembers] savedConfig vorhanden:', !!savedConfig);
                    if (savedConfig) {
                        const savedCreds = savedConfig.getLoginCredentials();
                        infoLog('[transferMembers] Gespeicherte Credentials vorhanden:', !!savedCreds && Object.keys(savedCreds).length > 0);
                        if (savedCreds) {
                            infoLog('[transferMembers] Gespeicherte Credential-Keys:', Object.keys(savedCreds));
                        }
                    }
                }
            }
            
            if (loginEndpointUrl && loginCredentials && Object.keys(loginCredentials).length > 0) {
                try {
                    const loginResult = await this.performLogin(
                        loginEndpointUrl,
                        config.loginFormat || 'json',
                        loginCredentials
                    );

                    if (!loginResult.success) {
                        // WICHTIG: Verwende 400 statt 401, damit der Benutzer nicht ausgeloggt wird
                        // 401 wird vom Frontend als "nicht autorisiert" interpretiert und führt zu automatischem Logout
                        return {
                            status: 400,
                            response: {
                                success: false,
                                message: 'Login am externen System fehlgeschlagen',
                                error: loginResult.error,
                                transferred: 0,
                                errors: []
                            }
                        };
                    }

                    authToken = loginResult.token;
                    sessionCookie = loginResult.cookie;
                } catch (loginError) {
                    errorLog('[transferMembers] Login error:', loginError);
                    // WICHTIG: Verwende 400 statt 401, damit der Benutzer nicht ausgeloggt wird
                    return {
                        status: 400,
                        response: {
                            success: false,
                            message: 'Login am externen System fehlgeschlagen: ' + loginError.message,
                            transferred: 0,
                            errors: []
                        }
                    };
                }
            }

            // 3. Mitglieder übertragen
            const useBulkMode = config.useBulkMode === true;
            
            if (useBulkMode) {
                // Bulk-Import: Alle Mitglieder auf einmal übertragen
                try {
                    const membersArray = [];
                    const memberErrors = [];
                    
                    for (const member of validMembers) {
                        try {
                            const memberData = this.replacePlaceholders(
                                config.transferTemplate,
                                member
                            );
                            
                            // Debug-Logging: Erste 3 Mitglieder vollständig loggen (auch in Prod)
                            if (membersArray.length < 3) {
                                infoLog(`[transferMembers] Mitglied ${membersArray.length + 1} (${member.firstName} ${member.lastName}):`, JSON.stringify(memberData, null, 2));
                            }
                            
                            membersArray.push(memberData);
                        } catch (error) {
                            infoLog(`[transferMembers] Error processing ${member.firstName} ${member.lastName}:`, error);
                            memberErrors.push({
                                member: `${member.firstName} ${member.lastName}`,
                                error: error.message
                            });
                        }
                    }
                    
                    infoLog(`[transferMembers] Anzahl zu übertragender Mitglieder: ${membersArray.length}`);
                    
                    // Bulk-Objekt erstellen
                    let bulkData;
                    
                    // Wenn ein Wrapper-Template vorhanden ist, verwende es
                    if (config.bulkWrapperTemplate) {
                        // Wrapper-Template verwenden, {{members}} wird durch das Array ersetzt
                        const wrapperTemplate = config.bulkWrapperTemplate;
                        const membersArrayString = JSON.stringify(membersArray);
                        
                        // Ersetze {{members}} Platzhalter im Wrapper-Template
                        // Der Platzhalter kann in zwei Formen vorkommen:
                        // 1. "{{members}}" (als JSON-String mit Anführungszeichen)
                        // 2. [{{members}}] (als Array-Platzhalter ohne Anführungszeichen)
                        let wrapperString = wrapperTemplate;
                        
                        // Ersetze zuerst "{{members}}" (String-Platzhalter in Anführungszeichen)
                        // durch das Array als JSON-String (ohne die äußeren Anführungszeichen)
                        wrapperString = wrapperString.replace(/"\{\{members\}\}"/g, membersArrayString);
                        
                        // Ersetze auch [{{members}}] (Array-Platzhalter)
                        wrapperString = wrapperString.replace(/\[\{\{members\}\}\]/g, membersArrayString);
                        
                        // Ersetze auch {{members}} ohne Anführungszeichen (falls direkt verwendet)
                        wrapperString = wrapperString.replace(/\{\{members\}\}/g, membersArrayString);
                        
                        // Parse zu Objekt
                        try {
                            bulkData = JSON.parse(wrapperString);
                        } catch (parseError) {
                            infoLog('[transferMembers] Error parsing wrapper template after replacement:', parseError);
                            infoLog('[transferMembers] Wrapper template:', wrapperTemplate);
                            infoLog('[transferMembers] After replacement:', wrapperString);
                            // Fallback: Standard-Format
                            bulkData = {
                                members: membersArray
                            };
                        }
                    } else {
                        // Standard: {"members": [...]}
                        bulkData = {
                            members: membersArray
                        };
                    }
                    
                    // Debug-Logging: Was wird übertragen? (auch in Prod)
                    infoLog('[transferMembers] Bulk-Daten werden übertragen:');
                    infoLog('[transferMembers] Endpoint:', transferEndpointUrl);
                    infoLog('[transferMembers] Methode:', config.transferMethod || 'POST');
                    infoLog('[transferMembers] Format:', config.transferFormat || 'json');
                    infoLog('[transferMembers] Anzahl Mitglieder im Bulk:', membersArray.length);
                    
                    // Logge die ersten 2 Mitglieder vollständig für Debugging
                    if (membersArray.length > 0) {
                        infoLog('[transferMembers] Erstes Mitglied (Beispiel):', JSON.stringify(membersArray[0], null, 2));
                        if (membersArray.length > 1) {
                            infoLog('[transferMembers] Zweites Mitglied (Beispiel):', JSON.stringify(membersArray[1], null, 2));
                        }
                    }
                    
                    // Logge die vollständige Bulk-Struktur (begrenzt auf erste 1000 Zeichen)
                    const bulkDataString = JSON.stringify(bulkData, null, 2);
                    if (bulkDataString.length > 1000) {
                        infoLog('[transferMembers] Bulk-Daten (erste 1000 Zeichen):', bulkDataString.substring(0, 1000) + '...');
                        infoLog('[transferMembers] Bulk-Daten Gesamtlänge:', bulkDataString.length, 'Zeichen');
                    } else {
                        infoLog('[transferMembers] Vollständige Bulk-Daten:', bulkDataString);
                    }
                    
                    const transferResult = await this.transferMember(
                        transferEndpointUrl,
                        config.transferMethod || 'POST',
                        config.transferFormat || 'json',
                        bulkData,
                        authToken,
                        sessionCookie
                    );
                    
                    if (transferResult.success) {
                        const summary = transferResult.data?.summary || {};
                        const transferred = summary.imported || membersArray.length;
                        const bulkErrors = transferResult.data?.results?.errors || [];
                        const bulkDuplicates = transferResult.data?.results?.duplicates || [];
                        
                        let message = `${transferred} von ${validMembers.length} gültigen Mitglieder(n) erfolgreich übertragen.`;
                        if (bulkDuplicates.length > 0) {
                            message += ` ${bulkDuplicates.length} Duplikat(e) gefunden.`;
                        }
                        if (bulkErrors.length > 0 || memberErrors.length > 0) {
                            message += ` ${bulkErrors.length + memberErrors.length} Fehler.`;
                        }
                        
                        // Kombiniere Fehler aus ungültigen Mitgliedern und Übertragungsfehlern
                        const allErrors = [
                            ...invalidMembers.map(inv => ({
                                member: `${inv.member.firstName} ${inv.member.lastName}`.trim() || `ID: ${inv.member.id}`,
                                error: inv.errors.join(', ')
                            })),
                            ...bulkErrors,
                            ...memberErrors
                        ];
                        
                        // Erweitere Nachricht um Informationen über ausgeschlossene Mitglieder
                        let finalMessage = message;
                        if (invalidMembers.length > 0) {
                            finalMessage += ` ${invalidMembers.length} Mitglieder wurden aufgrund fehlender Pflichtfelder ausgeschlossen.`;
                        }
                        
                        return {
                            status: 200,
                            response: {
                                success: true,
                                message: finalMessage,
                                transferred: transferred,
                                total: members.length,
                                validCount: validMembers.length,
                                invalidCount: invalidMembers.length,
                                duplicates: bulkDuplicates.length,
                                invalidMembers: invalidMembers,
                                errors: allErrors,
                                details: transferResult.data
                            }
                        };
                    } else {
                        // Extrahiere detaillierte Fehlerinformationen
                        let errorMessage = transferResult.error || 'Bulk-Übertragung fehlgeschlagen';
                        
                        // Wenn die Fehlermeldung Validierungsfehler enthält, versuche zu identifizieren, welches Mitglied das Problem verursacht
                        if (errorMessage.includes('Zeile') || errorMessage.includes('Validierungsfehler')) {
                            // Versuche die Zeilennummer zu extrahieren
                            const lineMatch = errorMessage.match(/Zeile\s+(\d+)/);
                            if (lineMatch) {
                                const lineNumber = parseInt(lineMatch[1], 10);
                                // Zeile 1 = Index 0 im Array
                                const memberIndex = lineNumber - 1;
                                if (memberIndex >= 0 && memberIndex < membersArray.length) {
                                    const problematicMember = membersArray[memberIndex];
                                    const memberName = `${problematicMember.firstName || ''} ${problematicMember.lastName || ''}`.trim() || 'Unbekanntes Mitglied';
                                    errorMessage = `${errorMessage}\n\nProblematisches Mitglied (Index ${memberIndex + 1}): ${memberName}`;
                                }
                            }
                        }
                        
                        // Kombiniere Fehler aus ungültigen Mitgliedern und Übertragungsfehlern
                        const allErrors = [
                            ...invalidMembers.map(inv => ({
                                member: `${inv.member.firstName} ${inv.member.lastName}`.trim() || `ID: ${inv.member.id}`,
                                error: inv.errors.join(', ')
                            })),
                            ...memberErrors
                        ];
                        
                        return {
                            status: transferResult.status || 500,
                            response: {
                                success: false,
                                message: 'Bulk-Übertragung fehlgeschlagen',
                                error: errorMessage,
                                transferred: 0,
                                total: members.length,
                                invalidMembers: invalidMembers,
                                errors: allErrors
                            }
                        };
                    }
                } catch (error) {
                    errorLog('[transferMembers] Bulk transfer error:', error);
                    return {
                        status: 500,
                        response: {
                            success: false,
                            message: 'Fehler bei der Bulk-Übertragung: ' + error.message,
                            transferred: 0,
                            total: members.length,
                            errors: []
                        }
                    };
                }
            } else {
                // Einzelne Übertragung: Jedes Mitglied einzeln übertragen
                const results = [];
                const errors = [];
                let successCount = 0;

                // Füge Fehler für ungültige Mitglieder hinzu
                for (const inv of invalidMembers) {
                    errors.push({
                        member: `${inv.member.firstName} ${inv.member.lastName}`.trim() || `ID: ${inv.member.id}`,
                        error: inv.errors.join(', ')
                    });
                }

                for (const member of validMembers) {
                    try {
                        const memberData = this.replacePlaceholders(
                            config.transferTemplate,
                            member
                        );

                        const transferResult = await this.transferMember(
                            transferEndpointUrl,
                            config.transferMethod || 'POST',
                            config.transferFormat || 'json',
                            memberData,
                            authToken,
                            sessionCookie
                        );

                        if (transferResult.success) {
                            successCount++;
                            results.push({
                                member: `${member.firstName} ${member.lastName}`,
                                success: true
                            });
                        } else {
                            errors.push({
                                member: `${member.firstName} ${member.lastName}`,
                                error: transferResult.error
                            });
                        }
                    } catch (error) {
                        errorLog(`[transferMembers] Error transferring ${member.firstName} ${member.lastName}:`, error);
                        errors.push({
                            member: `${member.firstName} ${member.lastName}`,
                            error: error.message
                        });
                    }
                }

                let message = `${successCount} von ${validMembers.length} gültigen Mitglieder(n) erfolgreich übertragen.`;
                if (invalidMembers.length > 0) {
                    message += ` ${invalidMembers.length} Mitglieder wurden aufgrund fehlender Pflichtfelder ausgeschlossen.`;
                }
                
                return {
                    status: 200,
                    response: {
                        success: true,
                        message: message,
                        transferred: successCount,
                        total: members.length,
                        validCount: validMembers.length,
                        invalidCount: invalidMembers.length,
                        results: results,
                        invalidMembers: invalidMembers,
                        errors: errors
                    }
                };
            }
        } catch (error) {
            errorLog('[transferMembers] Error:', error);
            return {
                status: 500,
                response: {
                    success: false,
                    message: 'Fehler bei der Übertragung: ' + error.message,
                    transferred: 0,
                    errors: [error.message]
                }
            };
        }
    }

    /**
     * Führt Login am externen Endpoint durch
     */
    async performLogin(endpoint, format, credentials) {
        try {
            // Debug-Logging (auch in Prod)
            infoLog('[performLogin] Endpoint:', endpoint);
            infoLog('[performLogin] Format:', format);
            infoLog('[performLogin] Credential-Keys:', Object.keys(credentials || {}));
            infoLog('[performLogin] Credentials vorhanden:', !!(credentials && Object.keys(credentials).length > 0));
            
            if (!credentials || Object.keys(credentials).length === 0) {
                return {
                    success: false,
                    error: 'Keine Login-Credentials übergeben',
                    statusCode: 400
                };
            }
            
            let requestConfig = {
                url: endpoint,
                method: 'POST',
                timeout: 10000,
                maxRedirects: 5,
                validateStatus: (status) => status >= 200 && status < 400
            };

            // Headers und Daten je nach Format setzen
            if (format === 'json' || format === 'application/json') {
                requestConfig.headers = {
                    'Content-Type': 'application/json'
                };
                requestConfig.data = credentials;
                infoLog('[performLogin] Sende JSON-Daten:', JSON.stringify(credentials, null, 2).replace(/("password"[^,}]*")([^"]*)(")/g, '$1***$3'));
            } else if (format === 'form-data' || format === 'multipart/form-data') {
                const FormData = (await import('form-data')).default;
                const formData = new FormData();
                for (const [key, value] of Object.entries(credentials)) {
                    formData.append(key, value);
                }
                requestConfig.headers = formData.getHeaders();
                requestConfig.data = formData;
            } else if (format === 'x-www-form-urlencoded' || format === 'urlencoded') {
                requestConfig.headers = {
                    'Content-Type': 'application/x-www-form-urlencoded'
                };
                const params = new URLSearchParams();
                for (const [key, value] of Object.entries(credentials)) {
                    params.append(key, value);
                }
                requestConfig.data = params.toString();
            } else {
                // Default: JSON
                requestConfig.headers = {
                    'Content-Type': 'application/json'
                };
                requestConfig.data = credentials;
            }

            const response = await axios(requestConfig);

            // Versuche Token/Cookie aus Response zu extrahieren
            // Typische Felder: token, accessToken, authToken, cookie, session
            const token = response.data?.token || 
                         response.data?.accessToken || 
                         response.data?.authToken ||
                         response.headers['authorization'] ||
                         response.headers['x-auth-token'];

            const cookie = response.headers['set-cookie']?.[0] || 
                          response.data?.cookie || 
                          response.data?.session;

            return {
                success: true,
                token: token,
                cookie: cookie,
                response: response.data
            };
        } catch (error) {
            errorLog('[performLogin] Error:', error);
            
            // Extrahiere detaillierte Fehlerinformationen
            let errorMessage = 'Login fehlgeschlagen';
            let statusCode = error.response?.status;
            
            if (error.response?.data) {
                // Versuche verschiedene Felder für die Fehlermeldung
                errorMessage = error.response.data.message || 
                              error.response.data.error || 
                              error.response.data.errorMessage ||
                              (typeof error.response.data === 'string' ? error.response.data : errorMessage);
            } else if (error.message) {
                errorMessage = error.message;
            }
            
            // Logge den Status-Code für Debugging (auch in Prod)
            if (statusCode) {
                infoLog(`[performLogin] Externer Endpoint Status: ${statusCode}`);
            }
            
            return {
                success: false,
                error: errorMessage,
                statusCode: statusCode
            };
        }
    }

    /**
     * Überträgt ein einzelnes Mitglied
     */
    async transferMember(endpoint, method, format, data, authToken, sessionCookie) {
        try {
            // Debug-Logging (auch in Prod)
            infoLog('[transferMember] Starte Übertragung:');
            infoLog('[transferMember] Endpoint:', endpoint);
            infoLog('[transferMember] Method:', method);
            infoLog('[transferMember] Format:', format);
            infoLog('[transferMember] AuthToken vorhanden:', !!authToken);
            infoLog('[transferMember] SessionCookie vorhanden:', !!sessionCookie);
            
            // Logge Daten-Struktur (ohne vollständige Daten bei großen Objekten)
            if (typeof data === 'object' && data !== null) {
                if (Array.isArray(data)) {
                    infoLog('[transferMember] Daten ist Array mit', data.length, 'Elementen');
                    if (data.length > 0) {
                        infoLog('[transferMember] Erstes Array-Element:', JSON.stringify(data[0], null, 2));
                    }
                } else if (data.members && Array.isArray(data.members)) {
                    infoLog('[transferMember] Daten enthält members-Array mit', data.members.length, 'Elementen');
                    if (data.members.length > 0) {
                        infoLog('[transferMember] Erstes Mitglied im members-Array:', JSON.stringify(data.members[0], null, 2));
                        if (data.members.length > 1) {
                            infoLog('[transferMember] Zweites Mitglied im members-Array:', JSON.stringify(data.members[1], null, 2));
                        }
                    }
                } else {
                    const dataString = JSON.stringify(data, null, 2);
                    if (dataString.length > 500) {
                        infoLog('[transferMember] Daten (erste 500 Zeichen):', dataString.substring(0, 500) + '...');
                    } else {
                        infoLog('[transferMember] Vollständige Daten:', dataString);
                    }
                }
            } else {
                infoLog('[transferMember] Daten-Typ:', typeof data);
                if (typeof data === 'string') {
                    infoLog('[transferMember] Daten-String (erste 500 Zeichen):', data.substring(0, 500));
                }
            }
            
            let requestConfig = {
                url: endpoint,
                method: method.toUpperCase(),
                timeout: 10000,
                maxRedirects: 5
            };

            // Auth-Header setzen falls vorhanden
            if (authToken) {
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Authorization': `Bearer ${authToken}`,
                    'X-Auth-Token': authToken
                };
            }

            // Cookie setzen falls vorhanden
            if (sessionCookie) {
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Cookie': sessionCookie
                };
            }

            // Daten je nach Format setzen
            if (format === 'json' || format === 'application/json') {
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Content-Type': 'application/json'
                };
                requestConfig.data = typeof data === 'string' ? JSON.parse(data) : data;
            } else if (format === 'xml' || format === 'application/xml' || format === 'text/xml') {
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Content-Type': 'application/xml'
                };
                requestConfig.data = data; // XML als String
            } else if (format === 'form-data' || format === 'multipart/form-data') {
                const FormData = (await import('form-data')).default;
                const formData = new FormData();
                
                // Wenn data ein Objekt ist, alle Felder hinzufügen
                if (typeof data === 'object') {
                    for (const [key, value] of Object.entries(data)) {
                        formData.append(key, value);
                    }
                } else {
                    // Wenn data ein String ist, versuche es zu parsen
                    try {
                        const parsed = JSON.parse(data);
                        for (const [key, value] of Object.entries(parsed)) {
                            formData.append(key, value);
                        }
                    } catch {
                        // Fallback: als Text hinzufügen
                        formData.append('data', data);
                    }
                }
                
                requestConfig.headers = {
                    ...formData.getHeaders(),
                    ...requestConfig.headers
                };
                requestConfig.data = formData;
            } else if (format === 'x-www-form-urlencoded' || format === 'urlencoded') {
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Content-Type': 'application/x-www-form-urlencoded'
                };
                
                const params = new URLSearchParams();
                if (typeof data === 'object') {
                    for (const [key, value] of Object.entries(data)) {
                        params.append(key, value);
                    }
                } else {
                    // Versuche JSON zu parsen
                    try {
                        const parsed = JSON.parse(data);
                        for (const [key, value] of Object.entries(parsed)) {
                            params.append(key, value);
                        }
                    } catch {
                        params.append('data', data);
                    }
                }
                
                requestConfig.data = params.toString();
            } else {
                // Default: JSON
                requestConfig.headers = {
                    ...requestConfig.headers,
                    'Content-Type': 'application/json'
                };
                requestConfig.data = typeof data === 'string' ? JSON.parse(data) : data;
            }

            const response = await axios(requestConfig);

            return {
                success: response.status >= 200 && response.status < 300,
                status: response.status,
                data: response.data
            };
        } catch (error) {
            errorLog('[transferMember] Error:', error);
            
            // Extrahiere detaillierte Fehlerinformationen
            let errorMessage = 'Übertragung fehlgeschlagen';
            let statusCode = error.response?.status;
            
            if (error.response?.data) {
                // Versuche verschiedene Felder für die Fehlermeldung
                errorMessage = error.response.data.message || 
                              error.response.data.error || 
                              error.response.data.errorMessage ||
                              (typeof error.response.data === 'string' ? error.response.data : errorMessage);
                
                // Logge die vollständige Fehlerantwort für Debugging
                infoLog('[transferMember] Fehlerantwort vom externen Endpoint:', JSON.stringify(error.response.data, null, 2));
            } else if (error.message) {
                errorMessage = error.message;
            }
            
            // Logge den Status-Code für Debugging
            if (statusCode) {
                infoLog(`[transferMember] Externer Endpoint Status: ${statusCode}`);
            }
            
            return {
                success: false,
                error: errorMessage,
                status: statusCode
            };
        }
    }

    /**
     * Ersetzt Platzhalter im Template mit Mitgliedsdaten
     * Unterstützte Platzhalter: {{firstName}}, {{lastName}}, {{email}}, {{phone}}, 
     * {{street}}, {{city}}, {{birthDate}}, {{ttr}}, {{qttr}}, {{gender}}
     */
    replacePlaceholders(template, member) {
        if (!template) {
            return {};
        }

        // Wenn Template ein JSON-String ist, parsen
        let parsedTemplate;
        try {
            parsedTemplate = JSON.parse(template);
        } catch {
            // Wenn kein JSON, als einfachen String behandeln
            let result = template;
            
            // Alle verfügbaren Platzhalter ersetzen
                const placeholders = {
                    '{{firstName}}': member.firstName || '',
                    '{{lastName}}': member.lastName || '',
                    '{{email}}': member.email || '',
                    '{{phone}}': member.phone || '',
                    '{{street}}': member.street || '',
                    '{{city}}': member.city || '',
                    '{{birthDate}}': this.formatBirthDate(member.birthDate) || '',
                    '{{geburtsdatum}}': this.formatBirthDate(member.birthDate) || '',
                    '{{address}}': `${member.street || ''}, ${member.city || ''}`.trim().replace(/^,\s*|,\s*$/g, ''),
                    '{{ttr}}': member.ttr || '',
                    '{{qttr}}': member.qttr || '',
                    '{{gender}}': member.gender || '',
                    '{{fullName}}': `${member.firstName || ''} ${member.lastName || ''}`.trim(),
                    '{{notes}}': '' // Notizen werden nicht übertragen
                };

            for (const [placeholder, value] of Object.entries(placeholders)) {
                result = result.replace(new RegExp(placeholder.replace(/[{}]/g, '\\$&'), 'g'), value);
            }

            return result;
        }

        // Wenn es ein Objekt ist, rekursiv Platzhalter ersetzen
        const replaceInObject = (obj) => {
            if (typeof obj === 'string') {
                let result = obj;
                const placeholders = {
                    '{{firstName}}': member.firstName || '',
                    '{{lastName}}': member.lastName || '',
                    '{{email}}': member.email || '',
                    '{{phone}}': member.phone || '',
                    '{{street}}': member.street || '',
                    '{{city}}': member.city || '',
                    '{{birthDate}}': this.formatBirthDate(member.birthDate) || '',
                    '{{geburtsdatum}}': this.formatBirthDate(member.birthDate) || '',
                    '{{address}}': `${member.street || ''}, ${member.city || ''}`.trim().replace(/^,\s*|,\s*$/g, ''),
                    '{{ttr}}': member.ttr || '',
                    '{{qttr}}': member.qttr || '',
                    '{{gender}}': member.gender || '',
                    '{{fullName}}': `${member.firstName || ''} ${member.lastName || ''}`.trim(),
                    '{{notes}}': '' // Notizen werden nicht übertragen
                };

                for (const [placeholder, value] of Object.entries(placeholders)) {
                    result = result.replace(new RegExp(placeholder.replace(/[{}]/g, '\\$&'), 'g'), String(value));
                }

                return result;
            } else if (Array.isArray(obj)) {
                return obj.map(item => replaceInObject(item));
            } else if (obj && typeof obj === 'object') {
                const result = {};
                for (const [key, value] of Object.entries(obj)) {
                    result[replaceInObject(key)] = replaceInObject(value);
                }
                return result;
            }
            return obj;
        };

        return replaceInObject(parsedTemplate);
    }

    /**
     * Formatiert Geburtsdatum in YYYY-MM-DD Format
     */
    formatBirthDate(birthDate) {
        if (!birthDate) return '';
        
        // Wenn bereits im richtigen Format
        if (typeof birthDate === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(birthDate)) {
            return birthDate;
        }

        // Erstes Matching auf deutsches Format dd.mm.yyyy
        const dottedMatch = String(birthDate).match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
        if (dottedMatch) {
            const day = dottedMatch[1].padStart(2, '0');
            const month = dottedMatch[2].padStart(2, '0');
            const year = dottedMatch[3];
            return `${year}-${month}-${day}`;
        }
        
        // Versuche zu parsen
        try {
            const date = new Date(birthDate);
            if (!isNaN(date.getTime())) {
                const year = date.getFullYear();
                const month = String(date.getMonth() + 1).padStart(2, '0');
                const day = String(date.getDate()).padStart(2, '0');
                return `${year}-${month}-${day}`;
            }
        } catch (error) {
            // noop
        }
        
        return birthDate || '';
    }
}

export default new MemberTransferService();
