import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { authApi, getToken } from '@/lib/api';
import { ApiError } from '@/lib/api';

interface User {
  id: string;
  email: string;
  name: string | null;
  createdAt?: Date | string;
}

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (email: string, password: string) => Promise<void>;
  register: (email: string, password: string, name?: string) => Promise<void>;
  logout: () => void;
  verifyAuth: () => Promise<void>;
  updateProfile: (data: { name?: string; email?: string; password?: string }) => Promise<void>;
}

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

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

  const verifyAuth = useCallback(async () => {
    const token = getToken();
    if (!token) {
      setIsLoading(false);
      return;
    }

    try {
      const response = await authApi.verify();
      if (response.valid && response.user) {
        const profile = await authApi.getProfile();
        setUser(profile.user);
      } else {
        setUser(null);
      }
    } catch (error) {
      console.error('Auth verification failed:', error);
      setUser(null);
    } finally {
      setIsLoading(false);
    }
  }, []);

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

  const login = async (email: string, password: string) => {
    try {
      const response = await authApi.login(email, password);
      if (response.user) {
        setUser(response.user);
      } else {
        throw new ApiError(500, 'Login successful but user data not received');
      }
    } catch (error) {
      console.error('Login error:', error);
      if (error instanceof ApiError) {
        throw error;
      }
      throw new ApiError(500, error instanceof Error ? error.message : 'Login failed');
    }
  };

  const register = async (email: string, password: string, name?: string) => {
    try {
      const response = await authApi.register(email, password, name);
      if (response.user) {
        setUser(response.user);
      } else {
        throw new ApiError(500, 'Registration successful but user data not received');
      }
    } catch (error) {
      console.error('Registration error:', error);
      if (error instanceof ApiError) {
        throw error;
      }
      throw new ApiError(500, error instanceof Error ? error.message : 'Registration failed');
    }
  };

  const logout = () => {
    authApi.logout();
    setUser(null);
  };

  const updateProfile = async (data: { name?: string; email?: string; password?: string }) => {
    const response = await authApi.updateProfile(data);
    if (response.user) setUser(response.user);
  };

  return (
    <AuthContext.Provider
      value={{
        user,
        isLoading,
        isAuthenticated: !!user,
        login,
        register,
        logout,
        verifyAuth,
        updateProfile,
      }}
    >
      {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;
};
