import React, { createContext, useContext, useState, useEffect } from 'react';
import api from '../api';

const AuthContext = createContext();

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

export const AuthProvider = ({ children }) => {
    const [user, setUser] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const [isAuthenticated, setIsAuthenticated] = useState(false);

    // 토큰 관리
    const getToken = () => localStorage.getItem('access_token');
    const getRefreshToken = () => localStorage.getItem('refresh_token');
    
    const setTokens = (accessToken, refreshToken) => {
        localStorage.setItem('access_token', accessToken);
        if (refreshToken) {
            localStorage.setItem('refresh_token', refreshToken);
        }
    };
    
    const clearTokens = () => {
        localStorage.removeItem('access_token');
        localStorage.removeItem('refresh_token');
        localStorage.removeItem('user_data');
    };

    // 사용자 권한 확인
    const hasPermission = (permission) => {
        if (!user || !user.permissions) return false;
        return user.permissions.includes(permission);
    };

    const hasRole = (role) => {
        if (!user) return false;
        return user.role === role;
    };

    const isAdmin = () => hasRole('admin') || hasRole('system');
    const isManager = () => hasRole('admin') || hasRole('system') || hasRole('leader');

    // 로그인
    const login = async (username, password) => {
        try {
            const response = await api.post('/auth/login', {
                username,
                password
            });

            if (response.data.success) {
                const { access_token, refresh_token, user: userData } = response.data;
                
                setTokens(access_token, refresh_token);
                setUser(userData);
                setIsAuthenticated(true);
                
                // 사용자 데이터 로컬 저장
                localStorage.setItem('user_data', JSON.stringify(userData));
                
                return userData;
            } else {
                throw new Error(response.data.error?.message || '로그인에 실패했습니다.');
            }
        } catch (error) {
            console.error('Login error:', error);
            
            if (error.response?.data?.error?.message) {
                throw new Error(error.response.data.error.message);
            } else if (error.response?.status === 401) {
                throw new Error('아이디 또는 비밀번호가 올바르지 않습니다.');
            } else if (error.response?.status >= 500) {
                throw new Error('서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.');
            } else {
                throw new Error('로그인에 실패했습니다. 네트워크 연결을 확인해주세요.');
            }
        }
    };

    // 로그아웃
    const logout = async () => {
        try {
            const token = getToken();
            if (token) {
                await api.post('/auth/logout');
            }
        } catch (error) {
            console.error('Logout error:', error);
        } finally {
            clearTokens();
            setUser(null);
            setIsAuthenticated(false);
        }
    };

    // 토큰 갱신
    const refreshAccessToken = async () => {
        try {
            const refreshToken = getRefreshToken();
            if (!refreshToken) {
                throw new Error('No refresh token available');
            }

            const response = await api.post('/auth/refresh', {
                refresh_token: refreshToken
            });

            if (response.data.success) {
                const { access_token } = response.data;
                setTokens(access_token);
                return access_token;
            } else {
                throw new Error('Token refresh failed');
            }
        } catch (error) {
            console.error('Token refresh error:', error);
            await logout();
            throw error;
        }
    };

    // 현재 사용자 정보 조회
    const getCurrentUser = async () => {
        try {
            const token = getToken();
            if (!token) {
                throw new Error('No access token available');
            }
            
            const response = await api.get('/auth/me');
            if (response.data.success) {
                const userData = response.data.user;
                setUser(userData);
                setIsAuthenticated(true);
                localStorage.setItem('user_data', JSON.stringify(userData));
                return userData;
            }
        } catch (error) {
            console.error('Get current user error:', error);
            if (error.response?.status === 401 || error.response?.status === 403) {
                // 토큰이 만료되었거나 인증 실패한 경우 갱신 시도
                try {
                    await refreshAccessToken();
                    return await getCurrentUser();
                } catch (refreshError) {
                    await logout();
                }
            }
            throw error;
        }
    };

    // 초기 인증 상태 확인
    useEffect(() => {
        const initializeAuth = async () => {
            try {
                const token = getToken();
                const savedUserData = localStorage.getItem('user_data');
                
                if (token && savedUserData) {
                    try {
                        const userData = JSON.parse(savedUserData);
                        setUser(userData);
                        setIsAuthenticated(true);
                        
                        // 백그라운드에서 토큰 유효성 검증 (선택적)
                        getCurrentUser().catch(error => {
                            console.warn('Background token validation failed:', error);
                            // 백그라운드 검증 실패는 무시 (사용자 경험 우선)
                        });
                    } catch (parseError) {
                        console.error('Failed to parse saved user data:', parseError);
                        clearTokens();
                        setUser(null);
                        setIsAuthenticated(false);
                    }
                } else {
                    // 토큰이나 사용자 데이터가 없으면 로그아웃 상태로 설정
                    setUser(null);
                    setIsAuthenticated(false);
                }
            } catch (error) {
                console.error('Auth initialization error:', error);
                clearTokens();
                setUser(null);
                setIsAuthenticated(false);
            } finally {
                setIsLoading(false);
            }
        };

        initializeAuth();
    }, []);

    // API 요청 인터셉터 설정
    useEffect(() => {
        const requestInterceptor = api.interceptors.request.use(
            (config) => {
                const token = getToken();
                if (token) {
                    config.headers.Authorization = `Bearer ${token}`;
                }
                return config;
            },
            (error) => Promise.reject(error)
        );

        const responseInterceptor = api.interceptors.response.use(
            (response) => response,
            async (error) => {
                const originalRequest = error.config;
                
                if (error.response?.status === 401 && !originalRequest._retry) {
                    originalRequest._retry = true;
                    
                    try {
                        await refreshAccessToken();
                        const token = getToken();
                        originalRequest.headers.Authorization = `Bearer ${token}`;
                        return api(originalRequest);
                    } catch (refreshError) {
                        await logout();
                        return Promise.reject(refreshError);
                    }
                }
                
                return Promise.reject(error);
            }
        );

        return () => {
            api.interceptors.request.eject(requestInterceptor);
            api.interceptors.response.eject(responseInterceptor);
        };
    }, []);

    const value = {
        user,
        isLoading,
        isAuthenticated,
        login,
        logout,
        getCurrentUser,
        hasPermission,
        hasRole,
        isAdmin,
        isManager,
        refreshAccessToken
    };

    return (
        <AuthContext.Provider value={value}>
            {children}
        </AuthContext.Provider>
    );
};
