import { createContext, useContext, useState, type ReactNode, useEffect } from 'react';
import { apiClient, setCsrfToken } from '../api/client';

export interface User {
    id: string;
    name: string;
    role: 'supervisor' | 'admin' | 'user';
    department?: string;
    position?: string;
    phone?: string;
    last_login?: string;
}

interface AuthContextType {
    user: User | null;
    login: (id: string, password: string) => Promise<boolean>;
    logout: () => void;
    isAuthenticated: boolean;
    isLoading: boolean;
}

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

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

    // Check for existing session on mount and periodically
    useEffect(() => {
        let lastActivity = Date.now();
        let timeoutMs = 3600000; // Default 1 hour

        const checkSession = async () => {
            try {
                const response = await apiClient.get('/check');
                if (response.data.isAuthenticated) {
                    setUser(response.data.user);
                    if (response.data.csrfToken) setCsrfToken(response.data.csrfToken);
                    if (response.data.sessionTimeout) timeoutMs = response.data.sessionTimeout;
                } else {
                    // Safety: only redirect if we were previously logged in
                    setUser(prev => {
                        if (prev) {
                            setCsrfToken(null);
                            window.location.href = '/login?expired=true';
                            return null;
                        }
                        return prev;
                    });
                }
            } catch (error) {
                setUser(prev => {
                    if (prev) {
                        setCsrfToken(null);
                        window.location.href = '/login?expired=true';
                        return null;
                    }
                    return prev;
                });
            } finally {
                setIsLoading(false);
            }
        };

        const updateActivity = () => {
            lastActivity = Date.now();
        };

        // Activity Listeners
        window.addEventListener('mousemove', updateActivity);
        window.addEventListener('keydown', updateActivity);
        window.addEventListener('scroll', updateActivity);
        window.addEventListener('click', updateActivity);

        checkSession();

        // Check activity status every 30 seconds
        const activityInterval = setInterval(() => {
            // Functional check to avoid stale user closure
            setUser(current => {
                if (current) {
                    const idleTime = Date.now() - lastActivity;
                    if (idleTime >= timeoutMs) {
                        console.log('Idle timeout reached. Checking session...');
                        checkSession();
                    }
                }
                return current;
            });
        }, 30000);

        // Fallback polling every 5 minutes (for secondary tabs etc)
        const pollInterval = setInterval(checkSession, 300000);

        return () => {
            window.removeEventListener('mousemove', updateActivity);
            window.removeEventListener('keydown', updateActivity);
            window.removeEventListener('scroll', updateActivity);
            window.removeEventListener('click', updateActivity);
            clearInterval(activityInterval);
            clearInterval(pollInterval);
        };
    }, []); // Removed [user] to prevent infinite loop

    const login = async (id: string, password: string) => {
        try {
            const response = await apiClient.post('/login', { id, password });
            if (response.data.success) {
                setUser(response.data.user);
                if (response.data.csrfToken) {
                    setCsrfToken(response.data.csrfToken);
                }
                return true;
            }
            return false;
        } catch (error) {
            console.error('Login failed:', error);
            return false;
        }
    };

    const logout = async () => {
        try {
            await apiClient.post('/logout');
        } catch (error) {
            console.error('Logout failed:', error);
        } finally {
            setUser(null);
            setCsrfToken(null);
        }
    };

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

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