import React, { useState, useEffect } from "react";
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Link,
    useParams,
} from "react-router-dom";
import DOMPurify from "dompurify";
import { AuthProvider, useAuth } from "./contexts/AuthContext";
import { ThemeProvider } from "./contexts/ThemeContext";
// Lazy load components for performance
const AdminDashboard = React.lazy(() => import("./components/AdminDashboard"));
const PostEditor = React.lazy(() => import("./components/PostEditor"));
const LoginForm = React.lazy(() => import("./components/LoginForm"));
const ThemesManager = React.lazy(() => import("./components/ThemesManager"));
const ThemeEditor = React.lazy(() => import("./components/ThemeEditor"));
const MediaManager = React.lazy(() => import("./components/MediaManager"));

import ProtectedRoute from "./components/ProtectedRoute";
import { createMarkdownParser } from "./utils/markdownParser";
import { API_BASE } from "./config";

// Initialize the shared markdown parser
const md = createMarkdownParser();

// Loading Fallback Component
const LoadingSpinner = () => (
    <div className="flex justify-center items-center p-12">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 theme-primary"></div>
    </div>
);


// Lightbox Component
const Lightbox = ({ src, alt, onClose }) => {
    if (!src) return null;

    return (
        <div className="lightbox-overlay" onClick={onClose}>
            <span className="lightbox-close" onClick={onClose}>
                &times;
            </span>
            <img
                src={src}
                alt={alt}
                className="lightbox-content"
                onClick={(e) => e.stopPropagation()} // Prevent closing when clicking the image
            />
        </div>
    );
};

// Navigation Header Component
function NavHeader() {
    const { isAdmin, user, logout } = useAuth();

    const handleLogout = async () => {
        await logout();
    };

    return (
        <header className="headercontainer py-6 border-b theme-border flex items-center justify-between">
            <div className="text-2xl font-bold theme-text">
                <Link to="/">
                    <span className="theme-primary">Goon</span>Blog
                </Link>
            </div>
            <nav>
                <ul className="flex space-x-4 items-center">
                    <li>
                        <Link
                            to="/"
                            className="theme-text-secondary hover:theme-text transition-colors duration-200 font-medium"
                        >
                            Home
                        </Link>
                    </li>
                    {isAdmin && (
                        <li>
                            <Link
                                to="/admin"
                                className="theme-primary hover:theme-secondary transition-colors duration-200 font-medium"
                            >
                                Admin
                            </Link>
                        </li>
                    )}
                    {user ? (
                        <li className="flex items-center space-x-2">
                            <span className="text-sm theme-text-secondary">
                                Welcome, {user.username}
                            </span>
                            <button
                                onClick={handleLogout}
                                className="text-red-600 hover:text-red-800 transition-colors duration-200 font-medium text-sm"
                            >
                                Logout
                            </button>
                        </li>
                    ) : (
                        <li>
                            <Link
                                to="/login"
                                className="theme-primary hover:theme-secondary transition-colors duration-200 font-medium"
                            >
                                Login
                            </Link>
                        </li>
                    )}
                </ul>
            </nav>
        </header>
    );
}

// Layout ComponentWrapper
const Layout = ({ children }) => (
    <div className="min-h-screen theme-bg font-sans theme-text antialiased flex flex-col">
        <div className="max-w-5xl mx-auto w-full flex-grow">
            <NavHeader />
            <main className="py-10 px-4 sm:px-6 lg:px-8">
                {children}
            </main>
        </div>
    </div>
);

// Skeleton Components
const SkeletonCard = () => (
    <div className="theme-surface border theme-border rounded-xl p-6 flex flex-col h-full animate-pulse">
        <div className="h-6 bg-gray-200 dark:bg-gray-700 rounded w-3/4 mb-4"></div>
        <div className="space-y-2 flex-grow">
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-full"></div>
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-5/6"></div>
        </div>
        <div className="mt-4 h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/4"></div>
    </div>
);

const SkeletonPost = () => (
    <div className="w-full animate-pulse">
        <div className="theme-surface border theme-border rounded-xl p-8 md:p-12 lg:p-16">
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-32 mb-6"></div>
            <div className="mb-8">
                <div className="h-10 bg-gray-200 dark:bg-gray-700 rounded w-3/4 mb-4"></div>
                <div className="h-6 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
            </div>
            <hr className="theme-border mb-8" />
            <div className="space-y-4">
                <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-full"></div>
                <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-full"></div>
                <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-5/6"></div>
                <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-full"></div>
                <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-4/5"></div>
            </div>
        </div>
    </div>
);

// Blog Home Component
function BlogHome() {
    const [posts, setPosts] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        async function getTingyun() {
            setLoading(true);
            try {
                const response = await fetch(`${API_BASE}/posts`);
                if (!response.ok)
                    throw new Error(
                        `Failed to fetch posts: ${response.statusText}`,
                    );
                const postsData = await response.json();
                setPosts(postsData);
            } catch (e) {
                console.error("Error fetching posts:", e);
                setError(
                    "Failed to load posts. Please check if the backend server is running.",
                );
            } finally {
                setLoading(false);
            }
        }
        getTingyun();
    }, []);

    if (loading) {
        return (
            <Layout>
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    {[1, 2, 3, 4, 5, 6].map((i) => (
                        <SkeletonCard key={i} />
                    ))}
                </div>
            </Layout>
        );
    }

    if (error) {
        return (
            <Layout>
                <div className="text-center">
                    <div className="bg-red-50 border border-red-200 rounded-lg p-6 inline-block">
                        <h2 className="text-red-800 font-semibold mb-2">
                            Error
                        </h2>
                        <p className="text-red-600">{error}</p>
                    </div>
                </div>
            </Layout>
        );
    }

    return (
        <Layout>
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                {posts.map((post) => (
                    <div
                        key={post.slug}
                        className="group cursor-pointer theme-surface border theme-border rounded-xl hover:border-blue-400 transition-colors duration-200 p-6 flex flex-col justify-between h-full"
                    >
                        <div>
                            <h2 className="text-xl font-semibold theme-text group-hover:theme-primary transition-colors duration-200 mb-2">
                                <Link to={`/posts/${post.slug}`}>
                                    {post.title}
                                </Link>
                            </h2>
                        </div>
                        <div className="flex-grow mt-4">
                            <div className="theme-text-secondary leading-relaxed">
                                {post.description}
                            </div>
                        </div>
                        <div className="mt-4">
                            <Link
                                to={`/posts/${post.slug}`}
                                className="theme-primary font-medium hover:underline focus:outline-none"
                            >
                                Read more →
                            </Link>
                        </div>
                    </div>
                ))}
            </div>
        </Layout>
    );
}

// Post View Component
function PostView({ onImageClick }) {
    const { slug } = useParams();
    const [post, setPost] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        async function fetchPost() {
            try {
                setLoading(true);
                const response = await fetch(`${API_BASE}/posts/${slug}`);
                if (!response.ok) throw new Error("Post not found");
                const postData = await response.json();
                setPost(postData);

                // Update document title
                document.title = postData.title || "GoonBlog";
            } catch (e) {
                console.error("Error fetching post:", e);
                setError(e.message);
            } finally {
                setLoading(false);
            }
        }

        if (slug) {
            fetchPost();
        }
    }, [slug]);

    useEffect(() => {
        if (post) {
            const setMeta = (name, content) => {
                let element = document.querySelector(`meta[name="${name}"]`);
                if (!element) {
                    element = document.createElement("meta");
                    element.setAttribute("name", name);
                    document.head.appendChild(element);
                }
                element.setAttribute("content", content);
            };

            setMeta("og:title", post.title);
            setMeta("og:description", post.description);
            setMeta("og:type", "article");
            setMeta("og:url", window.location.href);
            setMeta("twitter:title", post.title);
            setMeta("twitter:description", post.description);
            setMeta("twitter:card", "summary");
            setMeta("twitter:url", window.location.href);
        }

        return () => {
            const metaTags = [
                "og:title",
                "og:description",
                "og:type",
                "og:url",
                "og:image",
                "twitter:title",
                "twitter:description",
                "twitter:card",
                "twitter:url",
                "twitter:image",
            ];
            metaTags.forEach((name) => {
                const element = document.querySelector(`meta[name="${name}"]`);
                if (element) {
                    element.remove();
                }
            });
        };
    }, [post]);

    useEffect(() => {
        // Reset title when component unmounts
        return () => {
            document.title = "GoonBlog - A Retard's Thoughts";
        };
    }, []);

    // Effect to handle interactions (Comparison Slider, Zoom Reel & Lightbox)
    useEffect(() => {
        if (!post) return;

        // 1. Handle Comparison Sliders (Updated to use clip-path)
        const sliders = document.querySelectorAll(".comparison-slider");

        const handleSliderInput = (e) => {
            const container = e.target.closest(".comparison-wrapper");
            const topImage = container.querySelector(".comparison-top");
            const handle = container.querySelector(".slider-handle");
            const val = e.target.value;

            // Use clip-path inset(top right bottom left)
            // We want to clip the right side based on the slider value.
            // If slider is at 50%, we want to show 50% of the image from the left.
            // So we clip 50% from the right.
            // Inset right value = 100 - val
            if (topImage) topImage.style.clipPath = `inset(0 ${100 - val}% 0 0)`;
            if (handle) handle.style.left = `${val}%`;
        };

        sliders.forEach(slider => {
            slider.addEventListener("input", handleSliderInput);
        });

        // 2. Handle Zoom Reels
        const zoomReels = document.querySelectorAll(".interactive-zoom-reel");
        const cleanupZoomReels = []; // To store cleanup functions for each reel

        zoomReels.forEach(reel => {
            const images = reel.querySelectorAll(".zoom-reel-img");
            const viewports = reel.querySelectorAll(".zoom-reel-viewport");
            const slider = reel.querySelector(".zoom-slider");
            const resetBtn = reel.querySelector(".reset-zoom");

            let state = {
                zoom: 1,
                panX: 0,
                panY: 0,
                isDragging: false,
                startX: 0,
                startY: 0,
                initialPanX: 0,
                initialPanY: 0
            };

            const updateTransform = () => {
                images.forEach(img => {
                    img.style.transform = `translate(${state.panX}px, ${state.panY}px) scale(${state.zoom})`;
                });
            };

            const handleZoomInput = (e) => {
                state.zoom = parseFloat(e.target.value);
                // Reset pan if zoom is 1
                if (state.zoom === 1) {
                    state.panX = 0;
                    state.panY = 0;
                }
                updateTransform();
            };

            const handleReset = () => {
                state.zoom = 1;
                state.panX = 0;
                state.panY = 0;
                if (slider) slider.value = 1;
                updateTransform();
            };

            // Drag Logic for Viewports
            const handleMouseDown = (e) => {
                if (state.zoom <= 1) return; // Only pan if zoomed in
                e.preventDefault(); // Prevent standard drag
                state.isDragging = true;
                state.startX = e.clientX;
                state.startY = e.clientY;
                state.initialPanX = state.panX;
                state.initialPanY = state.panY;

                viewports.forEach(vp => vp.style.cursor = "grabbing");
            };

            const handleMouseMove = (e) => {
                if (!state.isDragging) return;
                e.preventDefault();
                const dx = e.clientX - state.startX;
                const dy = e.clientY - state.startY;
                state.panX = state.initialPanX + dx;
                state.panY = state.initialPanY + dy;
                updateTransform();
            };

            const handleMouseUp = () => {
                state.isDragging = false;
                viewports.forEach(vp => vp.style.cursor = "grab");
            };

            if (slider) slider.addEventListener("input", handleZoomInput);
            if (resetBtn) resetBtn.addEventListener("click", handleReset);

            viewports.forEach(vp => {
                vp.addEventListener("mousedown", handleMouseDown);
            });
            // We listen to document for move/up to handle drag going outside viewport
            document.addEventListener("mousemove", handleMouseMove);
            document.addEventListener("mouseup", handleMouseUp);

            cleanupZoomReels.push(() => {
                if (slider) slider.removeEventListener("input", handleZoomInput);
                if (resetBtn) resetBtn.removeEventListener("click", handleReset);
                viewports.forEach(vp => vp.removeEventListener("mousedown", handleMouseDown));
                document.removeEventListener("mousemove", handleMouseMove);
                document.removeEventListener("mouseup", handleMouseUp);
            });
        });

        // 3. Handle Lightbox clicks
        const lightboxImages = document.querySelectorAll(".markdown-content img");
        const handleImageClick = (e) => {
            // Ignore images inside comparison slider or zoom reel
            if (e.target.closest(".comparison-wrapper") || e.target.closest(".zoom-reel-container")) return;

            onImageClick(e.target.src, e.target.alt);
        };

        lightboxImages.forEach(img => {
            img.addEventListener("click", handleImageClick);
        });

        return () => {
            sliders.forEach(slider => {
                slider.removeEventListener("input", handleSliderInput);
            });
            lightboxImages.forEach(img => {
                img.removeEventListener("click", handleImageClick);
            });
            cleanupZoomReels.forEach(cleanup => cleanup());
        };
    }, [post, onImageClick]);

    if (loading) {
        return (
            <Layout>
                <SkeletonPost />
            </Layout>
        );
    }

    if (error || !post) {
        return (
            <Layout>
                <div className="text-center">
                    <h2 className="text-2xl font-bold theme-text mb-2">
                        Post Not Found
                    </h2>
                    <p className="theme-text-secondary mb-4">
                        {error || "The requested post could not be found."}
                    </p>
                    <Link
                        to="/"
                        className="theme-primary hover:theme-secondary font-medium"
                    >
                        ← Back to Home
                    </Link>
                </div>
            </Layout>
        );
    }

    const conceiveFoxFromSemen = (rawMarkdown) => {
        let processedText = rawMarkdown;
        let tags = null;
        let imageCredit = null;
        let imageSrc = null;
        let imageAlt = null;
        let customQuestion = null;

        const tagsRegex = /tags: (.*)/;
        const tagsMatch = processedText.match(tagsRegex);
        if (tagsMatch) {
            tags = tagsMatch[1].split(",").map((tag) => tag.trim());
            processedText = processedText.replace(tagsRegex, "").trim();
        }

        const imageRegex = /!\[(.*?)\]\((.*?)\)\n_Image credit: (.*?)_/;
        const imageMatch = processedText.match(imageRegex);
        if (imageMatch) {
            imageAlt = imageMatch[1];
            imageSrc = imageMatch[2];
            imageCredit = imageMatch[3];
            processedText = processedText.replace(imageRegex, "").trim();
        }

        const questionRegex = /\?\?\? "(.*?)"/;
        const questionMatch = processedText.match(questionRegex);
        if (questionMatch) {
            customQuestion = questionMatch[1];
            processedText = processedText.replace(questionRegex, "").trim();
        }
        processedText = processedText
            .replace(/^title:.*$/m, "")
            .replace(/^desc:.*$/m, "");
        return {
            processedText,
            tags,
            imageSrc,
            imageAlt,
            imageCredit,
            customQuestion,
        };
    };

    const { processedText } = conceiveFoxFromSemen(post.content);
    const htmlContent = md.render(processedText);
    const sanitizedHtml = DOMPurify.sanitize(htmlContent, {
        ADD_TAGS: ["input"], // Allow input tags for the slider
        ADD_ATTR: ["type", "min", "max", "value", "step", "checked"],
    });

    return (
        <Layout>
            <div className="w-full">
                <div className="theme-surface theme-text border theme-border rounded-xl p-8 md:p-12 lg:p-16">
                    <Link
                        to="/"
                        className="theme-text-secondary hover:theme-text transition-colors duration-200 mb-6 flex items-center"
                    >
                        ← Back to Home
                    </Link>

                    <div className="mb-8">
                        <h1 className="text-3xl md:text-4xl font-bold theme-text mb-2 leading-tight">
                            {post.title}
                        </h1>
                        <div className="text-lg italic font-light theme-text-secondary">
                            {post.description}
                        </div>
                    </div>

                    <hr className="theme-border mb-8" />

                    <div
                        className="markdown-content theme-text leading-relaxed text-lg"
                        dangerouslySetInnerHTML={{
                            __html: sanitizedHtml,
                        }}
                    />
                </div>
            </div>
        </Layout>
    );
}

function App() {
    const [lightboxOpen, setLightboxOpen] = useState(false);
    const [lightboxImage, setLightboxImage] = useState({ src: "", alt: "" });

    const openLightbox = (src, alt) => {
        setLightboxImage({ src, alt });
        setLightboxOpen(true);
    };

    const closeLightbox = () => {
        setLightboxOpen(false);
    };

    return (
        <Router>
            <AuthProvider>
                <ThemeProvider>
                    {lightboxOpen && (
                        <Lightbox
                            src={lightboxImage.src}
                            alt={lightboxImage.alt}
                            onClose={closeLightbox}
                        />
                    )}
                    <React.Suspense fallback={<LoadingSpinner />}>
                        <Routes>
                            <Route path="/" element={<BlogHome />} />
                            <Route path="/posts/:slug" element={<PostView onImageClick={openLightbox} />} />
                            <Route path="/login" element={<LoginForm />} />
                            <Route
                                path="/admin"
                                element={
                                    <ProtectedRoute>
                                        <AdminDashboard />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/post/new"
                                element={
                                    <ProtectedRoute>
                                        <PostEditor />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/post/:slug/edit"
                                element={
                                    <ProtectedRoute>
                                        <PostEditor />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/themes"
                                element={
                                    <ProtectedRoute>
                                        <ThemesManager />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/themes/new"
                                element={
                                    <ProtectedRoute>
                                        <ThemeEditor />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/themes/:themeId/edit"
                                element={
                                    <ProtectedRoute>
                                        <ThemeEditor />
                                    </ProtectedRoute>
                                }
                            />
                            <Route
                                path="/admin/media"
                                element={
                                    <ProtectedRoute>
                                        <MediaManager />
                                    </ProtectedRoute>
                                }
                            />
                        </Routes>
                    </React.Suspense>
                </ThemeProvider>
            </AuthProvider>
        </Router>
    );
}

export default App;
