'use client';

import {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
  ReactNode,
} from 'react';
import {
  User,
  AuthTokens,
  RegisterRequest,
  LoginRequest,
  getStoredUser,
  getStoredToken,
  login as apiLogin,
  register as apiRegister,
  logout as apiLogout,
  getMe,
  refreshTokens,
  clearAuth,
} from '@/lib/auth';

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (data: LoginRequest) => Promise<AuthTokens>;
  register: (data: RegisterRequest) => Promise<AuthTokens>;
  logout: () => Promise<void>;
  refreshUser: () => Promise<void>;
  showAuthModal: (mode: 'login' | 'register') => void;
  hideAuthModal: () => void;
  authModalMode: 'login' | 'register' | null;
}

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

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [authModalMode, setAuthModalMode] = useState<'login' | 'register' | null>(null);

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

    const storedUser = getStoredUser();
    if (storedUser) {
      setUser(storedUser);
    }

    try {
      const freshUser = await getMe();
      if (freshUser) {
        setUser(freshUser);
      } else {
        setUser(null);
        clearAuth();
      }
    } catch {
      const refreshed = await refreshTokens();
      if (refreshed) {
        setUser(refreshed.user);
      } else {
        setUser(null);
        clearAuth();
      }
    } finally {
      setIsLoading(false);
    }
  }, []);

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

  const login = useCallback(async (data: LoginRequest): Promise<AuthTokens> => {
    const tokens = await apiLogin(data);
    setUser(tokens.user);
    setAuthModalMode(null);
    return tokens;
  }, []);

  const register = useCallback(async (data: RegisterRequest): Promise<AuthTokens> => {
    const tokens = await apiRegister(data);
    setUser(tokens.user);
    setAuthModalMode(null);
    return tokens;
  }, []);

  const logout = useCallback(async () => {
    await apiLogout();
    setUser(null);
  }, []);

  const refreshUser = useCallback(async () => {
    const freshUser = await getMe();
    setUser(freshUser);
  }, []);

  const showAuthModal = useCallback((mode: 'login' | 'register') => {
    setAuthModalMode(mode);
  }, []);

  const hideAuthModal = useCallback(() => {
    setAuthModalMode(null);
  }, []);

  return (
    <AuthContext.Provider
      value={{
        user,
        isLoading,
        isAuthenticated: !!user,
        login,
        register,
        logout,
        refreshUser,
        showAuthModal,
        hideAuthModal,
        authModalMode,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth(): AuthContextType {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within AuthProvider');
  }
  return context;
}
