package site

import (
	"fmt"
	"github.com/delaneyj/toolbelt"
	datastar "github.com/starfederation/datastar/sdk/go"
	"net/http"
	"strings"
)

templ Page(title, description string, uri string) {
	<!DOCTYPE html>
	<html lang="en">
		<head>
			<title>{ title }</title>
			<meta name="description" content={ description }/>
			<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
			<link rel="canonical" href={ canonicalUrl(uri) }/>
			<link rel="stylesheet" href={ staticPath("css/site.css") } type="text/css"/>
			<link rel="preconnect" href="https://fonts.googleapis.com"/>
			<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
			<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Orbitron:wght@400..900&display=swap"/>
			<link rel="apple-touch-icon" sizes="180x180" href={ staticPath("favicon/apple-touch-icon.png") }/>
			<link rel="icon" type="image/png" sizes="32x32" href={ staticPath("favicon/favicon-32x32.png") }/>
			<link rel="icon" type="image/png" sizes="16x16" href={ staticPath("favicon/favicon-16x16.png") }/>
			<link rel="manifest" href={ staticPath("favicon/site.webmanifest") }/>
			<meta property="og:title" content={ title }/>
			<meta property="og:description" content={ description }/>
			<meta property="og:image" content={ staticAbsolutePath("images/rocket-social-preview.png") }/>
			<meta property="og:url" content="https://data-star.dev/"/>
			<meta property="og:type" content="website"/>
			<meta property="og:site_name" content="Datastar"/>
			<meta name="twitter:card" content="summary"/>
			<meta name="twitter:title" content={ title }/>
			<meta name="twitter:description" content={ description }/>
			<meta name="twitter:image" content={ staticAbsolutePath("images/rocket-social-preview.png") }/>
			<meta name="twitter:site" content="@DelaneyGillilan"/>
			<meta name="twitter:creator" content="@DelaneyGillilan"/>
			<script src="https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js"></script>
			<script type="module" src={ staticPath("js/datastar.js") }></script>
			<style>
.indicator {
	opacity:0;
	transition: opacity 300ms ease-out;
}
.indicator.loading {
	opacity:1;
	transition: opacity 300ms ease-in;
}
			</style>
		</head>
		// data-on-pageshow__window is to combat Safari's aggressive caching
		// https://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked
		<body
			data-on-pageshow__window="evt?.persisted && window.location.reload()"
			class="flex flex-col min-h-screen overflow-y-scroll min-w-screen scrollbar scrollbar-thumb-primary scrollbar-track-accent"
		>
			{ children... }
		</body>
	</html>
}

templ icon(icon string, attrs ...string) {
	<iconify-icon icon={ icon } { KVPairsAttrs(attrs...)... } noobserver></iconify-icon>
}

templ headerIconLink(iconName, href string) {
	<a target="_blank" rel="noopener noreferrer" href={ templ.SafeURL(href) }>
		@icon(iconName)
	</a>
}

templ headerTopLevelLink(r *http.Request, text string) {
	{{ url := templ.SafeURL("/" + strings.ToLower(text)) }}
	<a
		href={ url }
		class={
			"font-bold uppercase link-hover",
			templ.KV("link-primary", strings.HasPrefix(r.URL.Path, string(url))),
		}
	>
		{ text }
	</a>
}

templ headerExternalLinks() {
	@headerIconLink("simple-icons:discord", "https://discord.gg/bnRNgZjgPh")
	@headerIconLink("simple-icons:github", "https://github.com/starfederation/datastar/tree/main/library")
	@headerIconLink("simple-icons:npm", "https://www.npmjs.com/package/@starfederation/datastar")
	@headerIconLink("simple-icons:twitter", "https://x.com/DelaneyGillilan")
	@headerIconLink("simple-icons:reddit", "https://www.reddit.com/r/datastardev/")
}

templ headerTopLevelLinks(r *http.Request) {
	@headerTopLevelLink(r, "Guide")
	@headerTopLevelLink(r, "Reference")
	@headerTopLevelLink(r, "Examples")
	@headerTopLevelLink(r, "Essays")
	@headerTopLevelLink(r, "Memes")
	@headerTopLevelLink(r, "Bundler")
}

templ header(r *http.Request) {
	<div class="navbar bg-base-200">
		<div class="flex justify-between w-full gap-4">
			<div class="flex flex-wrap items-baseline gap-1">
				<a
					class="flex gap-1 text-2xl font-bold uppercase font-brand"
					href="/"
				>
					<span>Datastar</span>
					<img src={ staticPath("images/datastar_icon.svg") } class="h-8"/>
				</a>
				<div class="font-mono text-xs text-accent">v{ datastar.Version }</div>
			</div>
			<div class="hidden lg:text-md lg:text-lg lg:flex lg:gap-4 lg:visible ">
				@headerTopLevelLinks(r)
			</div>
			<div class="hidden text-xl lg:flex lg:gap-4 lg:visible">
				@headerExternalLinks()
			</div>
		</div>
	</div>
	<div class="flex flex-wrap justify-around visible gap-2 pb-8 text-sm bg-base-200 lg:hidden">
		@headerTopLevelLinks(r)
	</div>
	<div class="visible navbar bg-base-300 lg:hidden">
		<div class="navbar-start">
			<label for="sidebar-drawer" class="btn btn-ghost drawer-button">
				@icon("material-symbols:menu")
			</label>
		</div>
		<div class="gap-4 navbar-end">
			@headerExternalLinks()
		</div>
	</div>
}

type SidebarLink struct {
	ID                     string
	Label                  string
	URL                    templ.SafeURL
	Prev                   *SidebarLink
	Next                   *SidebarLink
	IsDisabled             bool
	ShouldIncludeInspector bool
}

type SidebarGroup struct {
	Label string
	Links []*SidebarLink
}

templ SidebarPage(
	r *http.Request, sidebarGroups []*SidebarGroup, current *SidebarLink,
	title, description, contents string,
) {
	@Page(title, description, r.URL.String()) {
		@highlightCSS
		<div class="drawer">
			<input id="sidebar-drawer" type="checkbox" class="drawer-toggle"/>
			<div class="flex flex-col min-h-screen drawer-content">
				@header(r)
				if current.ShouldIncludeInspector {
					<div class="flex">
						@sidebarPageContents(sidebarGroups, current, contents)
						<div class="h-full pl-2 bg-base-200 ">
							<datastar-inspector></datastar-inspector>
						</div>
					</div>
				} else {
					@sidebarPageContents(sidebarGroups, current, contents)
				}
			</div>
			<aside class="drawer-side">
				<label for="sidebar-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
				<ul class="min-h-full px-4 menu w-80 bg-base-300 text-base-content">
					@SidebarContents(sidebarGroups, current)
				</ul>
			</aside>
		</div>
	}
}

templ sidebarPageContents(sidebarGroups []*SidebarGroup, current *SidebarLink, contents string) {
	<div class="flex flex-1">
		<aside class="flex-col hidden gap-4 px-4 py-8 overflow-y-auto lg:flex min-w-80 bg-base-300 lg:visible">
			@SidebarContents(sidebarGroups, current)
		</aside>
		<div class="flex flex-col w-full gap-16 p-4 lg:items-center lg:p-16">
			@SidebarPrevNextLinks(sidebarGroups, current)
			<article
				class="flex flex-col flex-1 p-1 prose prose-primary lg:prose-lg prose-a:link-primary max-w-none lg:max-w-prose w-full"
			>
				@templ.Raw(contents)
			</article>
			@SidebarPrevNextLinks(sidebarGroups, current)
		</div>
	</div>
}

templ SidebarContents(sidebarGroups []*SidebarGroup, current *SidebarLink) {
	<div class="flex flex-col gap-8">
		for i, grp := range sidebarGroups {
			<div class="flex flex-col gap-2">
				<h3 class="text-xs font-bold text-primary uppercase">{ grp.Label }</h3>
				for _, link := range grp.Links {
					if link.IsDisabled {
						<div class="opacity-25">{ link.Label }</div>
					} else {
						<a
							class="link-secondary link-hover"
							href={ link.URL }
						>{ link.Label }</a>
					}
				}
				if i != len(sidebarGroups)-1 {
					<div class="divider"></div>
				}
			</div>
		}
	</div>
}

templ SidebarPrevNextLinks(essayGroups []*SidebarGroup, current *SidebarLink) {
	<div class="flex flex-wrap justify-between w-full gap-4">
		<div>
			if  current.Prev != nil {
				<a
					class="btn btn-sm btn-ghost"
					disabled?={ current.Prev.IsDisabled }
					href={ current.Prev.URL }
				>
					@icon("material-symbols:arrow-back-ios")
					{ current.Prev.Label }
				</a>
			}
		</div>
		<div>
			if current.Next != nil {
				<a
					class="btn btn-sm btn-ghost"
					disabled?={ current.Next.IsDisabled }
					href={ current.Next.URL }
				>
					{ current.Next.Label }
					@icon("material-symbols:arrow-forward-ios")
				</a>
			}
		</div>
	</div>
}

templ codeSnippetFragment(block CodeSnippetBlock) {
	<div
		class="flex flex-col gap-2"
		data-signals="{language:'go'}"
	>
		<div class="flex justify-end -mb-8">
			<div class="join">
				for _, snippet := range block.Snippets {
					<button
						class="btn join-item btn-lg flex items-center gap-2"
						data-class={ fmt.Sprintf(
							"{'btn-primary btn-outline z-0': language.value == '%s'}",
							snippet.Extension,
						) }
						data-on-click={ fmt.Sprintf("language.value = '%s'", snippet.Extension) }
					>
						{ toolbelt.Upper( snippet.Extension) }
						<iconify-icon icon={ snippet.Icon } class="text-4xl" noobserver></iconify-icon>
					</button>
				}
			</div>
		</div>
		for _, snippet := range block.Snippets {
			<div data-show={ fmt.Sprintf("language.value == '%s'", snippet.Extension) }>
				{ snippet.Path.Snake }
				@templ.Raw(snippet.ContentHighlighted)
			</div>
		}
	</div>
}

templ templSignalsJSON() {
	<div>
		<pre data-text="ctx.signals.JSON()"></pre>
	</div>
}

templ sseIndicator(signalName string) {
	<div class="loading-dots text-primary" data-class={ fmt.Sprintf("{'loading ml-4': %s.value}", signalName) }></div>
}
