import { type ComponentChildren } from "preact";
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
import { Footer } from "./Footer";
import { ConsoleSpinner } from "./ConsoleSpinner";
import { Avatar } from "./Avatar";
import "../global.css";
import "../scss/application.scss";

const Project = ({
    title,
    imgPath,
    children,
    websiteHref,
    sourceHref,
}: {
    title: string;
    imgPath: string;
    children: ComponentChildren;
    websiteHref?: string;
    sourceHref?: string;
}) => {
    return (
        <div className="flex flex-col justify-between">
            <div>
                <img
                    src={imgPath}
                    alt={`${title} Logo`}
                    title={title}
                    loading="lazy"
                    className="mx-auto h-20"
                />
                <h3 className="font-display text-3xl text-center">{title}</h3>
                {children}
            </div>
            <div>
                {websiteHref && (
                    <a
                        href={websiteHref}
                        target="_blank"
                        rel="noopener"
                        className="btn btn-primary font-display"
                    >
                        <i class="icon-new_tab" /> Website
                    </a>
                )}
                {sourceHref && (
                    <a
                        href={sourceHref}
                        target="_blank"
                        rel="noopener"
                        className="btn btn-accent font-display"
                    >
                        <i class="icon-new_tab" /> Source
                    </a>
                )}
            </div>
        </div>
    );
};

const ContactTile = ({
    title,
    iconName,
    children,
    href,
    buttonText,
}: {
    title: string;
    iconName: string;
    children: ComponentChildren;
    href: string;
    buttonText: string;
}) => {
    return (
        <div className="flex flex-col justify-between">
            <div>
                <h3 className="font-display text-3xl text-center">
                    <i className={`icon-${iconName}`} /> {title}
                </h3>
                {children}
            </div>
            <div>
                <a
                    href={href}
                    target="_blank"
                    rel="noopener"
                    className="btn btn-primary font-display"
                >
                    {buttonText}
                </a>
            </div>
        </div>
    );
};

export const App = () => {
    const developmentLinks = [
        {
            iconName: "codeberg",
            title: "Codeberg",
            href: "https://codeberg.org/Scrumplex",
        },
        {
            iconName: "github",
            title: "GitHub",
            href: "https://github.com/Scrumplex",
        },
        {
            iconName: "gitlab",
            title: "GitLab.com",
            href: "https://gitlab.com/Scrumplex",
        },
    ];

    const donateLinks = [
        {
            iconName: "github_sponsors",
            title: "GitHub Sponsors",
            href: "https://github.com/sponsors/Scrumplex",
        },
        {
            iconName: "liberapay",
            title: "Liberapay",
            href: "https://liberapay.com/Scrumplex/donate",
        },
        {
            iconName: "paypal",
            title: "PayPal",
            href: "https://www.paypal.me/Scrumplex",
        },
        {
            iconName: "ko-fi",
            title: "Ko-Fi",
            href: "https://ko-fi.com/scrumplex",
        },
    ];

    const mainRef = useRef<HTMLDivElement>(null);

    const [mainOffset, setMainOffset] = useState(0);

    const scrollToElement = (selector: string) => {
        const elem = document.querySelector(selector);
        if (!elem) {
            return;
        }

        const rect = elem.getBoundingClientRect();

        const offset = window.pageYOffset + rect.top;

        window.scrollTo({ top: offset, behavior: "smooth" });
    };

    const expandConditionally = useCallback(
        (force?: boolean) => {
            if (mainOffset > 0) {
                return;
            }

            const rect = mainRef.current!.getBoundingClientRect();
            if (
                rect.top <= 0 || // offset to top window border
                rect.height >= window.innerHeight ||
                force
            ) {
                setMainOffset(window.pageYOffset + rect.top);
            }
        },
        [mainRef],
    );

    useEffect(() => {
        if (mainOffset || !mainRef.current) {
            return;
        }

        const onScroll = () => expandConditionally();
        window.addEventListener("scroll", onScroll);

        const onHashChange = () => {
            expandConditionally(true);
            setTimeout(() => scrollToElement(location.hash), 10);
        };
        window.addEventListener("hashchange", onHashChange);
        return () => {
            window.removeEventListener("scroll", onScroll);
            window.removeEventListener("hashchange", onHashChange);
        };
    }, [mainRef, mainOffset, setMainOffset]);

    return (
        <>
            <noscript>
                Enable JavaScript for best experience. Source code of this
                website is available at{" "}
                <a
                    href="https://codeberg.org/Scrumplex/website"
                    target="_blank"
                    rel="noopener"
                >
                    Codeberg
                </a>
                .
            </noscript>
            <div className="container wrapper mx-auto grow" id="wrapper">
                <div
                    ref={mainRef}
                    className={`sheet ${!mainOffset ? "sheet-splash" : "sheet-splashed"} wavy`}
                    style={mainOffset ? { marginTop: mainOffset } : {}}
                    onAnimationEnd={() => {
                        if (location.hash) {
                            expandConditionally(true);
                            location.href = location.hash;
                        }
                    }}
                >
                    <div className="row">
                        <div className="col-med-5 text-center flex flex-col justify-between">
                            <div className="row">
                                <div className="col flex flex-col items-center">
                                    <Avatar />
                                    <h1 className="font-display text-5xl">
                                        Scrumplex
                                    </h1>
                                    <strong>he/him or any</strong>
                                </div>
                            </div>
                            <div className="row">
                                <div className="col-med-6">
                                    <h2 className="font-display text-4xl">
                                        Development
                                    </h2>
                                    {developmentLinks.map((link) => (
                                        <a
                                            href={link.href}
                                            target="_blank"
                                            rel="noopener"
                                            className={`link link-${link.iconName}`}
                                            title={link.title}
                                        >
                                            <i
                                                className={`icon-2x icon-${link.iconName}`}
                                            />
                                        </a>
                                    ))}
                                </div>
                                <div className="col-med-6">
                                    <h2 className="font-display text-4xl">
                                        Donate
                                    </h2>
                                    {donateLinks.map((link) => (
                                        <a
                                            href={link.href}
                                            target="_blank"
                                            rel="noopener"
                                            className={`link link-${link.iconName}`}
                                            title={link.title}
                                        >
                                            <i
                                                className={`icon-2x icon-${link.iconName}`}
                                            />
                                        </a>
                                    ))}
                                </div>
                            </div>
                        </div>
                        <div className="col-med-7">
                            <blockquote className="text-right">
                                Converting coffee to code... <ConsoleSpinner />
                            </blockquote>
                            <p className="text-justify">
                                Hello there,
                                <br />I am Scrumplex, but you can call me Scrum,
                                Scrump or Sefa. I am an enthusiastic developer
                                from <b>Germany</b>, and I invest lots of my
                                time into playing around with many technologies.
                                Linux is my primary interest, as I maintain
                                multiple servers and contribute to various open
                                source technologies around the Linux space. As
                                for programming languages, I primarily use
                                C/C++, Python, Bash, Go, Rust and Kotlin. But I
                                always try to incorporate other languages as
                                well, if they fit the use-case.
                                <br />I know my way around CI/CD professionally,
                                especially working with GitLab CI, Flux CD,
                                Kubernetes and all the technologies around
                                these. And in an effort to apply my DevOps
                                skills at home, I also do lots of{" "}
                                <a
                                    href="https://nixos.org"
                                    target="_blank"
                                    rel="noopener"
                                >
                                    <i className="icon-new_tab"></i> Nix
                                </a>{" "}
                                stuff. My daily computing is shaped by{" "}
                                <a
                                    href="https://gnu.org/philosophy/free-sw.html"
                                    target="_blank"
                                    rel="noopener"
                                >
                                    <i className="icon-new_tab"></i> free
                                    software
                                </a>{" "}
                                and in an effort to ensure that it stays that
                                way I generally publish all my work under a
                                copyleft license. If you want to see what I am
                                working on right now, go to any of the code
                                forges linked on this page.
                            </p>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col text-right">
                            <Footer />
                        </div>
                    </div>
                </div>
                <div
                    className={`sheet wavy ${!mainOffset ? "sheet-hidden" : ""}`}
                    id="projects"
                >
                    <h2 className="font-display text-4xl">Current Projects</h2>
                    <div className="grid grid-cols-2 md:grid-cols-3">
                        <Project
                            title="Prism Launcher"
                            imgPath="prismlauncher.svg"
                            websiteHref="https://prismlauncher.org"
                            sourceHref="https://github.com/PrismLauncher/PrismLauncher"
                        >
                            A custom launcher for Minecraft that allows you to
                            easily manage multiple installations of Minecraft at
                            once.
                        </Project>
                        <Project
                            title="nixpkgs"
                            imgPath="nixos.svg"
                            websiteHref="https://nixos.org"
                            sourceHref="https://github.com/NixOS/nixpkgs"
                        >
                            A reproducible toolchain for package management,
                            system configuration and more.
                        </Project>
                        <Project
                            title="libvibrant"
                            imgPath="vibrant.svg"
                            sourceHref="https://github.com/libvibrant"
                        >
                            A collection of software to adjust color vibrancy
                            and other color correction settings on Linux display
                            servers.
                        </Project>
                    </div>
                    <h2 className="font-display text-4xl">Legacy Projects</h2>
                    <div className="grid grid-cols-2 md:grid-cols-3">
                        <Project
                            title="PASSY"
                            imgPath="passy.svg"
                            sourceHref="https://gitlab.com/PASSYpw/PASSY"
                        >
                            A beautiful password manager utilizing modern web
                            technologies.
                        </Project>
                        <Project
                            title="Waves.js"
                            imgPath="waves.js.svg"
                            sourceHref="https://gitlab.com/PASSYpw/Waves.js"
                        >
                            A JQuery plugin providing authentic Material Design
                            ripples.
                        </Project>
                        <Project
                            title="Sprummlbot"
                            imgPath="sprummlbot.svg"
                            sourceHref="https://gitlab.com/Scrumplex/Sprummlbot"
                        >
                            A lightweight TeamSpeak 3 ServerAdmin Bot, adding
                            many missing features to TeamSpeak 3 servers.
                        </Project>
                        <Project
                            title="ExitNow"
                            imgPath="exitnow.png"
                            sourceHref="https://codeberg.org/Scrumplex/ExitNow"
                        >
                            A simple application, providing an easy method to
                            kill foreground windows with a shortcut.
                        </Project>
                    </div>
                </div>
                <div
                    className={`sheet wavy ${!mainOffset ? "sheet-hidden" : ""}`}
                    id="contact"
                >
                    <h2 className="font-display text-4xl">Contact</h2>
                    <div className="grid grid-cols-1 md:grid-cols-2">
                        <ContactTile
                            title="Email"
                            iconName="mail"
                            href="mailto:contact@scrumplex.net"
                            buttonText="Write an email"
                        >
                            Send me an email at <b>contact@scrumplex.net</b> for
                            questions or help. PGP:{" "}
                            <a
                                href="https://keys.openpgp.org/search?q=contact%40scrumplex.net"
                                target="_blank"
                                rel="noopener"
                            >
                                <code>E13DFD4B47127951</code>
                            </a>
                        </ContactTile>
                        <ContactTile
                            title="Matrix"
                            iconName="matrix"
                            href="https://matrix.to/#/@scrumplex:duckhub.io"
                            buttonText="Message me on Matrix"
                        >
                            Contact me on Matrix via{" "}
                            <b>@scrumplex:duckhub.io</b> and have a conversation
                            with me.
                        </ContactTile>
                        <ContactTile
                            title="Telegram"
                            iconName="telegram"
                            href="https://telegram.me/Scrumplex"
                            buttonText="Message me on Telegram"
                        >
                            Contact me on Telegram at <b>@Scrumplex</b> and have
                            a conversation with me.
                        </ContactTile>
                    </div>
                </div>
                <div
                    className={`sheet wavy ${!mainOffset ? "sheet-hidden" : ""}`}
                    id="privacy"
                >
                    <h2 className="font-display text-4xl">Privacy Policy</h2>
                    <p>
                        Privacy information for services hosted on{" "}
                        <code>scrumplex.net</code>, <code>sefa.cloud</code> and{" "}
                        <code>duckhub.io</code> (and all subdomains)
                    </p>
                    <p>
                        Every service collects log-data. This includes IP
                        addresses, browser user-agents and visited sites. These
                        are not used to track the user, but are only collected
                        for operation purposes.
                        <br />
                        Some services may require you to enter some kind of
                        username or email-address to access them These services
                        can not operate without this information. You may choose
                        to use anonymous or pseudonymous usernames or email
                        addresses. All personal data (such as, but not limited
                        to names, addresses or telephone numbers) shall always
                        be in line with the General Data Protection Regulation.
                        <br />
                        No data is ever processed to track user activity.
                    </p>
                </div>
            </div>
            {!mainOffset && (
                <div className="scroll-indicator">
                    <h1 className="text-center">▾</h1>
                </div>
            )}
        </>
    );
};
