import "./App.css";
import { useState } from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";

// Components
import {
    AnimatedBackground,
    ProjectThumb,
    CascadeItem,
    FadeContainer,
    ScrollArea,
} from "./components";

// Hooks
import {
    useSystemDarkMode,
    useGitHubReadme,
    useGitHubRepoImages,
} from "./hooks";

// Data
import { profile, featuredProjects, allProjects, skills } from "./data";

// Utils
import { stripHtmlFromMarkdown } from "./utils";

export default function PortfolioAboveTheFold() {
    const [active, setActive] = useState<number | null>(null);
    const [displayedProject, setDisplayedProject] = useState<number | null>(
        null,
    );
    const [isContentVisible, setIsContentVisible] = useState(true);
    const isDark = useSystemDarkMode();

    // Handle project selection with fade transition
    const handleProjectSelect = (projectId: number) => {
        if (projectId === active) return;

        // Start fade out
        setIsContentVisible(false);

        // After fade out completes, update the project and fade in
        setTimeout(() => {
            setActive(projectId);
            setDisplayedProject(projectId);
            // Small delay to ensure state is set before fading in
            requestAnimationFrame(() => {
                setIsContentVisible(true);
            });
        }, 200); // Match the fade-out duration
    };

    // Handle closing with fade transition
    const handleClose = () => {
        setIsContentVisible(false);
        setTimeout(() => {
            setActive(null);
            setDisplayedProject(null);
            requestAnimationFrame(() => {
                setIsContentVisible(true);
            });
        }, 200);
    };

    // Combine all projects for lookup
    const allProjectsList = [...featuredProjects, ...allProjects];

    // Get all repo URLs for fetching images
    const allRepos = allProjectsList.map((p) => p.repo);

    // Fetch README images for all repos (for thumbnails)
    const repoImages = useGitHubRepoImages(allRepos);

    // Get the active project's repo
    const activeProject = active
        ? allProjectsList.find((p) => p.id === active)
        : null;
    const activeRepo = activeProject?.repo || null;

    // Fetch README from GitHub for the active project
    const {
        content: readmeContent,
        isLoading: readmeLoading,
        error: readmeError,
        image: readmeImage,
    } = useGitHubReadme(activeRepo);

    return (
        <main className="h-screen w-full flex items-center justify-center p-6 overflow-hidden relative">
            <AnimatedBackground
                palette={activeProject?.palette}
                isDark={isDark}
            />
            <section className="relative max-w-[1100px] w-full h-[88vh] bg-white/60 dark:bg-slate-900/60 backdrop-blur-sm border border-white/60 dark:border-slate-700/60 rounded-2xl shadow-2xl p-6 grid grid-cols-2 gap-6 items-stretch">
                <ScrollArea className="min-h-0" scrollbarOffset={12}>
                    <div className="flex flex-col gap-4">
                        <div>
                            <p className="text-sm uppercase tracking-wide text-gray-500 dark:text-gray-400">
                                Hello, I'm
                            </p>
                            <h1 className="mt-2 text-[clamp(22px,3.6vw,40px)] leading-tight font-semibold text-gray-900 dark:text-white">
                                {profile.name}
                            </h1>
                            <p className="mt-1 text-[clamp(14px,1.6vw,18px)] text-gray-600 dark:text-gray-300">
                                {profile.role} • {profile.location}
                            </p>

                            <p className="mt-6 text-[clamp(13px,1.2vw,16px)] text-gray-700 dark:text-gray-300 max-w-[38ch]">
                                {profile.blurb}
                            </p>

                            <div className="mt-6 flex flex-wrap gap-3">
                                <a
                                    href={profile.cv}
                                    className="inline-flex items-center gap-2 rounded-md px-4 py-2 border border-gray-200 dark:border-slate-600 shadow-sm text-sm font-medium text-gray-900 dark:text-white hover:shadow hover:-translate-y-0.5 transition-transform"
                                >
                                    Download CV
                                </a>

                                <a
                                    href={`mailto:${profile.email}`}
                                    className="inline-flex items-center gap-2 rounded-md px-4 py-2 bg-gray-900 dark:bg-white text-white dark:text-gray-900 text-sm font-medium hover:opacity-95 transition-opacity"
                                >
                                    Contact
                                </a>
                            </div>
                        </div>

                        <div className="mt-2">
                            <h3 className="text-xs uppercase text-gray-500 dark:text-gray-400 tracking-wide">
                                Featured projects
                            </h3>

                            <div className="mt-3 grid grid-cols-2 gap-3">
                                {featuredProjects.map((p) => {
                                    const isActive = active === p.id;

                                    return (
                                        // Wrapper div creates the gradient border effect
                                        <div
                                            key={p.id}
                                            className="group relative rounded-lg p-[2px] transition-all duration-200 shadow-sm hover:shadow-md hover:-translate-y-0.5 bg-white dark:bg-slate-800"
                                        >
                                            {/* Gradient border layer - always present, opacity controlled */}
                                            <div
                                                aria-hidden
                                                className="absolute inset-0 rounded-lg transition-opacity duration-300 pointer-events-none"
                                                style={{
                                                    backgroundImage: p.gradient,
                                                    opacity: isActive ? 1 : 0,
                                                }}
                                            />
                                            <button
                                                onClick={() =>
                                                    handleProjectSelect(p.id)
                                                }
                                                className={`relative flex flex-col w-full rounded-[6px] overflow-hidden
                                            bg-white dark:bg-slate-800
                                            focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-indigo-500`}
                                                aria-expanded={isActive}
                                                type="button"
                                            >
                                                {/* Gradient overlay that covers the entire button; becomes visible on hover. */}
                                                <div
                                                    aria-hidden
                                                    className="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none rounded-[6px]"
                                                    style={{
                                                        backgroundImage:
                                                            p.gradient,
                                                    }}
                                                />

                                                {/* Slight dark layer to insure text contrast when gradient is visible */}
                                                <div
                                                    aria-hidden
                                                    className="absolute inset-0 bg-black/0 group-hover:bg-black/25 transition-colors duration-300 pointer-events-none rounded-[6px]"
                                                />

                                                {/* Image fills width */}
                                                <div className="relative z-10 w-full h-24 overflow-hidden">
                                                    <ProjectThumb
                                                        src={
                                                            (p.repo &&
                                                                repoImages[
                                                                    p.repo
                                                                ]) ||
                                                            p.image
                                                        }
                                                        alt={p.title}
                                                    />
                                                </div>

                                                {/* Text below image */}
                                                <div className="relative z-10 text-left p-2">
                                                    <div className="text-sm font-medium transition-colors duration-200 text-gray-900 dark:text-white group-hover:text-white">
                                                        {p.title}
                                                    </div>
                                                    <div className="text-xs transition-colors duration-200 text-gray-500 dark:text-gray-400 group-hover:text-gray-100 line-clamp-2">
                                                        {p.desc}
                                                    </div>
                                                </div>
                                            </button>
                                        </div>
                                    );
                                })}
                            </div>

                            <h3 className="mt-4 text-xs uppercase text-gray-500 dark:text-gray-400 tracking-wide">
                                All projects
                            </h3>

                            <div className="mt-3 grid grid-cols-2 gap-3">
                                {allProjects.map((p) => {
                                    const isActive = active === p.id;

                                    return (
                                        // Wrapper div creates the gradient border effect
                                        <div
                                            key={p.id}
                                            className="group relative rounded-lg p-[2px] transition-all duration-200 shadow-sm hover:shadow-md hover:-translate-y-0.5 bg-white dark:bg-slate-800"
                                        >
                                            {/* Gradient border layer - always present, opacity controlled */}
                                            <div
                                                aria-hidden
                                                className="absolute inset-0 rounded-lg transition-opacity duration-300 pointer-events-none"
                                                style={{
                                                    backgroundImage: p.gradient,
                                                    opacity: isActive ? 1 : 0,
                                                }}
                                            />
                                            <button
                                                onClick={() =>
                                                    handleProjectSelect(p.id)
                                                }
                                                className={`relative flex flex-col w-full rounded-[6px] overflow-hidden
                                            bg-white dark:bg-slate-800
                                            focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-indigo-500`}
                                                aria-expanded={isActive}
                                                type="button"
                                            >
                                                {/* Gradient overlay that covers the entire button; becomes visible on hover. */}
                                                <div
                                                    aria-hidden
                                                    className="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none rounded-[6px]"
                                                    style={{
                                                        backgroundImage:
                                                            p.gradient,
                                                    }}
                                                />

                                                {/* Slight dark layer to insure text contrast when gradient is visible */}
                                                <div
                                                    aria-hidden
                                                    className="absolute inset-0 bg-black/0 group-hover:bg-black/25 transition-colors duration-300 pointer-events-none rounded-[6px]"
                                                />

                                                {/* Image fills width */}
                                                <div className="relative z-10 w-full h-24 overflow-hidden">
                                                    <ProjectThumb
                                                        src={
                                                            (p.repo &&
                                                                repoImages[
                                                                    p.repo
                                                                ]) ||
                                                            p.image
                                                        }
                                                        alt={p.title}
                                                    />
                                                </div>

                                                {/* Text below image */}
                                                <div className="relative z-10 text-left p-2">
                                                    <div className="text-sm font-medium transition-colors duration-200 text-gray-900 dark:text-white group-hover:text-white">
                                                        {p.title}
                                                    </div>
                                                    <div className="text-xs transition-colors duration-200 text-gray-500 dark:text-gray-400 group-hover:text-gray-100 line-clamp-2">
                                                        {p.desc}
                                                    </div>
                                                </div>
                                            </button>
                                        </div>
                                    );
                                })}
                            </div>
                        </div>
                    </div>
                </ScrollArea>

                <div className="flex flex-col gap-4 min-h-0">
                    <div className="flex-1 bg-white dark:bg-slate-800 rounded-lg border border-gray-100 dark:border-slate-700 overflow-hidden">
                        <div className="w-full h-full flex items-center justify-center relative">
                            {/* Project detail view */}
                            <FadeContainer
                                isVisible={
                                    displayedProject !== null &&
                                    isContentVisible
                                }
                            >
                                {displayedProject && (
                                    <ScrollArea
                                        className="w-full h-full"
                                        scrollbarOffset={12}
                                    >
                                        <article>
                                            <CascadeItem
                                                delay={0}
                                                isVisible={isContentVisible}
                                            >
                                                <div className="w-full aspect-[4/3] rounded-lg overflow-hidden bg-gray-100 dark:bg-slate-700">
                                                    <ProjectThumb
                                                        src={
                                                            readmeImage ||
                                                            (allProjectsList.find(
                                                                (p) =>
                                                                    p.id ===
                                                                    displayedProject,
                                                            )?.image ??
                                                                "")
                                                        }
                                                        alt={
                                                            allProjectsList.find(
                                                                (p) =>
                                                                    p.id ===
                                                                    displayedProject,
                                                            )?.title ?? ""
                                                        }
                                                    />
                                                </div>
                                            </CascadeItem>

                                            <CascadeItem
                                                delay={75}
                                                isVisible={isContentVisible}
                                            >
                                                <div className="mt-4 flex items-start justify-between">
                                                    <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
                                                        {
                                                            allProjectsList.find(
                                                                (p) =>
                                                                    p.id ===
                                                                    displayedProject,
                                                            )?.title
                                                        }
                                                    </h2>
                                                    <button
                                                        onClick={handleClose}
                                                        className="text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
                                                    >
                                                        Close
                                                    </button>
                                                </div>
                                            </CascadeItem>

                                            <CascadeItem
                                                delay={150}
                                                isVisible={isContentVisible}
                                            >
                                                <div className="mt-3 flex flex-wrap gap-2">
                                                    {allProjectsList
                                                        .find(
                                                            (p) =>
                                                                p.id ===
                                                                displayedProject,
                                                        )
                                                        ?.tags.map((t, i) => (
                                                            <span
                                                                key={i}
                                                                className="text-xs px-2 py-1 bg-gray-100 dark:bg-slate-700 rounded-md text-gray-700 dark:text-gray-300"
                                                            >
                                                                {t}
                                                            </span>
                                                        ))}
                                                </div>
                                            </CascadeItem>

                                            <CascadeItem
                                                delay={225}
                                                isVisible={isContentVisible}
                                            >
                                                <div className="mt-4">
                                                    {readmeLoading && (
                                                        <div className="text-sm text-gray-500 dark:text-gray-400">
                                                            Loading README...
                                                        </div>
                                                    )}
                                                    {readmeError &&
                                                        !readmeLoading && (
                                                            <p className="text-sm text-gray-700 dark:text-gray-300">
                                                                {
                                                                    allProjectsList.find(
                                                                        (p) =>
                                                                            p.id ===
                                                                            displayedProject,
                                                                    )?.desc
                                                                }
                                                            </p>
                                                        )}
                                                    {readmeContent &&
                                                        !readmeLoading && (
                                                            <div className="prose prose-sm dark:prose-invert max-w-none text-gray-700 dark:text-gray-300">
                                                                <Markdown
                                                                    remarkPlugins={[
                                                                        remarkGfm,
                                                                    ]}
                                                                    components={{
                                                                        code: ({
                                                                            className,
                                                                            children,
                                                                            ...props
                                                                        }) => {
                                                                            // Check if this code is inside a pre (fenced code block)
                                                                            // by checking if className exists or if it's multi-line
                                                                            const isCodeBlock =
                                                                                className ||
                                                                                (typeof children ===
                                                                                    "string" &&
                                                                                    children.includes(
                                                                                        "\n",
                                                                                    ));

                                                                            if (
                                                                                isCodeBlock
                                                                            ) {
                                                                                return (
                                                                                    <code
                                                                                        className={`${className || ""} text-sm`}
                                                                                        {...props}
                                                                                    >
                                                                                        {
                                                                                            children
                                                                                        }
                                                                                    </code>
                                                                                );
                                                                            }
                                                                            // Inline code
                                                                            return (
                                                                                <code
                                                                                    className="bg-gray-200 dark:bg-slate-700 px-1.5 py-0.5 rounded text-sm font-mono"
                                                                                    {...props}
                                                                                >
                                                                                    {
                                                                                        children
                                                                                    }
                                                                                </code>
                                                                            );
                                                                        },
                                                                        pre: ({
                                                                            children,
                                                                            ...props
                                                                        }) => (
                                                                            <pre
                                                                                className="bg-gray-100 dark:bg-slate-800 p-4 rounded-lg overflow-x-auto text-sm"
                                                                                {...props}
                                                                            >
                                                                                {
                                                                                    children
                                                                                }
                                                                            </pre>
                                                                        ),
                                                                    }}
                                                                >
                                                                    {stripHtmlFromMarkdown(
                                                                        readmeContent,
                                                                    )}
                                                                </Markdown>
                                                            </div>
                                                        )}
                                                    {!activeRepo &&
                                                        !readmeLoading && (
                                                            <p className="text-sm text-gray-700 dark:text-gray-300">
                                                                {
                                                                    allProjectsList.find(
                                                                        (p) =>
                                                                            p.id ===
                                                                            displayedProject,
                                                                    )?.desc
                                                                }
                                                            </p>
                                                        )}
                                                </div>
                                            </CascadeItem>
                                        </article>
                                    </ScrollArea>
                                )}
                            </FadeContainer>

                            {/* Empty state view */}
                            <FadeContainer
                                isVisible={
                                    displayedProject === null &&
                                    isContentVisible
                                }
                            >
                                <div className="text-center max-w-[44ch] flex flex-col items-center justify-center h-full">
                                    <CascadeItem
                                        delay={0}
                                        isVisible={
                                            displayedProject === null &&
                                            isContentVisible
                                        }
                                    >
                                        <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
                                            Selected work
                                        </h2>
                                    </CascadeItem>

                                    <CascadeItem
                                        delay={75}
                                        isVisible={
                                            displayedProject === null &&
                                            isContentVisible
                                        }
                                    >
                                        <p className="mt-3 text-sm text-gray-600 dark:text-gray-400">
                                            Click a project on the left to open
                                            a short preview.
                                        </p>
                                    </CascadeItem>

                                    <CascadeItem
                                        delay={150}
                                        isVisible={
                                            displayedProject === null &&
                                            isContentVisible
                                        }
                                    >
                                        <div className="mt-6 flex justify-center gap-3"></div>
                                    </CascadeItem>
                                </div>
                            </FadeContainer>
                        </div>
                    </div>

                    <div className="flex items-center justify-between gap-3">
                        <div>
                            <h4 className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">
                                Skills
                            </h4>
                            <div className="mt-2 flex flex-wrap gap-2">
                                {skills.map((s, i) => (
                                    <span
                                        key={i}
                                        className="text-xs px-2 py-1 border border-gray-200 dark:border-slate-600 rounded-md text-gray-700 dark:text-gray-300"
                                    >
                                        {s}
                                    </span>
                                ))}
                            </div>
                        </div>

                        <div className="text-right text-xs text-gray-500 dark:text-gray-400">
                            <div>Available for freelance & contract</div>
                            <div className="mt-2">{profile.email}</div>
                        </div>
                    </div>
                </div>

                <div className="pointer-events-none absolute bottom-6 right-6 text-[10px] text-gray-400 dark:text-gray-500">
                    Built with React + Tailwind
                </div>
            </section>
        </main>
    );
}
