import { createStore } from 'vuex';
import dialogs from './modules/dialogs';
import loadMenu from '../utils/menuLoader.js';
import router from '../router';
import apiClient from '../utils/axios.js';
import { io } from 'socket.io-client';

const store = createStore({
  state: {
    isLoggedIn: localStorage.getItem('isLoggedIn') === 'true',
    user: JSON.parse(localStorage.getItem('user')) || null,
    language: navigator.language.startsWith('de') ? 'de' : 'en',
    menu: JSON.parse(localStorage.getItem('menu')) || [],
    socket: null,
    daemonSocket: null,
    menuNeedsUpdate: false,
  },
  mutations: {
    async dologin(state, user) {
      state.isLoggedIn = true;
      state.user = user;
      localStorage.setItem('isLoggedIn', 'true');
      localStorage.setItem('user', JSON.stringify(user));
      state.menuNeedsUpdate = true;
      if (user.param.filter(param => ['birthdate', 'gender'].includes(param.name)).length < 2) {
        router.push({ path: '/settings/personal' });
      }
    },
    async dologout(state) {
      state.isLoggedIn = false;
      state.user = null;
      localStorage.removeItem('isLoggedIn');
      localStorage.removeItem('user');
      localStorage.removeItem('menu');
      state.menuNeedsUpdate = false;
    },
    setLanguage(state, language) {
      state.language = language;
    },
    setMenu(state, menu) {
      state.menu = menu;
      localStorage.setItem('menu', JSON.stringify(menu));
      state.menuNeedsUpdate = false;
    },
    setSocket(state, socket) {
      state.socket = socket;
    },
    clearSocket(state) {
      if (state.socket) {
        state.socket.disconnect();
      }
      state.socket = null;
    },
    setDaemonSocket(state, daemonSocket) {
      state.daemonSocket = daemonSocket;
    },
    clearDaemonSocket(state) {
      if (state.daemonSocket) {
        state.daemonSocket.close();
      }
      state.daemonSocket = null;
    },
  },
  actions: {
    async login({ commit, dispatch }, user) {
      await commit('dologin', user);
      await dispatch('initializeSocket');
      await dispatch('initializeDaemonSocket');
      const socket = this.getters.socket;
      if (socket) {
        socket.emit('setUserId', user.id);
      }
      await dispatch('loadMenu');
    },
    logout({ commit }) {
      commit('clearSocket');
      commit('clearDaemonSocket');
      commit('dologout');
      router.push('/');
    },
    initializeSocket({ commit, state }) {
      if (state.isLoggedIn && state.user) {
        let currentSocket = state.socket;
        const connectSocket = () => {
          if (currentSocket) {
            currentSocket.disconnect();
          }
          console.log('🔌 Initializing Socket.io connection to:', import.meta.env.VITE_API_BASE_URL);
          const socket = io(import.meta.env.VITE_API_BASE_URL, {
            secure: true,
            transports: ['websocket', 'polling']
          });
    
                    socket.on('connect', () => {
            console.log('✅ Socket.io connected successfully');
            socket.emit('setUserId', state.user.id); // Sende user.id, wenn user vorhanden ist
          });

          socket.on('disconnect', (reason) => {
            console.warn('❌ Socket.io disconnected:', reason);
            retryConnection(connectSocket);
          });

          socket.on('connect_error', (error) => {
            console.error('❌ Socket.io connection error:', error);
            console.error('❌ URL attempted:', import.meta.env.VITE_API_BASE_URL);
          });
    
          commit('setSocket', socket);
        };
    
        const retryConnection = (reconnectFn) => {
          setTimeout(() => {
            console.log('Retrying Socket.io connection...');
            reconnectFn();
          }, 1000); // Retry every second
        };
    
        connectSocket();
      } else {
        console.log("User is not logged in or user data is not available.");
      }
    },
    initializeDaemonSocket({ commit, state }) {
      if (state.isLoggedIn && state.user) {
        let currentDaemonSocket = state.daemonSocket;
        const connectDaemonSocket = () => {
          if (currentDaemonSocket) {
            currentDaemonSocket.disconnect();
          }
          const daemonUrl = import.meta.env.VITE_DAEMON_SOCKET || 'wss://www.your-part.de:4551';
          console.log('🔌 Initializing Daemon WebSocket connection to:', daemonUrl);
          try {
            const daemonSocket = new WebSocket(daemonUrl, 'yourpart-protocol');

            daemonSocket.onopen = () => {
              console.log('✅ Daemon WebSocket connected successfully');
              const payload = JSON.stringify({
                user_id: state.user.id,
                event: 'setUserId',
                data: { userId: state.user.id }
              });
              daemonSocket.send(payload);
            };

            daemonSocket.onclose = (event) => {
              console.warn('❌ Daemon WebSocket disconnected:', event.reason);
              retryConnection(connectDaemonSocket);
            };

            daemonSocket.onerror = (error) => {
              console.error('❌ Daemon WebSocket error:', error);
              retryConnection(connectDaemonSocket);
            };

            daemonSocket.addEventListener('message', (event) => {
              const message = event.data;
              if (message === "ping") {
                daemonSocket.send("pong");
              } else {
                try {
                  const data = JSON.parse(message);
                } catch (error) {
                  console.error("Error parsing message:", error);
                }
              }
            });

            commit('setDaemonSocket', daemonSocket);
          } catch (error) {
            console.error('❌ Failed to create Daemon WebSocket:', error);
            console.error('❌ URL attempted:', import.meta.env.VITE_DAEMON_SOCKET);
            retryConnection(connectDaemonSocket);
          }
        };

        const retryConnection = (reconnectFn) => {
          setTimeout(() => {
            reconnectFn();
          }, 1000);
        };
        connectDaemonSocket();
      }
    },
    setLanguage({ commit }, language) {
      commit('setLanguage', language);
    },
    async loadMenu({ commit }) {
      try {
        const menu = await loadMenu();
        commit('setMenu', menu);
      } catch (err) {
        console.error(err);
        commit('setMenu', []);
      }
    },
  },
  getters: {
    isLoggedIn: state => state.isLoggedIn,
    user: state => state.user,
    language: state => state.language,
    menu: state => state.menu,
    socket: state => state.socket,
    daemonSocket: state => state.daemonSocket,
    menuNeedsUpdate: state => state.menuNeedsUpdate,
  },
  modules: {
    dialogs,
  },
});

if (store.state.isLoggedIn && store.state.user) {
  store.dispatch('initializeSocket');
  store.dispatch('initializeDaemonSocket');
}

export default store;
