import { createContext, useContext, useState, ReactNode } from 'react';
import { useEffect } from 'react';
import { useNavigate } from "react-router-dom";
import { supabase } from '@/lib/supabase';

interface User {
    email: string;
    password: string;
}

interface AuthContextType {
    isAuthenticated: boolean;
    loading: boolean;
    login: (user_login_data: User) => void;
    logout: () => void;
    check_auth: (target_path: string | null) => void;
    authStep: string;
}

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

export const AuthProvider = ({ children }: { children: ReactNode }) => {
    const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
    const [loading, setLoading] = useState<boolean>(true);
    const [authStep, setAuthStep] = useState<string>("Initializing");
    const navigate = useNavigate();

    // Monitor session expiration periodically
    useEffect(() => {
        let sessionCheckInterval: NodeJS.Timeout;

        const checkSessionValidity = async () => {
            // Only check if user is authenticated
            if (!isAuthenticated) {
                return;
            }

            try {
                // Use Supabase SDK to validate session
                const { data: { session }, error } = await supabase.auth.getSession();

                if (error || !session) {
                    // Session expired or invalid
                    handleSessionExpired();
                }
            } catch (error) {
                console.error("Session validation failed:", error);
                // Network error or server error - don't logout immediately
                // Let the user continue and handle on next navigation attempt
            }
        };

        const handleSessionExpired = () => {
            // Clear all authentication data
            localStorage.removeItem("session_data");
            localStorage.setItem('IsAuthenticated', 'false');
            setIsAuthenticated(false);
            setAuthStep("Session expired");

            // Refresh the page to reset app state and redirect to landing
            window.location.href = '/';
        };

        // Start periodic session check (every 5 minutes)
        if (isAuthenticated) {
            sessionCheckInterval = setInterval(checkSessionValidity, 5 * 60 * 1000);
        }

        return () => {
            if (sessionCheckInterval) {
                clearInterval(sessionCheckInterval);
            }
        };
    }, [isAuthenticated]);
    
    const check_auth = async(target_path: string | null) => {
        setLoading(true);
        setAuthStep("Checking session");

        try {
            // Use Supabase SDK to check session validity
            setAuthStep("Validating token");
            const { data: { session }, error } = await supabase.auth.getSession();

            if (error) {
                console.error("Session check error:", error);
                throw error;
            }

            if (session) {
                // Session is valid
                setAuthStep("Authentication successful");
                setIsAuthenticated(true);
                localStorage.setItem('IsAuthenticated', 'true');

                // Store session data in expected format
                const session_data = {
                    success: true,
                    user: session.user,
                    session: session
                };
                localStorage.setItem("session_data", JSON.stringify(session_data));

                if (target_path) {
                    navigate(target_path);
                }
            } else {
                // No valid session - redirect to login
                setAuthStep("No session found");
                localStorage.removeItem("session_data");
                localStorage.setItem('IsAuthenticated', 'false');
                setIsAuthenticated(false);
                navigate("/login");
            }
        } catch (error) {
            console.error("Auth check failed:", error);
            setAuthStep("Connection failed");
            localStorage.removeItem("session_data");
            localStorage.setItem('IsAuthenticated', 'false');
            setIsAuthenticated(false);
            navigate("/login");
        }

        setLoading(false);
    }

    const login = async (user_login_data: User) => {
        // Use Supabase Auth SDK for login
        const { data, error } = await supabase.auth.signInWithPassword({
            email: user_login_data.email,
            password: user_login_data.password,
        });

        if (error) {
            throw new Error(error.message);
        }

        if (data.session) {
            // Store session data in the format expected by existing code
            const login_response = {
                success: true,
                user: data.user,
                session: data.session
            };
            localStorage.setItem("session_data", JSON.stringify(login_response));

            // Check for pending integration redirect
            const pendingRedirect = sessionStorage.getItem('pending_integration_redirect');
            if (pendingRedirect) {
                sessionStorage.removeItem('pending_integration_redirect');
                check_auth(pendingRedirect);
            } else {
                check_auth("/dashboard");
            }
        } else {
            throw new Error("Login failed - no session created");
        }
    };

    const logout = async () => {
        // Sign out from Supabase
        await supabase.auth.signOut();

        // Clear local storage
        localStorage.removeItem("session_data");
        setIsAuthenticated(false);
        localStorage.setItem('IsAuthenticated', 'false');
        navigate("/login");
    };

    // Show loading while checking authentication
    return (
        <AuthContext.Provider value={{ isAuthenticated, loading, check_auth, login, logout, authStep }}>
            {children}
        </AuthContext.Provider>
    );
};

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