import Navbar from "../navbar/Navbar.11ty";
import Footer from "../footer/Footer.11ty";
import { LayoutContext, LayoutProps } from "../../src/models";
import { MetaOpenGraphImage } from "../../src/plugins/metaOpenGraphImagePlugin";
import { Resource } from "../../src/ResourceModels";
import {
	GoogleTagManagerBodyNoScript,
	GoogleTagManagerHeadScript,
} from "../googleTagManager.11ty";
import Subnav from "../navbar/Subnav.11ty";
import PromoBanner from "../navbar/PromoBanner.11ty";
import { Channel, isChannel } from "../resources/channel/ChannelModels";
import { Fragment } from "jsx-async-runtime/jsx-dev-runtime";
import { isLink } from "../resources/link/LinkModels";

export type BaseLayoutProps = {
	title: string;
	subtitle?: string;
	video?:
		| string
		| {
				url: string;
				start: number;
				end: number;
		  };
	resourceType: string;
	channel?: string;
} & LayoutProps;

export function BaseLayout(
	this: LayoutContext,
	data: BaseLayoutProps,
): JSX.Element {
	const { children, title, subtitle, resourceType, collections } = data;

	// Happy DOM throws a DOMException for external script/css even though
	// we do the settings to suppress it. Vite catches the exception but
	// logs it. We can't handle the exception, and it pollutes the test output.
	// Let's detect if we're running in a test, then later, wrap the
	// <link> and <script> to suppress.
	const isNotTest = !(
		typeof window != "undefined" && !!(window as any).happyDOM
	);

	// determine if there's an og:image
	let channel: Channel | undefined = undefined;
	let thumbnail: string | undefined = undefined;
	let canonicalURL: string | undefined = undefined;

	if (resourceType) {
		const resource = collections.resourceMap.get(data.page.url) as Resource;
		const resourceThumbnail = resource?.getThumbnail();
		canonicalURL = resource?.canonical;

		// make sure we don't try to use fontawesome icons as the thumbnail image
		if (
			resourceThumbnail &&
			resourceThumbnail.indexOf("fa-") < 0 &&
			resourceThumbnail.indexOf("fas-") < 0 &&
			resourceThumbnail.indexOf("far-") < 0
		) {
			thumbnail = resourceThumbnail;
		}
		if (isChannel(resource)) {
			channel = resource;
		} else if (
			resource &&
			resource.references &&
			resource.references.channel?.url
		) {
			channel = resource.references.channel;
		} else if (data.channel) {
			channel = collections.resourceMap.get(data.channel) as Channel;
		}

		if (isLink(resource)) {
			if (canonicalURL) {
				console.warn(
					`canonical URL (${canonicalURL}) set on ${resource.url} but is a Link URL. Ignoring.`,
				);
			}
			// overwrite canonical URL if this is a Link URL
			canonicalURL = resource?.linkURL;
		}
	}

	const year = new Date().getFullYear();
	const copyright = `Copyright © 2000–${year} <a href="https://www.jetbrains.com/">JetBrains</a> s.r.o.`;

	// TODO: data below should probably be cached and defined elsewhere, but hey - WIP!
	// data for navbar
	const featuredChannel = collections.resourceMap.get("/remote/");
	const technologies = [
		collections.resourceMap.get("/javascript/"),
		collections.resourceMap.get("/python/"),
		collections.resourceMap.get("/java/"),
		collections.resourceMap.get("/go/"),
		collections.resourceMap.get("/dotnet/"),
		collections.resourceMap.get("/kotlin/"),
	].filter((it) => it != undefined) as Resource[];
	const solutions = [
		collections.resourceMap.get("/gamedev/"),
		collections.resourceMap.get("/ai/"),
		collections.resourceMap.get("/remote/"),
		collections.resourceMap.get("/databases/"),
		collections.resourceMap.get("/django/"),
	].filter((it) => it != undefined) as Resource[];
	const hotTopics = [
		collections.resourceMap.get("topics:aws"),
		collections.resourceMap.get("topics:debugging"),
		collections.resourceMap.get("topics:git"),
		collections.resourceMap.get("topics:gcp"),
		collections.resourceMap.get("topics:gradle"),
		collections.resourceMap.get("topics:refactoring"),
	].filter((it) => it != undefined) as Resource[];

	// render
	return (
		<html lang="en">
			<head>
				<meta charset="utf-8" />
				<meta name="viewport" content="width=device-width, initial-scale=1.0" />
				<title>{data.title} - JetBrains Guide</title>
				<link
					rel="preload"
					as="font"
					href="https://resources.jetbrains.com/storage/jetbrains-sans/JetBrainsSans.woff2"
					crossorigin="anonymous"
				/>
				<link
					rel="preload"
					as="font"
					href="https://resources.jetbrains.com/storage/jetbrains-sans/JetBrainsSans-Regular.woff2"
					crossorigin="anonymous"
				/>
				<link rel="preload" as="style" href="/assets/site.scss" />
				{isNotTest && (
					<Fragment>
						<link rel="stylesheet" href="/assets/site.scss" />
						<script defer src="/assets/js/site.js" type="module"></script>
						<script defer src="/assets/js/video.js" type="module"></script>
					</Fragment>
				)}
				{canonicalURL && <link rel="canonical" href={canonicalURL} />}
				<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
				<link rel="shortcut icon" href="/assets/favicon.ico" />
				<link
					rel="alternate"
					type="application/rss+xml"
					title={`${title} RSS Feed`}
					href={`/rss.xml`}
				/>
				<meta property="og:title" content={title} />
				{subtitle && <meta property="og:description" content={subtitle} />}
				<meta property="og:type" content="article" />
				<meta property="article:published_time" content="2023-02-17" />
				<meta property="article:author" content="" />
				<meta property="article:section" content="" />
				{thumbnail && <meta property="og:image:alt" content={title} />}
				<meta name="twitter:card" content="summary" />
				<meta name="twitter:site" content="@jetbrains" />
				{subtitle && <meta name="description" content={subtitle} />}
				<GoogleTagManagerHeadScript googleTagManagerId="GTM-5P98" />
			</head>
			<body>
				<GoogleTagManagerBodyNoScript googleTagManagerId="GTM-5P98" />
				<Navbar
					featuredResource={featuredChannel}
					technologies={technologies}
					solutions={solutions}
					topics={hotTopics}
				/>
				{channel && <Subnav channel={channel} />}
				{channel && <PromoBanner channel={channel} />}
				{children}
				<Footer copyright={copyright}></Footer>
				{thumbnail && (
					<MetaOpenGraphImage
						siteUrl="https://www.jetbrains.com/guide/"
						src={thumbnail}
					/>
				)}
			</body>
		</html>
	);
}

export const render = BaseLayout;
