
import React, { useState, useCallback, useEffect, useRef, Suspense } from 'react';
import { User } from './types';
import * as authService from './services/authService';
import { getBackendUrl } from './services/api';
import PublicHomePage from './components/PublicHomePage';
import { Router, useRouter } from './components/Router';
import { loadRecaptcha } from './utils/recaptcha';

// Lazy load heavy components to improve TBT and LCP
const AuthContainer = React.lazy(() => import('./components/auth/AuthContainer'));
const Login = React.lazy(() => import('./components/auth/Login'));
const Register = React.lazy(() => import('./components/auth/Register'));
const ForgotPassword = React.lazy(() => import('./components/auth/ForgotPassword'));
const MainApp = React.lazy(() => import('./components/MainApp'));
const AdminPanel = React.lazy(() => import('./components/admin/AdminPanel'));
const GoogleCallback = React.lazy(() => import('./components/GoogleCallback'));
const PrivacyPolicyPage = React.lazy(() => import('./components/PrivacyPolicyPage'));
const TermsOfServicePage = React.lazy(() => import('./components/TermsOfServicePage'));
const PricingPage = React.lazy(() => import('./components/PricingPage'));
const DocumentationPage = React.lazy(() => import('./components/DocumentationPage'));
const LeadGenView = React.lazy(() => import('./components/LeadGenView'));
const PublicLeadForm = React.lazy(() => import('./components/public/PublicLeadForm'));
const WebChatWidget = React.lazy(() => import('./components/public/WebChatWidget'));
const ProfileDropdown = React.lazy(() => import('./components/ProfileDropdown'));
const BlogGoogleSheetsWhatsApp = React.lazy(() => import('./components/blog/BlogGoogleSheetsWhatsApp'));

const PageLoader = () => (
    <div className="min-h-screen flex items-center justify-center bg-[#0c1427] text-white">
        <div className="animate-spin w-8 h-8 border-4 border-teal-500 border-t-transparent rounded-full"></div>
    </div>
);

// Simple router based on pathname
function AppRoutes({ installPrompt, onInstall }: { installPrompt: any, onInstall: () => void }) {
    const { path } = useRouter();
    const pathname = path.split('?')[0];

    // Lazy load routes inside Suspense
    return (
        <Suspense fallback={<PageLoader />}>
            {(() => {
                if (pathname === '/google-callback') return <GoogleCallback />;
                if (pathname === '/privacy-policy') return <PrivacyPolicyPage />;
                if (pathname === '/terms-of-service') return <TermsOfServicePage />;
                if (pathname === '/pricing') return <PricingPage />;
                if (pathname === '/docs') return <DocumentationPage />;
                if (pathname === '/blog/whatsapp-google-sheets-sync') return <BlogGoogleSheetsWhatsApp />;
                if (pathname.startsWith('/p/')) return <PublicLeadForm />;
                if (pathname.startsWith('/embed/chat/')) return <WebChatWidget />;
                if (pathname.startsWith('/app')) return <div className="themed-background min-h-screen"><AppContent installPrompt={installPrompt} onInstall={onInstall} /></div>;
                return <PublicHomePage />;
            })()}
        </Suspense>
    );
}

function AppContent({ installPrompt, onInstall }: { installPrompt: any, onInstall: () => void }) {
    const [currentUser, setCurrentUser] = useState<User | null>(null);
    const [authView, setAuthView] = useState<'login' | 'register' | 'forgot'>('login');
    const [isLoading, setIsLoading] = useState(true);
    const [connectionError, setConnectionError] = useState<string | null>(null);
    const [googleClientId, setGoogleClientId] = useState<string | null>(null);
    const [isImpersonating, setIsImpersonating] = useState(!!localStorage.getItem('admin_return_token'));
    const [verificationMessage, setVerificationMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null);
    const { path, navigate } = useRouter();
    const refreshedRef = useRef(false);
    
    const pathname = path.split('?')[0];

    const onUserRefresh = useCallback(async () => {
        try {
            const user = await authService.verifySession();
            setCurrentUser(user);
        } catch (error) {
            console.error("Failed to refresh user session:", error);
            setCurrentUser(null);
            setIsImpersonating(false);
            localStorage.removeItem('admin_return_token');
            localStorage.removeItem('whatsapp_sender_token');
        }
    }, []);

    // Effect for initial app load: fetch config AND verify session
    useEffect(() => {
        const initializeApp = async () => {
            setIsLoading(true);
            
            // Initialize reCAPTCHA on load to satisfy "Request tokens" requirement
            loadRecaptcha();

            try {
                const backendUrl = getBackendUrl();
                if (!backendUrl) {
                    throw new Error("Backend URL has not been configured. Please edit the BACKEND_URL constant in `services/api` to point to your deployed backend service.");
                }

                const config = await authService.getAppConfig();
                setGoogleClientId(config.googleClientId);
                
                // Verification Logic
                const params = new URLSearchParams(window.location.hash.split('?')[1]);
                const verifyToken = params.get('verify_token');

                if (verifyToken) {
                    try {
                        const res = await authService.verifyEmail(verifyToken);
                        setVerificationMessage({ type: 'success', text: res.message || 'Email verified successfully! Please log in.' });
                        // Clean URL to remove token
                        window.history.replaceState(null, '', window.location.pathname + window.location.hash.split('?')[0]);
                        // Ensure login view is shown
                        setAuthView('login');
                    } catch (err: any) {
                        setVerificationMessage({ type: 'error', text: err.message || 'Verification failed. The link may be expired.' });
                    }
                }

                const user = await authService.verifySession();
                setCurrentUser(user);

                // Check impersonation status after verifying session
                setIsImpersonating(!!localStorage.getItem('admin_return_token'));
                setConnectionError(null);
            } catch (error: any) {
                console.error("App Initialization Failed:", error);
                if (error.message.includes("Backend URL has not been configured")) {
                    setConnectionError(error.message);
                } else if (error instanceof TypeError || error.message.includes('fetch')) {
                    setConnectionError("Could not connect to the backend. Please ensure the backend service is running, accessible, and the URL in `services/api` is correct.");
                } else {
                    setCurrentUser(null);
                    setIsImpersonating(false);
                    localStorage.removeItem('admin_return_token');
                }
            } finally {
                setIsLoading(false);
            }
        };

        initializeApp();
    }, []);

    useEffect(() => {
        const params = new URLSearchParams(window.location.search);
        const needsRefresh = params.get('refresh_user') === 'true';

        if (needsRefresh && !refreshedRef.current) {
            refreshedRef.current = true;
            onUserRefresh();
            window.history.replaceState({}, document.title, window.location.pathname);
        }
    }, [onUserRefresh]);


    const handleLoginSuccess = useCallback((user: User) => {
        setCurrentUser(user);
        
        // Handle post-login redirection
        // Check hash for query params since we use hash routing
        const hashPath = window.location.hash.substring(1); // e.g., /app?redirect=pricing
        const queryIndex = hashPath.indexOf('?');
        
        if (queryIndex !== -1) {
            const search = hashPath.substring(queryIndex);
            const params = new URLSearchParams(search);
            const redirect = params.get('redirect');
            if (redirect === 'pricing') {
                navigate('/pricing');
                return;
            }
        }
        
        // Fallback check on window.location.search just in case
        const searchParams = new URLSearchParams(window.location.search);
        if (searchParams.get('redirect') === 'pricing') {
             navigate('/pricing');
             return;
        }

        if (user.role === 'admin') {
            navigate('/app/admin');
        } else {
            navigate('/app');
        }
    }, [navigate]);

    const handleReturnToAdmin = useCallback(() => {
        const adminToken = localStorage.getItem('admin_return_token');
        if (adminToken) {
            localStorage.setItem('whatsapp_sender_token', adminToken);
            localStorage.removeItem('admin_return_token');
            // By doing a full navigation and reload, we bypass component state issues
            // and let the initial auth check correctly identify the admin user.
            window.location.hash = '/app/admin';
            window.location.reload();
        }
    }, []);

    useEffect(() => {
        if (!currentUser) return;

        const isOnAdminPath = pathname.startsWith('/app/admin');

        if (currentUser.role === 'admin' && !isImpersonating) {
            // Allow admin to access both /app and /app/admin
        } else { // Regular user OR impersonating admin
            if (isOnAdminPath) {
                navigate('/app');
            }
            
            // --- AGENT REDIRECT LOGIC ---
            // If the user is an 'agent' or 'manager' (not an owner) and they land on the root /app (dashboard),
            // redirect them immediately to the inbox.
            const isRestrictedRole = currentUser.orgRole === 'agent' || currentUser.orgRole === 'manager';
            if (isRestrictedRole && (pathname === '/app' || pathname === '/app/')) {
                navigate('/app/inbox');
            }
        }
    }, [currentUser, isImpersonating, pathname, navigate]);

    const handleLogout = useCallback(() => {
        authService.logout();
        localStorage.removeItem('admin_return_token'); // Clear impersonation on logout
        setCurrentUser(null);
        setAuthView('login');
        setIsImpersonating(false);
        navigate('/');
    }, [navigate]);

    const renderAuthView = () => {
        switch (authView) {
            case 'register':
                return <Register onLoginSuccess={handleLoginSuccess} onShowLogin={() => setAuthView('login')} googleClientId={googleClientId} />;
            case 'forgot':
                return <ForgotPassword onShowLogin={() => setAuthView('login')} />;
            case 'login':
            default:
                return (
                    <Login 
                        onLoginSuccess={handleLoginSuccess} 
                        onShowRegister={() => setAuthView('register')} 
                        onShowForgotPassword={() => setAuthView('forgot')}
                        googleClientId={googleClientId}
                    />
                );
        }
    };

    if (isLoading) {
        return <PageLoader />;
    }

    if (connectionError) {
        return <div className="min-h-screen flex items-center justify-center text-red-400 p-4 text-center">{connectionError}</div>;
    }

    if (!currentUser) {
        return (
            <AuthContainer>
                 {verificationMessage && (
                    <div className={`mb-6 p-4 rounded-lg border text-sm font-medium ${verificationMessage.type === 'success' ? 'bg-green-500/10 border-green-500/30 text-green-300' : 'bg-red-500/10 border-red-500/30 text-red-300'}`}>
                        {verificationMessage.text}
                    </div>
                )}
                {renderAuthView()}
            </AuthContainer>
        );
    }

    if (currentUser.role === 'admin' && !isImpersonating && pathname.startsWith('/app/admin')) {
        return <AdminPanel user={currentUser} onLogout={handleLogout} />;
    }

    // LeadGenView Routing Logic inside AppContent to handle the 'Growth Tools' view
    if (pathname.startsWith('/app/lead-gen')) {
        return (
            <div className="flex h-screen bg-[#030712] text-gray-200 overflow-hidden">
                <div className="flex-1 flex flex-col min-w-0">
                    <header className="bg-transparent flex-shrink-0 border-b border-white/5 backdrop-blur-sm bg-black/10 relative z-30">
                        <div className="container mx-auto px-4 sm:px-6 lg:px-8 py-3 flex items-center justify-between">
                            <div className="flex items-center space-x-4">
                                <a href="#/app" onClick={(e) => { e.preventDefault(); navigate('/app');}} className="text-xl font-bold text-white tracking-tight">Bytecohort Reach</a>
                            </div>
                            <div className="flex items-center space-x-4">
                                <button onClick={() => navigate('/app')} className="text-sm text-gray-300 hover:text-white">Dashboard</button>
                                <ProfileDropdown 
                                    user={currentUser} 
                                    onLogout={handleLogout} 
                                    installPrompt={installPrompt} 
                                    onInstall={onInstall} 
                                />
                            </div>
                        </div>
                    </header>
                    <main className="flex-1 min-h-0 relative overflow-hidden flex flex-col">
                        <LeadGenView onBack={() => navigate('/app')} />
                    </main>
                </div>
            </div>
        );
    }

    return (
        <MainApp 
            user={currentUser} 
            onLogout={handleLogout} 
            onUserRefresh={onUserRefresh}
            isImpersonating={isImpersonating}
            onReturnToAdmin={handleReturnToAdmin}
            installPrompt={installPrompt}
            onInstall={onInstall}
        />
    );
}

export default function App() {
    const [installPrompt, setInstallPrompt] = useState<any>(null);

    useEffect(() => {
        const handleBeforeInstallPrompt = (e: any) => {
            e.preventDefault();
            setInstallPrompt(e);
        };

        window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);

        return () => {
            window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
        };
    }, []);

    const handleInstall = async () => {
        if (!installPrompt) return;
        installPrompt.prompt();
        const { outcome } = await installPrompt.userChoice;
        if (outcome === 'accepted') {
            setInstallPrompt(null);
        }
    };

    return (
        <Router>
            <AppRoutes installPrompt={installPrompt} onInstall={handleInstall} />
        </Router>
    );
}


