import React, { createContext, useContext, useEffect, useState } from 'react';
import { ActivityIndicator, View, Text } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import {
  createAuthService,
  createTokenManager,
  setStorageAdapter,
  setDeviceAdapter,
  setNetworkAdapter,
  createMemoryStorageAdapter,
  type UserData,
} from '@manacore/shared-auth';

// Mana Core Auth URL from environment
const MANA_AUTH_URL = process.env.EXPO_PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001';

// Create SecureStore adapter for React Native
const createSecureStoreAdapter = () => ({
  async getItem<T>(key: string): Promise<T | null> {
    try {
      const value = await SecureStore.getItemAsync(key);
      return value ? JSON.parse(value) : null;
    } catch {
      return null;
    }
  },
  async setItem(key: string, value: unknown): Promise<void> {
    await SecureStore.setItemAsync(key, JSON.stringify(value));
  },
  async removeItem(key: string): Promise<void> {
    await SecureStore.deleteItemAsync(key);
  },
});

// Create device adapter for React Native
const createReactNativeDeviceAdapter = () => {
  let deviceId: string | null = null;

  return {
    async getDeviceInfo() {
      if (!deviceId) {
        // Try to get stored device ID
        deviceId = await SecureStore.getItemAsync('@device/id');

        if (!deviceId) {
          // Generate new device ID
          deviceId = `rn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
          await SecureStore.setItemAsync('@device/id', deviceId);
        }
      }

      return {
        deviceId,
        deviceName: 'React Native Device',
        platform: 'react-native',
      };
    },
    async getStoredDeviceId() {
      return deviceId || (await SecureStore.getItemAsync('@device/id'));
    },
  };
};

// Create network adapter (basic implementation)
const createReactNativeNetworkAdapter = () => ({
  async isConnected() {
    return true; // Always assume connected for now
  },
  async hasStableConnection() {
    return true;
  },
});

// Initialize adapters
setStorageAdapter(createSecureStoreAdapter());
setDeviceAdapter(createReactNativeDeviceAdapter());
setNetworkAdapter(createReactNativeNetworkAdapter());

// Create auth service
const authService = createAuthService({ baseUrl: MANA_AUTH_URL });
const tokenManager = createTokenManager(authService);

// Auth context type
type AuthContextType = {
  user: UserData | null;
  loading: boolean;
  signIn: (email: string, password: string) => Promise<{ error: any | null }>;
  signUp: (email: string, password: string) => Promise<{ error: any | null; data: any | null }>;
  signOut: () => Promise<void>;
  resetPassword: (email: string) => Promise<{ error: any | null }>;
};

// Create auth context
const AuthContext = createContext<AuthContextType | undefined>(undefined);

// Hook to access auth context
export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

// AuthProvider component
export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<UserData | null>(null);
  const [loading, setLoading] = useState(true);

  // Initialize auth state
  useEffect(() => {
    const initialize = async () => {
      try {
        setLoading(true);

        // Check if user is authenticated
        const authenticated = await authService.isAuthenticated();

        if (authenticated) {
          const userData = await authService.getUserFromToken();
          setUser(userData);
        }
      } catch (error) {
        console.error('Fehler beim Initialisieren der Auth-Session:', error);
        setUser(null);
      } finally {
        setLoading(false);
      }
    };

    initialize();
  }, []);

  // Sign in with email and password
  const signIn = async (email: string, password: string) => {
    try {
      console.log('Versuche Anmeldung mit:', email);
      const result = await authService.signIn(email, password);

      if (!result.success) {
        console.error('Auth Fehler:', result.error);
        return { error: { message: result.error } };
      }

      // Get user data from token
      const userData = await authService.getUserFromToken();
      setUser(userData);

      console.log('Anmeldung erfolgreich:', userData?.userId);
      return { error: null };
    } catch (error: any) {
      console.error('Unerwarteter Fehler beim Anmelden:', error.message || error);
      return { error };
    }
  };

  // Sign up with email and password
  const signUp = async (email: string, password: string) => {
    try {
      const result = await authService.signUp(email, password);

      if (!result.success) {
        return { data: null, error: { message: result.error } };
      }

      // Auto sign in after successful signup
      const signInResult = await signIn(email, password);

      if (signInResult.error) {
        return { data: null, error: signInResult.error };
      }

      return { data: user, error: null };
    } catch (error) {
      console.error('Fehler beim Registrieren:', error);
      return { data: null, error };
    }
  };

  // Sign out
  const signOut = async () => {
    try {
      await authService.signOut();
      setUser(null);
    } catch (error) {
      console.error('Fehler beim Abmelden:', error);
    }
  };

  // Reset password
  const resetPassword = async (email: string) => {
    try {
      const result = await authService.forgotPassword(email);

      if (!result.success) {
        return { error: { message: result.error } };
      }

      return { error: null };
    } catch (error) {
      console.error('Fehler beim Zurücksetzen des Passworts:', error);
      return { error };
    }
  };

  // Show loading indicator during initialization
  if (loading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" color="#0A84FF" />
        <Text style={{ marginTop: 16 }}>Authentifizierung wird initialisiert...</Text>
      </View>
    );
  }

  // Provide auth context
  return (
    <AuthContext.Provider
      value={{
        user,
        loading,
        signIn,
        signUp,
        signOut,
        resetPassword,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}
