import { useCallback, useEffect, useRef, useState } from 'react';
import { normalizeAdminSettings } from '../utils/adminSettings';

const TOKEN_STORAGE_KEY = 'pickupConfigToken';

const useSessionManager = ({ normalizeConfigEntries, onUnauthorized, setError, setLoading }) => {
  const [session, setSession] = useState(null);
  const unauthorizedRef = useRef(onUnauthorized || (() => {}));

  useEffect(() => {
    unauthorizedRef.current = onUnauthorized || (() => {});
  }, [onUnauthorized]);

  const handleUnauthorized = useCallback(() => {
    setSession(null);
    try {
      localStorage.removeItem(TOKEN_STORAGE_KEY);
    } catch (storageError) {
      console.warn('Konnte Token nicht aus dem Speicher entfernen:', storageError);
    }
    unauthorizedRef.current();
  }, []);

  const handleUnauthorizedRef = useRef(() => {});
  useEffect(() => {
    handleUnauthorizedRef.current = handleUnauthorized;
  }, [handleUnauthorized]);

  const authorizedFetch = useCallback(
    async (url, options = {}, tokenOverride) => {
      const activeToken = tokenOverride || session?.token;
      if (!activeToken) {
        throw new Error('Keine aktive Session');
      }
      const headers = {
        Authorization: `Bearer ${activeToken}`,
        ...(options.headers || {})
      };
      const response = await fetch(url, { ...options, headers });
      if (response.status === 401) {
        handleUnauthorizedRef.current();
        throw new Error('Nicht autorisiert');
      }
      return response;
    },
    [session?.token]
  );

  const storeToken = useCallback((token) => {
    if (!token) {
      return;
    }
    try {
      localStorage.setItem(TOKEN_STORAGE_KEY, token);
    } catch (storageError) {
      console.warn('Konnte Token nicht speichern:', storageError);
    }
  }, []);

  const getStoredToken = useCallback(() => {
    try {
      return localStorage.getItem(TOKEN_STORAGE_KEY);
    } catch (storageError) {
      console.warn('Konnte gespeicherten Token nicht lesen:', storageError);
      return null;
    }
  }, []);

  const bootstrapSession = useCallback(
    async (token, { progress } = {}) => {
      if (!token) {
        return {};
      }
      setLoading(true);
      setError('');
      progress?.update?.('Session wird aufgebaut...', 20);
      try {
        const response = await fetch('/api/auth/session', {
          headers: { Authorization: `Bearer ${token}` }
        });
        if (response.status === 401) {
          handleUnauthorized();
          return {};
        }
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        const data = await response.json();
        const sessionData = { token, profile: data.profile, isAdmin: data.isAdmin };
        setSession(sessionData);
        progress?.update?.('Betriebe werden geprüft...', 45);
        const stores = Array.isArray(data.stores) ? data.stores : [];
        const adminSettings = data.isAdmin ? normalizeAdminSettings(data.adminSettings) : null;
        const configSource = Array.isArray(data.config) ? data.config : data.config || null;
        let config = normalizeConfigEntries(Array.isArray(configSource) ? configSource : []);
        if (!configSource) {
          const configResponse = await fetch('/api/config', {
            headers: { Authorization: `Bearer ${token}` }
          });
          if (configResponse.status === 401) {
            handleUnauthorized();
            return {};
          }
          if (!configResponse.ok) {
            throw new Error(`HTTP ${configResponse.status}`);
          }
          const configData = await configResponse.json();
          progress?.update?.('Konfiguration wird geladen...', 75);
          config = normalizeConfigEntries(Array.isArray(configData) ? configData : []);
        } else {
          progress?.update?.('Konfiguration wird geladen...', 75);
        }
        progress?.update?.('Synchronisierung abgeschlossen', 95);

        return {
          session: sessionData,
          stores,
          adminSettings,
          regularPickupMap: data.regularPickupMap ?? null,
          config,
          storeRefreshJob: data.storeRefreshJob,
          storesFresh: data.storesFresh
        };
      } catch (error) {
        setError(`Session konnte nicht wiederhergestellt werden: ${error.message}`);
        return {};
      } finally {
        setLoading(false);
      }
    },
    [normalizeConfigEntries, handleUnauthorized, setError, setLoading]
  );

  const performLogout = useCallback(async () => {
    if (!session?.token) {
      handleUnauthorized();
      return;
    }
    try {
      await authorizedFetch('/api/auth/logout', { method: 'POST' });
    } catch (err) {
      console.warn('Logout fehlgeschlagen:', err);
    } finally {
      handleUnauthorized();
    }
  }, [session?.token, authorizedFetch, handleUnauthorized]);

  return {
    session,
    authorizedFetch,
    bootstrapSession,
    performLogout,
    handleUnauthorized,
    storeToken,
    getStoredToken
  };
};

export default useSessionManager;
