import React, { createContext, useContext, useState, useEffect } from 'react';
import * as Haptics from 'expo-haptics';
import * as LocalAuthentication from 'expo-local-authentication';
import { storage } from '../utils/storage';
import { Platform } from 'react-native';
import { router } from 'expo-router';
import { ApiService } from '../services/api';
import { DebugLogger } from '../utils/logger';

interface User {
  id: string;
  name: string;
  email: string;
  avatar?: string;
}

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  signIn: (email: string, pass: string) => Promise<void>;
  signOut: () => void;
  signUp: (name: string, email: string, pass: string) => Promise<void>;
  updateProfile: (name: string, email: string) => Promise<void>;
  syncUser: () => Promise<void>;
}

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

// Storage helper is now imported from utils/storage

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

  useEffect(() => {
    loadStoredToken();
  }, []);

  const loadStoredToken = async () => {
    try {
      const token = await storage.get('user_token');
      const storedUser = await storage.get('user_data');
      if (token && storedUser) {
        setUser(JSON.parse(storedUser));
      }
    } catch (e) {
      console.warn('Authentication failed during boot:', e);
      await storage.remove('user_token');
      await storage.remove('user_data');
      setUser(null);
    } finally {
      setIsLoading(false);
    }
  };

  const signIn = async (email: string, pass: string) => {
    setIsLoading(true);
    try {
      const response = await ApiService.login(email, pass);
      const userData = response.data.user;
      const token = response.data.token;
      
      setUser(userData);
      await storage.save('user_token', token);
      await storage.save('user_data', JSON.stringify(userData));
      await storage.save('saved_email', email);
      await storage.save('saved_pass', pass);
      DebugLogger.log(`User signed in: ${email}`, 'info');
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
    } catch (error: any) {
      DebugLogger.log(`Login failed for ${email}: ${error.message}`, 'error');
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const signUp = async (name: string, email: string, pass: string) => {
    setIsLoading(true);
    try {
      const response = await ApiService.register(name, email, pass);
      const userData = response.data.user;
      const token = response.data.token;

      setUser(userData);
      await storage.save('user_token', token);
      await storage.save('user_data', JSON.stringify(userData));
      await storage.save('saved_email', email);
      await storage.save('saved_pass', pass);
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
    } catch (error) {
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const updateProfile = async (name: string, email: string) => {
    setIsLoading(true);
    try {
      const response = await ApiService.updateProfile(name, email);
      const userData = response.data.user;
      setUser(userData);
      await storage.save('user_data', JSON.stringify(userData));
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
    } catch (error) {
      if (Platform.OS !== 'web') Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const signOut = async () => {
    setUser(null);
    await storage.remove('user_token');
    await storage.remove('user_data');
    if (Platform.OS !== 'web') Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
    DebugLogger.log('User signed out', 'info');
    router.replace('/(auth)/login');
  };

  const syncUser = async () => {
    if (!user) return;
    try {
      const response = await ApiService.getUser();
      const userData = response.data.user;
      setUser(userData);
      await storage.save('user_data', JSON.stringify(userData));
    } catch (error: any) {
      DebugLogger.log(`Sync failed: ${error.message}`, 'error');
      // If it's a 401, we might want to sign out, but for now let's be silent 
      // to avoid the "Global refresh failed" loop that annoys the user.
      if (error.message.includes('Unauthenticated')) {
         console.warn('Silent sync failure: User is unauthenticated but staying in app.');
      } else {
         throw error;
      }
    }
  };

  return (
    <AuthContext.Provider value={{ user, isLoading, signIn, signOut, signUp, updateProfile, syncUser }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined) {
    return {
      user: null,
      isLoading: false,
      signIn: async () => {},
      signOut: () => {},
      signUp: async () => {},
      updateProfile: async () => {},
      syncUser: async () => {}
    } as any;
  }
  return context;
}
