import { io } from 'socket.io-client';
import { backendBaseUrl } from '../apiClient.js';

let socket = null;
let isReloading = false;
let suppressLogs = false;

// Cleanup beim Seitenreload
if (typeof window !== 'undefined') {
  window.addEventListener('beforeunload', () => {
    isReloading = true;
    suppressLogs = true;
    if (socket) {
      // Trenne die Verbindung beim Reload, aber unterdrücke Logs
      socket.removeAllListeners();
      socket.disconnect();
      socket = null;
    }
  });
  
  // Nach dem Reload Logs wieder erlauben (nach kurzer Verzögerung)
  window.addEventListener('load', () => {
    setTimeout(() => {
      isReloading = false;
      suppressLogs = false;
    }, 1000);
  });
}

export const connectSocket = (clubId) => {
  // Beim ersten Connect nach Reload, entferne alte Socket.IO Cookies
  if (typeof document !== 'undefined' && !socket) {
    // Entferne alte Socket.IO Session-Cookies
    document.cookie.split(';').forEach((cookie) => {
      const eqPos = cookie.indexOf('=');
      const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();
      if (name === 'io') {
        document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
      }
    });
  }
  
  // Wenn bereits eine Verbindung existiert, aber nicht verbunden ist, trenne sie
  if (socket && !socket.connected) {
    socket.removeAllListeners();
    socket.disconnect();
    socket = null;
  }
  
  if (socket && socket.connected) {
    // Wenn bereits verbunden, verlasse den alten Club-Raum und trete dem neuen bei
    if (socket.currentClubId && socket.currentClubId !== clubId) {
      socket.emit('leave-club', socket.currentClubId);
      socket.currentClubId = clubId;
      socket.emit('join-club', clubId);
      return socket;
    } else if (socket.currentClubId === clubId) {
      // Bereits im richtigen Club-Raum - keine Aktion nötig
      return socket;
    }
  } else {
    // Neue Verbindung erstellen
    // Socket.IO läuft direkt auf HTTPS-Port 3051 (nicht über Apache-Proxy)
    let socketUrl;
    if (import.meta.env.PROD) {
      // Produktion: HTTPS direkt auf Port 3051
      socketUrl = 'https://tt-tagebuch.de:3051';
    } else {
      // Entwicklung: Socket.IO läuft auf demselben Port wie der HTTP-Server (3005)
      // Oder auf HTTPS-Port 3051, falls SSL-Zertifikate vorhanden sind
      // Versuche zuerst HTTP, dann HTTPS
      socketUrl = backendBaseUrl;
      // Falls der Server auf HTTPS-Port 3051 läuft, verwende diesen
      // (wird automatisch auf HTTP zurückfallen, wenn HTTPS nicht verfügbar ist)
    }
    
    // Bestimme, ob wir HTTPS verwenden
    const isHttps = socketUrl.startsWith('https://');
    
    socket = io(socketUrl, {
      path: '/socket.io/',
      transports: ['polling', 'websocket'], // Polling zuerst für bessere Kompatibilität, dann WebSocket
      reconnection: true,
      reconnectionDelay: 1000,
      reconnectionDelayMax: 5000,
      reconnectionAttempts: Infinity, // Unbegrenzte Versuche
      timeout: 20000,
      upgrade: true, // Erlaube Upgrade von Polling zu WebSocket
      forceNew: false,
      secure: isHttps, // Nur für HTTPS
      rejectUnauthorized: false, // Für selbst-signierte Zertifikate (nur Entwicklung)
      // Verbesserte Cookie-Handling
      withCredentials: true,
      // Auto-Connect
      autoConnect: true,
      // Erzwinge Upgrade-Versuch nach erfolgreicher Polling-Verbindung
      rememberUpgrade: true
    });

    socket.on('connect', () => {
      console.log('✅ Socket.IO verbunden:', socket.id);
      console.log('   Transport:', socket.io.engine.transport.name);
      // Wenn bereits ein Club ausgewählt war, trete dem Raum bei
      if (socket.currentClubId) {
        socket.emit('join-club', socket.currentClubId);
      }
    });

    socket.on('disconnect', (reason) => {
      // Beim Reload oder wenn Logs unterdrückt werden sollen, keine Logs
      if (isReloading || suppressLogs) {
        return;
      }
      
      // "transport error" ist normal beim Reload - unterdrücke diese Logs komplett
      if (reason === 'transport error' || reason === 'ping timeout') {
        return; // Keine Logs für normale Transport-Fehler
      }
      
      // Nur wichtige Disconnects loggen
      if (reason !== 'io client disconnect' && reason !== 'transport close') {
        console.log('❌ Socket.IO getrennt:', reason);
      }
      
      if (reason === 'io server disconnect') {
        // Server hat die Verbindung getrennt, neu verbinden
        socket.connect();
      }
    });

    socket.on('connect_error', (error) => {
      // Beim Reload keine Error-Logs
      if (isReloading || suppressLogs) {
        return;
      }
      
      // "xhr poll error" oder "Session ID unknown" sind normal - unterdrücke diese
      if (error.message && (
        error.message.includes('Session ID unknown') ||
        error.message.includes('xhr poll error') ||
        error.type === 'TransportError'
      )) {
        // Keine Logs für normale Verbindungsfehler
        return;
      }
      
      // Nur unerwartete Fehler loggen
      console.error('❌ Socket.IO Verbindungsfehler:', error.message);
      console.error('   Type:', error.type);
      console.error('   Description:', error.description);
    });

    socket.on('reconnect', (attemptNumber) => {
      // Beim Reload keine Reconnect-Logs
      if (!isReloading && !suppressLogs) {
        console.log('✅ Socket.IO wieder verbunden nach', attemptNumber, 'Versuch(en)');
      }
    });

    socket.on('reconnect_attempt', (attemptNumber) => {
      // Reconnect-Versuche nicht loggen - zu viele Logs
      // if (!isReloading && !suppressLogs) {
      //   console.log('🔄 Socket.IO Verbindungsversuch', attemptNumber);
      // }
    });

    socket.on('reconnect_error', (error) => {
      // Beim Reload keine Error-Logs
      if (!isReloading && !suppressLogs) {
        console.error('❌ Socket.IO Wiederverbindungsfehler:', error.message);
      }
    });

    socket.on('reconnect_failed', () => {
      // Nur kritische Fehler loggen
      if (!isReloading && !suppressLogs) {
        console.error('❌ Socket.IO Wiederverbindung fehlgeschlagen - alle Versuche aufgebraucht');
      }
    });
  }

  // Club-Raum beitreten
  if (clubId) {
    socket.emit('join-club', clubId);
    socket.currentClubId = clubId;
  }

  return socket;
};

export const disconnectSocket = () => {
  if (socket) {
    if (socket.currentClubId) {
      socket.emit('leave-club', socket.currentClubId);
    }
    socket.removeAllListeners();
    socket.disconnect();
    socket = null;
  }
};

export const getSocket = () => {
  return socket;
};

// Event-Listener registrieren
export const onParticipantAdded = (callback) => {
  if (socket) {
    socket.on('participant:added', callback);
  }
};

export const onParticipantRemoved = (callback) => {
  if (socket) {
    socket.on('participant:removed', callback);
  }
};

export const onParticipantUpdated = (callback) => {
  if (socket) {
    socket.on('participant:updated', (data) => {
      callback(data);
    });
  }
};

export const onDiaryNoteAdded = (callback) => {
  if (socket) {
    socket.on('diary:note:added', callback);
  }
};

export const onDiaryNoteUpdated = (callback) => {
  if (socket) {
    socket.on('diary:note:updated', callback);
  }
};

export const onDiaryNoteDeleted = (callback) => {
  if (socket) {
    socket.on('diary:note:deleted', callback);
  }
};

export const onDiaryTagAdded = (callback) => {
  if (socket) {
    socket.on('diary:tag:added', callback);
  }
};

export const onDiaryTagRemoved = (callback) => {
  if (socket) {
    socket.on('diary:tag:removed', callback);
  }
};

export const onDiaryDateUpdated = (callback) => {
  if (socket) {
    socket.on('diary:date:updated', callback);
  }
};

export const onActivityMemberAdded = (callback) => {
  if (socket) {
    socket.on('activity:member:added', (data) => {
      callback(data);
    });
  }
};

export const onActivityMemberRemoved = (callback) => {
  if (socket) {
    socket.on('activity:member:removed', (data) => {
      callback(data);
    });
  }
};

export const onActivityChanged = (callback) => {
  if (socket) {
    socket.on('activity:changed', (data) => {
      callback(data);
    });
  }
};

export const onMemberChanged = (callback) => {
  if (socket) {
    socket.on('member:changed', (data) => {
      callback(data);
    });
  }
};

export const onGroupChanged = (callback) => {
  if (socket) {
    socket.on('group:changed', (data) => {
      callback(data);
    });
  }
};

export const onTournamentChanged = (callback) => {
  if (socket) {
    socket.on('tournament:changed', (data) => {
      callback(data);
    });
  }
};

export const onScheduleMatchUpdated = (callback) => {
  if (socket) {
    socket.on('schedule:match:updated', callback);
  }
};

export const onMatchReportSubmitted = (callback) => {
  if (socket) {
    socket.on('schedule:match-report:submitted', callback);
  }
};

export const onFriendlyInvitationCreated = (callback) => {
  if (socket) {
    socket.on('friendly:invitation:created', callback);
  }
};

export const onFriendlyInvitationAccepted = (callback) => {
  if (socket) {
    socket.on('friendly:invitation:accepted', callback);
  }
};

export const onFriendlyInvitationDeclined = (callback) => {
  if (socket) {
    socket.on('friendly:invitation:declined', callback);
  }
};

export const onFriendlySharedMatchUpdated = (callback) => {
  if (socket) {
    socket.on('friendly:shared:match:updated', callback);
  }
};

export const onFriendlySharedMatchDeleted = (callback) => {
  if (socket) {
    socket.on('friendly:shared:match:deleted', callback);
  }
};

// Event-Listener entfernen
export const offParticipantAdded = (callback) => {
  if (socket) {
    socket.off('participant:added', callback);
  }
};

export const offParticipantRemoved = (callback) => {
  if (socket) {
    socket.off('participant:removed', callback);
  }
};

export const offParticipantUpdated = (callback) => {
  if (socket) {
    socket.off('participant:updated', callback);
  }
};

export const offDiaryNoteAdded = (callback) => {
  if (socket) {
    socket.off('diary:note:added', callback);
  }
};

export const offDiaryNoteUpdated = (callback) => {
  if (socket) {
    socket.off('diary:note:updated', callback);
  }
};

export const offDiaryNoteDeleted = (callback) => {
  if (socket) {
    socket.off('diary:note:deleted', callback);
  }
};

export const offDiaryTagAdded = (callback) => {
  if (socket) {
    socket.off('diary:tag:added', callback);
  }
};

export const offDiaryTagRemoved = (callback) => {
  if (socket) {
    socket.off('diary:tag:removed', callback);
  }
};

export const offDiaryDateUpdated = (callback) => {
  if (socket) {
    socket.off('diary:date:updated', callback);
  }
};

export const offActivityMemberAdded = (callback) => {
  if (socket) {
    socket.off('activity:member:added', callback);
  }
};

export const offActivityMemberRemoved = (callback) => {
  if (socket) {
    socket.off('activity:member:removed', callback);
  }
};

export const offActivityChanged = (callback) => {
  if (socket) {
    socket.off('activity:changed', callback);
  }
};

export const offMemberChanged = (callback) => {
  if (socket) {
    socket.off('member:changed', callback);
  }
};

export const offGroupChanged = (callback) => {
  if (socket) {
    socket.off('group:changed', callback);
  }
};

export const offTournamentChanged = (callback) => {
  if (socket) {
    socket.off('tournament:changed', callback);
  }
};

export const offScheduleMatchUpdated = (callback) => {
  if (socket) {
    socket.off('schedule:match:updated', callback);
  }
};

export const offMatchReportSubmitted = (callback) => {
  if (socket) {
    socket.off('schedule:match-report:submitted', callback);
  }
};

export const offFriendlyInvitationCreated = (callback) => {
  if (socket) {
    socket.off('friendly:invitation:created', callback);
  }
};

export const offFriendlyInvitationAccepted = (callback) => {
  if (socket) {
    socket.off('friendly:invitation:accepted', callback);
  }
};

export const offFriendlyInvitationDeclined = (callback) => {
  if (socket) {
    socket.off('friendly:invitation:declined', callback);
  }
};

export const offFriendlySharedMatchUpdated = (callback) => {
  if (socket) {
    socket.off('friendly:shared:match:updated', callback);
  }
};

export const offFriendlySharedMatchDeleted = (callback) => {
  if (socket) {
    socket.off('friendly:shared:match:deleted', callback);
  }
};

