import React, { createContext, useContext, useEffect, useState } from 'react';
import { useSession, signIn, signOut } from 'next-auth/react';
import axios from 'axios';

interface User {
  uid: string;
  email: string | null;
  displayName: string | null;
  emailVerified: boolean;
  isAnonymous: boolean;
}

interface AuthContextType {
  currentUser: User | null;
  userProfile: any | null;
  loading: boolean;
  isAdmin: boolean;
  sendOtp: (email: string, pass: string) => Promise<void>;
  loginWithEmail: (email: string, pass: string, otp: string) => Promise<void>;
  loginWithGoogle: (callbackUrl?: string) => Promise<any>;
  registerWithEmail: (email: string, pass: string, profileData?: any) => Promise<any>;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType>({
  currentUser: null,
  userProfile: null,
  loading: true,
  isAdmin: false,
  sendOtp: async () => {},
  loginWithEmail: async () => {},
  loginWithGoogle: async () => {},
  registerWithEmail: async () => {},
  logout: async () => {},
});

export const useAuth = () => useContext(AuthContext);

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const { data: session, status } = useSession();
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [userProfile, setUserProfile] = useState<any | null>(null);
  const [profileLoading, setProfileLoading] = useState(false);

  const loading = status === 'loading' || profileLoading || (status === 'authenticated' && currentUser === null);
  const isAdmin = userProfile?.role === 'admin';

  useEffect(() => {
    if (status === 'authenticated' && session?.user?.email) {
      const fetchProfile = async () => {
        setProfileLoading(true);
        try {
          const res = await axios.post('/api/db/query', {
            collection: 'users',
            conditions: [{ field: 'email', op: '==', value: session.user?.email }]
          });
          if (res.data && res.data.length > 0) {
            setUserProfile(res.data[0]);
            
            setCurrentUser({
              uid: res.data[0].id || session?.user?.email || '',
              email: session?.user?.email || '',
              displayName: session?.user?.name || session?.user?.email?.split('@')[0] || 'User',
              emailVerified: true,
              isAnonymous: false,
            });
          } else {
            console.warn("User profile not found in database. Forcing logout.");
            await signOut({ redirect: true, callbackUrl: '/login' });
          }
        } catch (error) {
          console.error("Error fetching user profile:", error);
          setCurrentUser({
            uid: session?.user?.email || '',
            email: session?.user?.email || '',
            displayName: session?.user?.name || session?.user?.email?.split('@')[0] || 'User',
            emailVerified: true,
            isAnonymous: false,
          });
          setUserProfile(null);
        } finally {
          setProfileLoading(false);
        }
      };
      fetchProfile();
    } else if (status === 'unauthenticated') {
      setCurrentUser(null);
      setUserProfile(null);
      setProfileLoading(false);
    }
  }, [session, status]);

  const sendOtp = async (email: string, pass: string) => {
    const res = await axios.post('/api/auth/send-otp', { email, password: pass });
    if (res.data.error) {
      throw new Error(res.data.error);
    }
    return res.data;
  };

  const loginWithEmail = async (email: string, pass: string, otp: string) => {
    const res = await signIn('credentials', {
      redirect: false,
      email,
      password: pass,
      otp
    });
    if (res?.error) {
      throw new Error(res.error);
    }
  };

  const loginWithGoogle = async (callbackUrl: string = '/admin') => {
    // NextAuth's signIn with Google redirects by default.
    // We trigger it here.
    signIn('google', { callbackUrl });
  };

  const registerWithEmail = async (email: string, pass: string, profileData: any = null) => {
    try {
      // 1. Generate temporary OTP for registration auto-login
      const tempOtp = Math.floor(100000 + Math.random() * 900000).toString();
      const tempOtpExpiry = new Date(Date.now() + 2 * 60000).toISOString(); // 2 minutes

      // 2. Create the user in the database
      await axios.post('/api/db', {
        collection: 'users',
        data: {
          email,
          password: pass,
          role: 'client',
          status: 'active',
          otpCode: tempOtp,
          otpExpiry: tempOtpExpiry,
          ...profileData
        }
      });
      
      // 3. Log them in
      const res = await signIn('credentials', {
        redirect: false,
        email,
        password: pass,
        otp: tempOtp
      });
      
      if (res?.error) {
        throw new Error(res.error);
      }
      return res;
    } catch (error: any) {
      console.error("Registration Error:", error);
      throw error;
    }
  };

  const logout = async () => {
    localStorage.clear();
    await signOut({ redirect: false });
  };

  return (
    <AuthContext.Provider value={{ currentUser, userProfile, loading, isAdmin, sendOtp, loginWithEmail, loginWithGoogle, registerWithEmail, logout }}>
      {!loading && children}
    </AuthContext.Provider>
  );
};
