<script lang="ts">
	// @ts-nocheck
	import DemosLite from "../../lib/components/DemosLite.svelte";
	import MetaTags from "$lib/components/MetaTags.svelte";
	import { page } from "$app/stores";
	import { browser } from "$app/environment";
	import { gradio_logo } from "$lib/assets";
	import { afterNavigate } from "$app/navigation";
	import { clickOutside } from "$lib/components/clickOutside.js";
	import { BaseCode as Code } from "@gradio/code";
	import version_json from "$lib/json/version.json";
	import WHEEL from "$lib/json/wheel.json";

	export let data: {
		demos_by_category: {
			category: string;
			demos: {
				name: string;
				dir: string;
				code: string;
				requirements: string[];
			}[];
		}[];
	};

	let all_demos = data.demos_by_category.flatMap((category) => category.demos);
	let current_selection = all_demos[0].name;

	let shared = "";
	if (browser) {
		let linked_demo = $page.url.searchParams.get("demo");
		if (linked_demo) {
			current_selection = linked_demo.replaceAll("_", " ");
			shared = current_selection;
		}
	}

	let show_nav = true;

	let show_mobile_nav = false;

	let show_preview = false;

	let on_desktop = false;
	afterNavigate(() => {
		if (window.innerWidth > 768) {
			on_desktop = true;
		}
	});

	const mobile_click = (demo_name: string) => {
		current_selection = demo_name;
		show_mobile_nav = false;
	};

	let version = version_json.version;
</script>

<MetaTags
	title="Gradio Playground"
	url="https://gradio.app/playground"
	canonical="https://gradio.app/playground"
	description="Play Around with Gradio Demos"
/>

<svelte:head>
	<script type="module" src="{WHEEL.gradio_lite_url}/dist/lite.js"></script>
	<link rel="stylesheet" href="https://gradio-hello-world.hf.space/theme.css" />
	<script
		id="gradio-js-script"
		type="module"
		src="https://gradio.s3-us-west-2.amazonaws.com/{version.replace(
			'b',
			'-beta.'
		)}/gradio.js"
	></script>
</svelte:head>

<!-- Header on Desktop -->
<div class="flex-row hidden md:flex">
	<div class="flex flex-row relative items-center px-1 py-1 pr-6 text-lg gap-8">
		<div class="flex">
			<a href="/">
				<img src={gradio_logo} alt="Gradio logo" />
			</a>
			<p class="self-center text-xl font-light -m-1">Playground</p>
		</div>

		<nav class="flex w-auto flex-row gap-6">
			<a class="thin-link flex items-center gap-3" href="/docs" target="_blank"
				><span>✍️</span> <span>Docs</span></a
			>
			<a
				class="thin-link flex items-center gap-3"
				href="/guides/gradio-lite"
				target="_blank"><span>💡</span> <span>Gradio Lite</span></a
			>
		</nav>
	</div>
</div>

<!-- Desktop -->
{#if on_desktop}
	<main
		class="playground flex-col justify-between hidden md:flex"
		style="height: 94vh"
	>
		<div class="w-full border border-gray-200 shadow-xl h-full relative">
			<div
				class="w-[200px] rounded-tr-none rounded-bl-xl overflow-y-scroll mb-0 p-0 pb-4 text-md block rounded-t-xl bg-gradient-to-r from-white to-gray-50 overflow-x-clip"
				style="word-break: normal; overflow-wrap: break-word; white-space:nowrap; height: 100%; width: {show_nav
					? 200
					: 37}px;"
			>
				<div class="flex justify-between align-middle h-8 border-b px-2">
					{#if show_nav}
						<h3 class="pl-2 pt-1">Demos</h3>
					{/if}
					<button
						on:click={() => (show_nav = !show_nav)}
						class="float-right text-gray-600 pl-1"
						>{#if show_nav}&larr;{:else}&rarr;{/if}</button
					>
				</div>
				{#if show_nav}
					<button
						on:click={() => (current_selection = "Blank")}
						class:current-playground-demo={current_selection == "Blank"}
						class:shared-link={shared == "Blank"}
						class="thin-link font-light px-4 block my-2">New Demo</button
					>
					{#each data.demos_by_category as { category, demos } (category)}
						<p class="px-4 my-2 font-medium">{category}</p>
						{#each demos as demo, i}
							<button
								on:click={() => (current_selection = demo.name)}
								class:current-playground-demo={current_selection == demo.name}
								class:shared-link={shared == demo.name}
								class="thin-link font-light px-4 block">{demo.name}</button
							>
						{/each}
					{/each}
				{/if}
			</div>

			<DemosLite demos={all_demos} {current_selection} {show_nav} />
		</div>
	</main>
{:else}
	<!-- Mobile -->
	<main class="playground flex-col justify-between flex md:hidden">
		<div
			class:hidden={!show_mobile_nav}
			class="fixed inset-0 bg-black/20 backdrop-blur-md lg:hidden z-50"
		></div>
		<div
			use:clickOutside
			on:click_outside={() => (show_mobile_nav = false)}
			class:hidden={!show_mobile_nav}
			class="max-w-max min-w-[75%] navigation mobile-nav shadow overflow-y-auto fixed backdrop-blur-lg z-50 bg-white pr-6 pl-4 py-4 -ml-4 h-full inset-0 lg:inset-auto lg:shadow-none lg:ml-0 lg:z-0 lg:backdrop-blur-none lg:navigation lg:p-0 lg:pb-4 lg:h-screen lg:leading-relaxed lg:sticky lg:top-0 lg:text-md lg:block lg:rounded-t-xl lg:bg-gradient-to-r lg:from-white lg:to-gray-50 lg:overflow-x-clip lg:w-2/12 lg:min-w-0"
			id="mobile-nav"
		>
			<button
				on:click={() => (show_mobile_nav = false)}
				type="button"
				class="absolute z-10 top-4 right-4 w-2/12 h-4 flex items-center justify-center text-grey-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300 p-4 lg:hidden"
				tabindex="0"
				data-svelte-h="svelte-1askwj0"
			>
				<svg viewBox="0 0 10 10" class="overflow-visible" style="width: 10px"
					><path
						d="M0 0L10 10M10 0L0 10"
						fill="none"
						stroke="currentColor"
						stroke-width="2"
						stroke-linecap="round"
					></path></svg
				>
			</button>

			{#each data.demos_by_category as { category, demos } (category)}
				<p class="font-semibold px-4 my-2 block">{category}</p>
				{#each demos as demo, i}
					<button
						on:click={() => mobile_click(demo.name)}
						class:current-playground-demo={current_selection == demo.name}
						class:shared-link={shared == demo.name}
						class="thin-link font-light px-4 block">{demo.name}</button
					>
				{/each}
			{/each}
		</div>

		{#each data.demos_by_category as { category, demos } (category)}
			{#each demos as demo, i}
				<div
					class:hidden={current_selection !== demo.name}
					class="flex items-center p-4 border-t border-slate-900/10 lg:hidden dark:border-slate-50/[0.06]"
				>
					<button
						on:click={() => (show_mobile_nav = !show_mobile_nav)}
						type="button"
						class="text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300"
					>
						<svg width="24" height="24"
							><path
								d="M5 6h14M5 12h14M5 18h14"
								fill="none"
								stroke="currentColor"
								stroke-width="2"
								stroke-linecap="round"
							></path></svg
						>
					</button>
					{#if category}
						<ol class="ml-4 flex text-sm leading-6 whitespace-nowrap min-w-0">
							<li class="flex items-center">
								{category}
								<svg
									width="3"
									height="6"
									aria-hidden="true"
									class="mx-3 overflow-visible text-slate-400"
									><path
										d="M0 0L3 3L0 6"
										fill="none"
										stroke="currentColor"
										stroke-width="1.5"
										stroke-linecap="round"
									></path></svg
								>
							</li>
							<li
								class="font-semibold text-slate-900 truncate dark:text-slate-200"
							>
								{demo.name}
							</li>
						</ol>
					{/if}
				</div>
				<div
					class:hidden={current_selection !== demo.name}
					class="mobile-window w-[95%] mx-auto relative border rounded-xl border-gray-200 shadow md:hidden"
				>
					{#if !show_preview}
						<Code
							bind:value={demos[i].code}
							language="python"
							lines={10}
							readonly
							dark_mode={false}
						/>
					{:else}
						<gradio-app space={"gradio/" + demo.dir} />
					{/if}
				</div>
			{/each}
		{/each}
		<div class="mx-auto mt-4 flex flex-row items-center gap-4">
			<span
				class:text-gray-500={show_preview}
				class:text-gray-600={!show_preview}
				class:font-semibold={!show_preview}
				class="text-lg">Code</span
			>
			<label class="switch">
				<input
					on:click={() => (show_preview = !show_preview)}
					type="checkbox"
					class=""
				/>
				<span class="slider round"></span>
			</label>
			<span
				class:text-gray-500={!show_preview}
				class:text-gray-600={show_preview}
				class:font-semibold={show_preview}
				class="text-lg">Preview</span
			>
		</div>
		<p class="mt-4 mx-auto text-lg text-gray-600 text-center md:hidden">
			To edit code and see live changes, use Playground on a desktop.
		</p>
	</main>
{/if}

<style>
	:global(body) {
		min-height: 100vh;
		display: grid;
		grid-template-rows: auto 1fr auto;
	}

	.switch {
		position: relative;
		width: 60px;
		height: 34px;
	}

	.switch input {
		opacity: 0;
		width: 0;
		height: 0;
	}

	.slider {
		position: absolute;
		cursor: pointer;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: #ccc;
		-webkit-transition: 0.4s;
		transition: 0.4s;
	}

	.slider:before {
		position: absolute;
		content: "";
		height: 26px;
		width: 26px;
		left: 4px;
		bottom: 4px;
		background-color: white;
		-webkit-transition: 0.4s;
		transition: 0.4s;
	}

	input:checked + .slider {
		background-color: #fc963c;
	}

	input:focus + .slider {
		box-shadow: 0 0 1px #fc963c;
	}

	input:checked + .slider:before {
		-webkit-transform: translateX(26px);
		-ms-transform: translateX(26px);
		transform: translateX(26px);
	}

	.slider.round {
		border-radius: 34px;
	}

	.slider.round:before {
		border-radius: 50%;
	}

	.mobile-window {
		height: 58vh;
		overflow-y: scroll;
	}

	:global(.mobile-window .embed-container .main) {
		margin: 0 !important;
		overflow: scroll;
	}
	:global(.mobile-window gradio-app) {
		height: 100%;
		display: flex;
	}
	:global(.mobile-window .gradio-container) {
		width: 100%;
		margin: 0px !important;
	}

	:global(.mobile-window .block .wrap) {
		display: grid;
	}

	:global(.mobile-window .block) {
		height: 100%;
		overflow: hidden !important;
	}
</style>
