<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Callback Hell Demo</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                max-width: 900px;
                margin: 0 auto;
                padding: 20px;
                background-color: #f5f5f5;
            }
            .demo-section {
                background-color: white;
                border-radius: 8px;
                padding: 20px;
                margin-bottom: 20px;
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }
            h2 {
                color: #333;
                margin-top: 0;
            }
            .code-block {
                background-color: #f8f9fa;
                border: 1px solid #e9ecef;
                border-radius: 4px;
                padding: 15px;
                font-family: 'Courier New', monospace;
                font-size: 14px;
                overflow-x: auto;
            }
            button {
                background-color: #007bff;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 4px;
                cursor: pointer;
                margin-right: 10px;
                margin-bottom: 10px;
            }
            button:hover {
                background-color: #0056b3;
            }
            .output {
                background-color: #f8f9fa;
                border: 1px solid #dee2e6;
                border-radius: 4px;
                padding: 15px;
                margin-top: 15px;
                min-height: 100px;
                white-space: pre-wrap;
            }
            .loading {
                color: #666;
                font-style: italic;
            }
            .error {
                color: #dc3545;
            }
            .success {
                color: #28a745;
            }
            .comparison {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 20px;
                margin-top: 20px;
            }
            @media (max-width: 768px) {
                .comparison {
                    grid-template-columns: 1fr;
                }
            }
            .comparison-box {
                background-color: #f8f9fa;
                padding: 15px;
                border-radius: 4px;
                border: 2px solid #dee2e6;
            }
            .comparison-box h3 {
                margin-top: 0;
                color: #495057;
            }
            .bad {
                border-color: #dc3545;
            }
            .good {
                border-color: #28a745;
            }
        </style>
    </head>
    <body>
        <h1>Understanding Callback Hell</h1>
        <div class="demo-section">
            <h2>Scenario: Loading User Dashboard</h2>
            <p>We need to:</p>
            <ol>
                <li>Get user ID from authentication</li>
                <li>Fetch user details using that ID</li>
                <li>Get user's posts</li>
                <li>Get comments for the latest post</li>
                <li>Get likes for that post</li>
            </ol>
            <button onclick="loadWithCallbackHell()">Load with Callback Hell 😱</button>
            <button onclick="loadWithPromises()">Load with Promises 👍</button>
            <button onclick="loadWithAsyncAwait()">Load with Async/Await 🌟</button>
            <div id="output" class="output"></div>
        </div>
        <div class="demo-section">
            <h2>Code Comparison</h2>
            <div class="comparison">
                <div class="comparison-box bad">
                    <h3>❌ Callback Hell</h3>
                    <pre class="code-block">
    getUserId(function(userId) {
        getUserDetails(userId, function(user) {
            getUserPosts(user.id, function(posts) {
                getPostComments(posts[0].id, function(comments) {
                    getPostLikes(posts[0].id, function(likes) {
                        // Finally display everything
                        displayDashboard(user, posts, comments, likes);
                    }, function(error) {
                        handleError(error);
                    });
                }, function(error) {
                    handleError(error);
                });
            }, function(error) {
                handleError(error);
            });
        }, function(error) {
            handleError(error);
        });
    }, function(error) {
        handleError(error);
    });
                    </pre>
                </div>
                <div class="comparison-box good">
                    <h3>✅ Async/Await</h3>
                    <pre class="code-block">
    try {
        const userId = await getUserId();
        const user = await getUserDetails(userId);
        const posts = await getUserPosts(user.id);
        const comments = await getPostComments(posts[0].id);
        const likes = await getPostLikes(posts[0].id);
        
        displayDashboard(user, posts, comments, likes);
    } catch (error) {
        handleError(error);
    }
                    </pre>
                </div>
            </div>
        </div>
        <div class="demo-section">
            <h2>Problems with Callback Hell</h2>
            <ul>
                <li><strong>Poor Readability:</strong> Code flows right and down instead of top to bottom</li>
                <li><strong>Error Handling:</strong> Need to handle errors at every level</li>
                <li><strong>Debugging Difficulty:</strong> Hard to set breakpoints and trace execution</li>
                <li><strong>Code Reusability:</strong> Difficult to reuse or refactor nested callbacks</li>
                <li><strong>Maintenance:</strong> Adding new steps or changing order is painful</li>
            </ul>
        </div>
        <script>
            const output = document.getElementById('output');
            // Simulate async operations with delays
            function simulateAsync(data, delay, callback, errorCallback) {
                output.innerHTML += `<span class="loading">Loading ${data.type}...</span>\n`;
                setTimeout(() => {
                    // Simulate occasional errors
                    if (Math.random() > 0.9) {
                        errorCallback(`Failed to load ${data.type}`);
                    } else {
                        callback(data.result);
                    }
                }, delay);
            }
            // CALLBACK HELL EXAMPLE
            function loadWithCallbackHell() {
                output.innerHTML = '<h3>Loading with Callback Hell...</h3>\n';
                // Get User ID
                simulateAsync(
                    { type: 'User ID', result: { id: 12345 } },
                    1000,
                    function (result) {
                        output.innerHTML += `<span class="success">✓ Got User ID: ${result.id}</span>\n`;
                        // Get User Details
                        simulateAsync(
                            { type: 'User Details', result: { id: result.id, name: 'John Doe', email: 'john@example.com' } },
                            800,
                            function (user) {
                                output.innerHTML += `<span class="success">✓ Got User: ${user.name}</span>\n`;
                                // Get User Posts
                                simulateAsync(
                                    {
                                        type: 'User Posts', result: [
                                            { id: 1, title: 'My First Post', date: '2024-01-15' },
                                            { id: 2, title: 'Another Post', date: '2024-01-20' }
                                        ]
                                    },
                                    600,
                                    function (posts) {
                                        output.innerHTML += `<span class="success">✓ Got ${posts.length} posts</span>\n`;
                                        // Get Comments for latest post
                                        simulateAsync(
                                            {
                                                type: 'Post Comments', result: [
                                                    { author: 'Alice', text: 'Great post!' },
                                                    { author: 'Bob', text: 'Thanks for sharing' }
                                                ]
                                            },
                                            700,
                                            function (comments) {
                                                output.innerHTML += `<span class="success">✓ Got ${comments.length} comments</span>\n`;
                                                // Get Likes for post
                                                simulateAsync(
                                                    { type: 'Post Likes', result: { count: 42, users: ['Alice', 'Bob', 'Charlie'] } },
                                                    500,
                                                    function (likes) {
                                                        output.innerHTML += `<span class="success">✓ Got ${likes.count} likes</span>\n`;
                                                        output.innerHTML += '\n<strong>Dashboard Loaded Successfully!</strong>\n';
                                                        output.innerHTML += `User: ${user.name}\nPosts: ${posts.length}\nLatest Post: "${posts[0].title}"\nComments: ${comments.length}\nLikes: ${likes.count}`;
                                                    },
                                                    function (error) {
                                                        output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                                                    }
                                                );
                                            },
                                            function (error) {
                                                output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                                            }
                                        );
                                    },
                                    function (error) {
                                        output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                                    }
                                );
                            },
                            function (error) {
                                output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                            }
                        );
                    },
                    function (error) {
                        output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                    }
                );
            }
            // PROMISE-BASED SOLUTION
            function simulateAsyncPromise(data, delay) {
                output.innerHTML += `<span class="loading">Loading ${data.type}...</span>\n`;
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        if (Math.random() > 0.9) {
                            reject(`Failed to load ${data.type}`);
                        } else {
                            resolve(data.result);
                        }
                    }, delay);
                });
            }
            function loadWithPromises() {
                output.innerHTML = '<h3>Loading with Promises...</h3>\n';
                simulateAsyncPromise({ type: 'User ID', result: { id: 12345 } }, 1000)
                    .then(result => {
                        output.innerHTML += `<span class="success">✓ Got User ID: ${result.id}</span>\n`;
                        return simulateAsyncPromise({
                            type: 'User Details',
                            result: { id: result.id, name: 'John Doe', email: 'john@example.com' }
                        }, 800);
                    })
                    .then(user => {
                        output.innerHTML += `<span class="success">✓ Got User: ${user.name}</span>\n`;
                        window.tempUser = user; // Store for later use
                        return simulateAsyncPromise({
                            type: 'User Posts',
                            result: [
                                { id: 1, title: 'My First Post', date: '2024-01-15' },
                                { id: 2, title: 'Another Post', date: '2024-01-20' }
                            ]
                        }, 600);
                    })
                    .then(posts => {
                        output.innerHTML += `<span class="success">✓ Got ${posts.length} posts</span>\n`;
                        window.tempPosts = posts;
                        return simulateAsyncPromise({
                            type: 'Post Comments',
                            result: [
                                { author: 'Alice', text: 'Great post!' },
                                { author: 'Bob', text: 'Thanks for sharing' }
                            ]
                        }, 700);
                    })
                    .then(comments => {
                        output.innerHTML += `<span class="success">✓ Got ${comments.length} comments</span>\n`;
                        window.tempComments = comments;
                        return simulateAsyncPromise({
                            type: 'Post Likes',
                            result: { count: 42, users: ['Alice', 'Bob', 'Charlie'] }
                        }, 500);
                    })
                    .then(likes => {
                        output.innerHTML += `<span class="success">✓ Got ${likes.count} likes</span>\n`;
                        output.innerHTML += '\n<strong>Dashboard Loaded Successfully!</strong>\n';
                        output.innerHTML += `User: ${window.tempUser.name}\nPosts: ${window.tempPosts.length}\nLatest Post: "${window.tempPosts[0].title}"\nComments: ${window.tempComments.length}\nLikes: ${likes.count}`;
                    })
                    .catch(error => {
                        output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                    });
            }
            // ASYNC/AWAIT SOLUTION
            async function loadWithAsyncAwait() {
                output.innerHTML = '<h3>Loading with Async/Await...</h3>\n';
                try {
                    const userId = await simulateAsyncPromise({ type: 'User ID', result: { id: 12345 } }, 1000);
                    output.innerHTML += `<span class="success">✓ Got User ID: ${userId.id}</span>\n`;
                    const user = await simulateAsyncPromise({
                        type: 'User Details',
                        result: { id: userId.id, name: 'John Doe', email: 'john@example.com' }
                    }, 800);
                    output.innerHTML += `<span class="success">✓ Got User: ${user.name}</span>\n`;
                    const posts = await simulateAsyncPromise({
                        type: 'User Posts',
                        result: [
                            { id: 1, title: 'My First Post', date: '2024-01-15' },
                            { id: 2, title: 'Another Post', date: '2024-01-20' }
                        ]
                    }, 600);
                    output.innerHTML += `<span class="success">✓ Got ${posts.length} posts</span>\n`;
                    const comments = await simulateAsyncPromise({
                        type: 'Post Comments',
                        result: [
                            { author: 'Alice', text: 'Great post!' },
                            { author: 'Bob', text: 'Thanks for sharing' }
                        ]
                    }, 700);
                    output.innerHTML += `<span class="success">✓ Got ${comments.length} comments</span>\n`;
                    const likes = await simulateAsyncPromise({
                        type: 'Post Likes',
                        result: { count: 42, users: ['Alice', 'Bob', 'Charlie'] }
                    }, 500);
                    output.innerHTML += `<span class="success">✓ Got ${likes.count} likes</span>\n`;
                    output.innerHTML += '\n<strong>Dashboard Loaded Successfully!</strong>\n';
                    output.innerHTML += `User: ${user.name}\nPosts: ${posts.length}\nLatest Post: "${posts[0].title}"\nComments: ${comments.length}\nLikes: ${likes.count}`;
                } catch (error) {
                    output.innerHTML += `<span class="error">✗ ${error}</span>\n`;
                }
            }
        </script>
    </body>
    </html>