import React, { createContext, useState, useContext, useEffect, ReactNode } from 'react';
import { authService, AuthResponse, UserResponse } from '../services/authApi';

interface AuthContextType {
  isAuthenticated: boolean;
  user: UserResponse | null;
  token: string | null;
  login: (usernameOrEmail: string, password: string) => Promise<void>;
  signUp: (username: string, email: string, password: string, name?: string) => Promise<void>;
  logout: () => void;
  isLoading: boolean;
}

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

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

interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [user, setUser] = useState<UserResponse | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // 페이지 로드 시 로컬 스토리지에서 토큰 복원
    const storedToken = localStorage.getItem('accessToken');
    const storedUser = localStorage.getItem('user');

    if (storedToken && storedUser) {
      setToken(storedToken);
      setUser(JSON.parse(storedUser));
      
      // 토큰 유효성 확인
      authService.getCurrentUser(storedToken)
        .then((userData) => {
          setUser(userData);
          localStorage.setItem('user', JSON.stringify(userData));
        })
        .catch(() => {
          // 토큰 만료 시 로그아웃
          console.error('토큰이 만료되었습니다.');
          logout();
        })
        .finally(() => {
          setIsLoading(false);
        });
    } else {
      setIsLoading(false);
    }
  }, []);

  const login = async (usernameOrEmail: string, password: string) => {
    try {
      console.log('[AuthContext] 로그인 시도:', { usernameOrEmail });
      
      const authResponse: AuthResponse = await authService.login({
        usernameOrEmail,
        password,
      });

      console.log('[AuthContext] 로그인 성공:', { 
        username: authResponse.username, 
        tokenLength: authResponse.accessToken?.length 
      });

      setToken(authResponse.accessToken);
      setUser({
        id: authResponse.userId,
        username: authResponse.username,
        email: authResponse.email,
        name: authResponse.name,
        role: 'USER',
        createdAt: new Date().toISOString(),
      });

      // 로컬 스토리지에 저장
      localStorage.setItem('accessToken', authResponse.accessToken);
      localStorage.setItem('user', JSON.stringify({
        id: authResponse.userId,
        username: authResponse.username,
        email: authResponse.email,
        name: authResponse.name,
        role: 'USER',
        createdAt: new Date().toISOString(),
      }));
    } catch (error: any) {
      console.error('[AuthContext] 로그인 실패:', error);
      throw error;
    }
  };

  const signUp = async (username: string, email: string, password: string, name?: string) => {
    try {
      const authResponse: AuthResponse = await authService.signUp({
        username,
        email,
        password,
        name,
      });

      setToken(authResponse.accessToken);
      setUser({
        id: authResponse.userId,
        username: authResponse.username,
        email: authResponse.email,
        name: authResponse.name,
        role: 'USER',
        createdAt: new Date().toISOString(),
      });

      // 로컬 스토리지에 저장
      localStorage.setItem('accessToken', authResponse.accessToken);
      localStorage.setItem('user', JSON.stringify({
        id: authResponse.userId,
        username: authResponse.username,
        email: authResponse.email,
        name: authResponse.name,
        role: 'USER',
        createdAt: new Date().toISOString(),
      }));
    } catch (error: any) {
      console.error('회원가입 실패:', error);
      throw error;
    }
  };

  const logout = () => {
    setToken(null);
    setUser(null);
    localStorage.removeItem('accessToken');
    localStorage.removeItem('user');
    
    // 서버에 로그아웃 알림 (옵션)
    authService.logout().catch(console.error);
  };

  return (
    <AuthContext.Provider
      value={{
        isAuthenticated: !!token,
        user,
        token,
        login,
        signUp,
        logout,
        isLoading,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

