import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import axios from 'axios';
import { authApi, setAccessToken, getAccessToken } from '../services/api';
import type { User } from '../types';

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (email: string, password: string) => Promise<void>;
  customerLogin: (email: string, password: string) => Promise<User>;
  logout: () => Promise<void>;
  hasPermission: (permission: string) => boolean;
  isCustomer: boolean;
  isCustomerPortal: boolean;
  developerMode: boolean;
  setDeveloperMode: (enabled: boolean) => void;
  refreshUser: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [developerMode, setDeveloperModeState] = useState(() => {
    return localStorage.getItem('developerMode') === 'true';
  });

  const setDeveloperMode = (enabled: boolean) => {
    setDeveloperModeState(enabled);
    localStorage.setItem('developerMode', String(enabled));
  };

  // Disable developer mode if user doesn't have developer:access permission
  useEffect(() => {
    console.log('useEffect check - user:', user?.email, 'developerMode:', developerMode, 'has developer:access:', user?.permissions?.includes('developer:access'));
    if (user && developerMode && !user.permissions.includes('developer:access')) {
      console.log('Disabling developer mode because user lacks developer:access permission');
      setDeveloperMode(false);
    }
  }, [user, developerMode]);

  // Beim App-Start versuchen, einen Access-Token via Refresh-Cookie zu holen.
  // Wenn das klappt → User ist eingeloggt. Wenn nicht → User muss sich neu
  // anmelden. Der Access-Token bleibt nur im memory (kein localStorage).
  useEffect(() => {
    (async () => {
      try {
        const res = await axios.post('/api/auth/refresh', {}, { withCredentials: true });
        if (res.data?.success && res.data?.data?.token) {
          setAccessToken(res.data.data.token);
          // Danach den vollen User aus /me laden (Permissions etc.)
          const me = await authApi.me();
          if (me.success && me.data) setUser(me.data);
        }
      } catch {
        // Kein gültiger Refresh-Cookie → User ist nicht eingeloggt
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  const login = async (email: string, password: string) => {
    const res = await authApi.login(email, password);
    if (res.success && res.data) {
      setAccessToken(res.data.token);
      setUser(res.data.user);
    } else {
      throw new Error(res.error || 'Login fehlgeschlagen');
    }
  };

  const customerLogin = async (email: string, password: string): Promise<User> => {
    const res = await authApi.customerLogin(email, password);
    if (res.success && res.data) {
      setAccessToken(res.data.token);
      setUser(res.data.user);
      return res.data.user;
    }
    throw new Error(res.error || 'Login fehlgeschlagen');
  };

  const logout = async () => {
    // Server-Logout: invalidiert Refresh-Token-Cookie + tokenInvalidatedAt
    try {
      await authApi.logout();
    } catch {
      // Selbst wenn der Server-Logout fehlschlägt: client-side clear
    }
    setAccessToken(null);
    setUser(null);
  };

  const refreshUser = async () => {
    if (!getAccessToken()) return;
    try {
      const res = await authApi.me();
      if (res.success && res.data) setUser(res.data);
    } catch (err) {
      console.error('refreshUser error:', err);
    }
  };

  const hasPermission = (permission: string) => {
    if (!user) return false;
    return user.permissions.includes(permission);
  };

  // Ist der Benutzer ein Kunde (entweder Mitarbeiter mit Kundenzuordnung ODER Kundenportal-Login)
  const isCustomer = !!(user?.customerId);
  // Ist dies ein Kundenportal-Login (nicht ein Mitarbeiter mit Kundenzuordnung)
  const isCustomerPortal = !!(user?.isCustomerPortal);

  return (
    <AuthContext.Provider
      value={{
        user,
        isLoading,
        isAuthenticated: !!user,
        login,
        customerLogin,
        logout,
        hasPermission,
        isCustomer,
        isCustomerPortal,
        developerMode,
        setDeveloperMode,
        refreshUser,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
}
