Skip to content
use actix_web::HttpRequest;
use maud::DOCTYPE;

use crate::constants::CONTACT_EMAIL;

fn nav_items() -> Vec<(&'static str, &'static str, &'static str)> {
    vec![
        ("/#home", "Home", "home"),
        ("/#about", "About", "about"),
        ("/#projects", "Projects", "projects"),
        ("/#contact", "Contact", "contact"),
    ]
}

fn render_head() -> maud::Markup {
    maud::html! {
        head {
            meta charset="utf-8";
            meta name="viewport" content="width=device-width, initial-scale=1";
            meta name="color-scheme" content="light dark";
            title { "Silen Locatelli" }
            link rel="icon" href="/assets/favicon.svg?v=1" type="image/svg+xml";
            script {
                "(function(){try{var theme=localStorage.getItem('theme');if(theme!=='light'&&theme!=='dark'){theme=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';}document.documentElement.dataset.theme=theme;document.documentElement.style.colorScheme=theme;}catch(_error){}})();"
            }
            link rel="stylesheet" href="/assets/t.css";
            link rel="stylesheet" href="/assets/theme.css?v=3";
            script src="/assets/h.js" {}
            script src="/assets/hx-response-targets.js" {}
            script src="/assets/gsap.min.js" {}
            script src="/assets/ScrollTrigger.min.js" {}
            style { "html { scroll-behavior: smooth; }" }
            script src="/assets/main.js?v=2" {}
        }
    }
}

fn render_theme_toggle(mobile: bool) -> maud::Markup {
    maud::html! {
        button
            type="button"
            class={ "theme-toggle bg-transparent bn pointer" @if mobile { " theme-toggle-mobile" } }
            aria-label="Switch to dark mode"
            aria-pressed="false"
            title="Switch to dark mode"
            onclick="toggleTheme()"
        {
            span class="theme-toggle-icon" aria-hidden="true" {
                svg class="theme-icon theme-icon-moon" viewBox="0 0 24 24" {
                    path d="M20.2 15.2A8.4 8.4 0 0 1 8.8 3.8a8.4 8.4 0 1 0 11.4 11.4Z" {}
                }
                svg class="theme-icon theme-icon-sun" viewBox="0 0 24 24" {
                    circle cx="12" cy="12" r="3.5" {}
                    path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" {}
                }
            }
        }
    }
}

fn render_nav(active_page: &str) -> maud::Markup {
    let items = nav_items();
    maud::html! {
        nav class="site-nav dt w-100 fixed top-0 left-0 right-0 z-1" aria-label="Main navigation" {
            div class="dtc v-mid pa3" {
                a href="/#home" class="site-brand link white-90 no-underline fw6 f4" data-section-link="home" {
                    "Silen Locatelli"
                }
            }
            div class="site-nav-links dtc v-mid tr pa3 dn dtc-ns" {
                @for (index, (href, label, section)) in items.iter().enumerate() {
                    @if active_page == "/" && *section == "home" {
                        a href=(href) class="site-nav-link is-active link no-underline f6 mr4 pa1 white fw6" data-section-link=(section) aria-current="location" {
                            span class="site-nav-number" aria-hidden="true" { (format!("{:02}", index)) }
                            span class="site-nav-label" { (label) }
                        }
                    } @else {
                        a href=(href) class="site-nav-link link no-underline f6 mr4 pa1 white-70" data-section-link=(section) {
                            span class="site-nav-number" aria-hidden="true" { (format!("{:02}", index)) }
                            span class="site-nav-label" { (label) }
                        }
                    }
                }
                (render_theme_toggle(false))
            }
            div class="dtc v-mid tr pa3 dn-ns" {
                button
                    class="menu-toggle bg-transparent bn white-70 pointer"
                    aria-label="Toggle navigation"
                    aria-controls="mobile-menu"
                    aria-expanded="false"
                    onclick="toggleMobileMenu(this)"
                {
                    span {}
                    span {}
                }
            }
        }
    }
}

fn render_mobile_menu(active_page: &str) -> maud::Markup {
    let items = nav_items();
    maud::html! {
        div id="mobile-menu" class="mobile-menu dn fixed top-0 left-0 right-0 z-2" style="margin-top: 4rem;" {
            div class="pa3 flex flex-column" {
                @for (href, label, section) in &items {
                    @if active_page == "/" && *section == "home" {
                        a href=(href) class="is-active link no-underline f5 mb3 pa2 white fw6" data-section-link=(section) aria-current="location" onclick="closeMobileMenu()" {
                            (label)
                        }
                    } @else {
                        a href=(href) class="link no-underline f5 mb3 pa2 white-70 hover-white" data-section-link=(section) onclick="closeMobileMenu()" {
                            (label)
                        }
                    }
                }
                (render_theme_toggle(true))
            }
        }
        div class="scroll-progress fixed top-0 left-0 right-0 z-2" aria-hidden="true" {}
    }
}

fn render_section_rail(active_page: &str) -> maud::Markup {
    if active_page != "/" {
        return maud::html! {};
    }

    let items = nav_items();
    maud::html! {
        nav class="section-rail" aria-label="Skip to page section" {
            @for (index, (href, label, section)) in items.iter().enumerate() {
                a
                    href=(href)
                    class={ "section-rail-link" @if index == 0 { " is-active" } }
                    data-section-link=(section)
                {
                    span class="section-rail-number" aria-hidden="true" { (format!("{:02}", index)) }
                    span class="section-rail-label" { (label) }
                }
            }
        }
    }
}

fn render_footer() -> maud::Markup {
    maud::html! {
        footer class="site-footer w-100 mt5 pa4 tc" data-motion-group {
            p class="footer-mark f6 ma0" data-motion-item { "SL / 26" }
            p class="f6 white-50 mt3 mb0" data-motion-item {
                "© 2026 Silen Locatelli"
            }
            div class="mt3" data-motion-item {
                a href="https://fig.silenlocatelli.ch" class="link white-50 hover-white f6 mr3 fw6" { "Projects" }
                a href="https://linkedin.com/in/silenlocatelli" class="link white-50 hover-white f6 mr3" { "LinkedIn" }
                a href=(format!("mailto:{CONTACT_EMAIL}")) class="link white-50 hover-white f6" { "Email" }
            }
        }
    }
}

pub fn render_layout(main_content: &maud::Markup, active_page: &str) -> maud::Markup {
    maud::html! {
        (DOCTYPE)
        html class="h-100" {
            (render_head())
            body hx-ext="response-targets" class="site-shell w-100 sans-serif ma0 bg-black white" style="min-height: 100vh;" {
                div class="ambient-field" aria-hidden="true" {
                    span class="ambient-orb orb-one" {}
                    span class="ambient-orb orb-two" {}
                    span class="ambient-orb orb-three" {}
                }
                (render_nav(active_page))
                (render_mobile_menu(active_page))
                (render_section_rail(active_page))
                main id="feature" class="site-main" style="padding-top: 5rem;" {
                    (main_content)
                }
                (render_footer())
            }
        }
    }
}

pub fn is_hx_request(req: &HttpRequest) -> bool {
    req.headers().get("HX-Request").is_some()
}