import { createContext, useContext, useEffect, useState, useCallback } from "react";

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [user, setUser] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [mustChangePassword, setMustChangePassword] = useState(false);

  useEffect(() => {
    let cancelled = false;

    window.omsorg.auth.getSession().then((session) => {
      if (cancelled) return;
      setIsAuthenticated(session.isAuthenticated);
      setUser(session.user);
      setMustChangePassword(!!session.mustChangePassword);
      setIsLoading(false);
    });

    const unsubscribe = window.omsorg.auth.onSessionChanged((session) => {
      setIsAuthenticated(session.isAuthenticated);
      setUser(session.user);
      setMustChangePassword(!!session.mustChangePassword);
      setIsLoading(false);
    });

    return () => {
      cancelled = true;
      unsubscribe();
    };
  }, []);

  const login = useCallback(async (username, password) => {
    const result = await window.omsorg.auth.login(username, password);
    if (result.success) {
      setIsAuthenticated(true);
      setUser(result.user);
      setMustChangePassword(!!result.mustChangePassword);
    }
    return result;
  }, []);

  const logout = useCallback(async () => {
    await window.omsorg.auth.logout();
    setIsAuthenticated(false);
    setUser(null);
    setMustChangePassword(false);
  }, []);

  const changePassword = useCallback(async (currentPassword, newPassword) => {
    const result = await window.omsorg.auth.changePassword(currentPassword, newPassword);
    if (result.success) {
      // Serverseitig wurden alle Sessions widerrufen (siehe UserService.ChangeOwnPasswordAsync) -
      // der aktuelle Access-Token ist schon tot, also lokal neu einloggen lassen statt weiterzumachen.
      setIsAuthenticated(false);
      setUser(null);
      setMustChangePassword(false);
    }
    return result;
  }, []);

  const hasPermission = useCallback(
    (module, action) => !!user?.permissions?.some((p) => p.module === module && p.action === action),
    [user]
  );

  return (
    <AuthContext.Provider
      value={{ isAuthenticated, user, isLoading, mustChangePassword, login, logout, changePassword, hasPermission }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth muss innerhalb von AuthProvider verwendet werden");
  return ctx;
}
