import React, { createContext, useContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

export interface User {
  id: string;
  email: string;
  name: string;
}

interface AuthContextType {
  user: User | null;
  loading: boolean;
  hasCompletedOnboarding: boolean;
  signUp: (email: string, password: string, name: string) => Promise<void>;
  signIn: (email: string, password: string) => Promise<void>;
  signOut: () => Promise<void>;
  completeOnboarding: () => Promise<void>;
}

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

const AUTH_STORAGE_KEY = '@pottery_diary_auth';
const USERS_STORAGE_KEY = '@pottery_diary_users';
const ONBOARDING_STORAGE_KEY = '@pottery_diary_onboarding';

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [hasCompletedOnboarding, setHasCompletedOnboarding] = useState(false);

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

  const loadUser = async () => {
    try {
      const userData = await AsyncStorage.getItem(AUTH_STORAGE_KEY);
      if (userData) {
        const parsedUser = JSON.parse(userData);
        setUser(parsedUser);

        // Load onboarding status for this user
        const onboardingData = await AsyncStorage.getItem(ONBOARDING_STORAGE_KEY);
        if (onboardingData) {
          const completedUsers = JSON.parse(onboardingData);
          setHasCompletedOnboarding(completedUsers[parsedUser.id] === true);
        }
      }
    } catch (error) {
      console.error('Failed to load user:', error);
    } finally {
      setLoading(false);
    }
  };

  const signUp = async (email: string, password: string, name: string) => {
    try {
      // Get existing users
      const usersData = await AsyncStorage.getItem(USERS_STORAGE_KEY);
      const users: Record<string, { email: string; password: string; name: string; id: string }> =
        usersData ? JSON.parse(usersData) : {};

      // Check if user already exists
      if (users[email.toLowerCase()]) {
        throw new Error('User with this email already exists');
      }

      // Create new user
      const newUser: User = {
        id: Date.now().toString(),
        email: email.toLowerCase(),
        name,
      };

      // Store user credentials
      users[email.toLowerCase()] = {
        email: email.toLowerCase(),
        password, // In production, this should be hashed
        name,
        id: newUser.id,
      };

      await AsyncStorage.setItem(USERS_STORAGE_KEY, JSON.stringify(users));
      await AsyncStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(newUser));

      setUser(newUser);
      setHasCompletedOnboarding(false); // New users haven't completed onboarding
    } catch (error) {
      console.error('Sign up failed:', error);
      throw error;
    }
  };

  const signIn = async (email: string, password: string) => {
    try {
      // Get existing users
      const usersData = await AsyncStorage.getItem(USERS_STORAGE_KEY);
      const users: Record<string, { email: string; password: string; name: string; id: string }> =
        usersData ? JSON.parse(usersData) : {};

      const storedUser = users[email.toLowerCase()];

      if (!storedUser || storedUser.password !== password) {
        throw new Error('Invalid email or password');
      }

      const currentUser: User = {
        id: storedUser.id,
        email: storedUser.email,
        name: storedUser.name,
      };

      await AsyncStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(currentUser));

      // Load onboarding status for returning user BEFORE setting user state
      // This prevents the flickering of the Onboarding screen
      const onboardingData = await AsyncStorage.getItem(ONBOARDING_STORAGE_KEY);
      let isCompleted = false;
      if (onboardingData) {
        const completedUsers = JSON.parse(onboardingData);
        isCompleted = completedUsers[currentUser.id] === true;
      }

      // Update states together
      setHasCompletedOnboarding(isCompleted);
      setUser(currentUser);
    } catch (error) {
      console.error('Sign in failed:', error);
      throw error;
    }
  };

  const signOut = async () => {
    try {
      await AsyncStorage.removeItem(AUTH_STORAGE_KEY);
      setUser(null);
      setHasCompletedOnboarding(false);
    } catch (error) {
      console.error('Sign out failed:', error);
      throw error;
    }
  };

  const completeOnboarding = async () => {
    if (!user) return;

    try {
      // Get existing onboarding data
      const onboardingData = await AsyncStorage.getItem(ONBOARDING_STORAGE_KEY);
      const completedUsers = onboardingData ? JSON.parse(onboardingData) : {};

      // Mark this user as having completed onboarding
      completedUsers[user.id] = true;

      await AsyncStorage.setItem(ONBOARDING_STORAGE_KEY, JSON.stringify(completedUsers));
      setHasCompletedOnboarding(true);
    } catch (error) {
      console.error('Failed to save onboarding completion:', error);
      throw error;
    }
  };

  return (
    <AuthContext.Provider value={{ user, loading, hasCompletedOnboarding, signUp, signIn, signOut, completeOnboarding }}>
      {children}
    </AuthContext.Provider>
  );
};

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