<script lang="ts">
	import { AppService, FlowService, ResourceService, ScriptService } from '$lib/gen'
	import { enterpriseLicense, workspaceStore } from '$lib/stores'
	import { clickOutside } from '$lib/utils'
	import { Boxes, Code2, Edit, LayoutDashboard, Loader2, X } from 'lucide-svelte'
	import Portal from 'svelte-portal'
	import { twMerge } from 'tailwind-merge'
	import SearchItems from './SearchItems.svelte'
	import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
	import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
	import FlowIcon from './home/FlowIcon.svelte'
	import { Alert, Button } from './common'
	import { goto } from '$app/navigation'
	import YAML from 'yaml'

	let search: string = ''

	export async function open(nsearch?: string) {
		isOpen = true
		await Promise.all([loadScripts(), loadResources(), loadApps(), loadFlows()])
		if (nsearch) {
			search = nsearch
		}
	}

	export async function loadScripts() {
		scripts = await ScriptService.listSearchScript({ workspace: $workspaceStore ?? '' })
	}

	export async function loadResources() {
		resources = await ResourceService.listSearchResource({ workspace: $workspaceStore ?? '' })
	}

	export async function loadApps() {
		apps = await AppService.listSearchApp({ workspace: $workspaceStore ?? '' })
	}

	export async function loadFlows() {
		flows = await FlowService.listSearchFlow({ workspace: $workspaceStore ?? '' })
	}

	let searchKind: 'all' | 'scripts' | 'flows' | 'apps' | 'resources' = 'all'

	let isOpen = false

	let scripts: undefined | { path: string; content: string }[] = undefined
	let filteredScriptItems: { path: string; content: string; marked: any }[] = []

	let resources: undefined | { path: string; value: any }[] = undefined
	let filteredResourceItems: { path: string; value: any; marked: any }[] = []

	let flows: undefined | { path: string; value: any }[] = undefined
	let filteredFlowItems: { path: string; value: any; marked: any }[] = []

	let apps: undefined | { path: string; value: any }[] = undefined
	let filteredAppItems: { path: string; value: any; marked: any }[] = []

	function getCounts(n: number) {
		return ` (${n})`
	}
	$: counts =
		search == '' ||
		!scripts ||
		!resources ||
		!flows ||
		!apps ||
		!filteredAppItems ||
		!filteredFlowItems ||
		!filteredResourceItems ||
		!filteredScriptItems
			? {
					all: '',
					apps: '',
					flows: '',
					resources: '',
					scripts: ''
			  }
			: {
					all: getCounts(
						filteredAppItems.length +
							filteredFlowItems.length +
							filteredResourceItems.length +
							filteredScriptItems.length
					),
					apps: getCounts(filteredAppItems.length),
					resources: getCounts(filteredResourceItems.length),
					flows: getCounts(filteredFlowItems.length),
					scripts: getCounts(filteredScriptItems.length)
			  }
</script>

<SearchItems
	filter={search}
	items={scripts}
	f={(s) => {
		return s.content
	}}
	bind:filteredItems={filteredScriptItems}
/>

<SearchItems
	filter={search}
	items={resources}
	f={(s) => {
		return YAML.stringify(s.value)
	}}
	bind:filteredItems={filteredResourceItems}
/>

<SearchItems
	filter={search}
	items={flows}
	f={(s) => {
		return YAML.stringify(s.value, null, 4)
	}}
	bind:filteredItems={filteredFlowItems}
/>

<SearchItems
	filter={search}
	items={apps}
	f={(s) => {
		return YAML.stringify(s.value, null, 4)
	}}
	bind:filteredItems={filteredAppItems}
/>

{#if isOpen}
	<Portal>
		<div
			class={twMerge(
				`fixed top-0 bottom-0 left-0 right-0 transition-all duration-50`,
				' bg-black bg-opacity-60',
				'z-[1100]'
			)}
		>
			<div
				class={'max-w-4xl lg:mx-auto mx-10 mt-8 bg-surface rounded-lg relative'}
				use:clickOutside={false}
				on:click_outside={() => {
					isOpen = false
				}}
			>
				<div class="px-4 py-2 border-b flex justify-between items-center">
					<div>Search by content</div>
					<div class="w-8">
						<button
							on:click|stopPropagation={() => {
								isOpen = false
							}}
							class="hover:bg-surface-hover bg-surface-secondary rounded-full w-8 h-8 flex items-center justify-center transition-all"
						>
							<X class="text-tertiary" />
						</button>
					</div>
				</div>
				<div class="px-2 py-2 overflow-auto">
					<div class="flex gap-2 flex-wrap">
						<div class="flex justify-start">
							<ToggleButtonGroup bind:selected={searchKind} class="h-10">
								<ToggleButton small light value="all" label={'All' + counts.all} />
								<ToggleButton
									small
									light
									value="scripts"
									icon={Code2}
									label={'Scripts' + counts.scripts}
								/>
								<ToggleButton
									small
									light
									value="resources"
									icon={Boxes}
									label={'Resources' + counts.resources}
								/>
								<ToggleButton
									small
									light
									value="flows"
									label={'Flows' + counts.flows}
									icon={FlowIcon}
									selectedColor="#14b8a6"
								/>
								<ToggleButton
									small
									light
									value="apps"
									label={'Apps' + counts.apps}
									icon={LayoutDashboard}
									selectedColor="#fb923c"
								/>
							</ToggleButtonGroup>
						</div>
						<div class="relative text-tertiary grow min-w-[100px]">
							<!-- svelte-ignore a11y-autofocus -->
							<input
								autofocus
								placeholder={'Search in the content of resources, scripts, flows and apps'}
								bind:value={search}
								class="bg-surface !h-10 !px-4 !pr-10 !rounded-lg text-sm focus:outline-none"
							/>
							<button type="submit" class="absolute right-0 top-0 mt-3 mr-4">
								<svg
									class="h-4 w-4 fill-current"
									xmlns="http://www.w3.org/2000/svg"
									xmlns:xlink="http://www.w3.org/1999/xlink"
									version="1.1"
									id="Capa_1"
									x="0px"
									y="0px"
									viewBox="0 0 56.966 56.966"
									style="enable-background:new 0 0 56.966 56.966;"
									xml:space="preserve"
									width="512px"
									height="512px"
								>
									<path
										d="M55.146,51.887L41.588,37.786c3.486-4.144,5.396-9.358,5.396-14.786c0-12.682-10.318-23-23-23s-23,10.318-23,23  s10.318,23,23,23c4.761,0,9.298-1.436,13.177-4.162l13.661,14.208c0.571,0.593,1.339,0.92,2.162,0.92  c0.779,0,1.518-0.297,2.079-0.837C56.255,54.982,56.293,53.08,55.146,51.887z M23.984,6c9.374,0,17,7.626,17,17s-7.626,17-17,17  s-17-7.626-17-17S14.61,6,23.984,6z"
									/>
								</svg>
							</button>
						</div>
					</div>
					<div class="mt-1">
						<div class="text-xs text-secondary"
							>Searching among <div class="inline-flex"
								>{#if scripts}{scripts?.length}{:else}
									<Loader2 size={10} class="animate-spin " />
								{/if}</div
							>
							scripts,
							<div class="inline-flex"
								>{#if resources}{resources?.length}{:else}
									<Loader2 size={10} class="animate-spin " />
								{/if}</div
							>
							resources,
							<div class="inline-flex"
								>{#if flows}{flows?.length}{:else}
									<Loader2 size={10} class="animate-spin " />
								{/if}</div
							>
							flows,
							<div class="inline-flex"
								>{#if apps}{apps?.length}{:else}
									<Loader2 size={10} class="animate-spin " />
								{/if}</div
							>
							apps</div
						>
					</div>

					<div class="mt-1 overflow-auto max-h-[80vh]">
						{#if !$enterpriseLicense}
							<div class="py-1" />

							<Alert title="Content Search is an EE feature" type="warning">
								Without EE, content search will only search among 10 scripts, 3 flows, 3 apps and 3
								resources.
							</Alert>
							<div class="py-1" />
						{/if}

						{#if search.length > 0}
							<div class="flex flex-col gap-4">
								{#if (searchKind == 'all' || searchKind == 'scripts') && filteredScriptItems?.length > 0}
									{#each filteredScriptItems ?? [] as item}
										<div>
											<div class="text-sm font-semibold"
												><a href="/scripts/get/{item.path}">Script: {item.path}</a></div
											>
											<div class="flex gap-2 justify-between">
												<pre class="text-xs border p-2 overflow-auto max-h-40 w-full max-w-2xl"
													><code>{@html item.marked}</code></pre
												>
												<div>
													<div class="flex gap-2">
														<Button
															on:click|once={() => {
																goto(`/scripts/edit/${item.path}?no_draft=true`)
															}}
															color="light"
															size="sm"
															startIcon={{ icon: Edit }}
														>
															Edit
														</Button>
													</div>
												</div>
											</div>
										</div>
									{/each}
								{/if}
								{#if (searchKind == 'all' || searchKind == 'resources') && filteredResourceItems?.length > 0}
									{#each filteredResourceItems ?? [] as item}
										<div>
											<div class="text-sm font-semibold">Resource: {item.path}</div>
											<div class="flex gap-2 justify-between">
												<pre class="text-xs border p-2 overflow-auto max-h-40 w-full max-w-2xl"
													><code>{@html item.marked}</code></pre
												>
											</div>
										</div>
									{/each}
								{/if}
								{#if (searchKind == 'all' || searchKind == 'flows') && filteredFlowItems?.length > 0}
									{#each filteredFlowItems ?? [] as item}
										<div>
											<div class="text-sm font-semibold"
												><a href="/flows/get/{item.path}">Flow: {item.path}</a></div
											>
											<div class="flex gap-2 justify-between">
												<pre class="text-xs border p-2 overflow-auto max-h-40 w-full max-w-2xl"
													><code>{@html item.marked}</code></pre
												>
												<div>
													<div class="flex gap-2">
														<Button
															on:click|once={() => {
																goto(`/flows/edit/${item.path}?no_draft=true`)
															}}
															color="light"
															size="sm"
															startIcon={{ icon: Edit }}>Edit</Button
														>
													</div>
												</div>
											</div>
										</div>
									{/each}
								{/if}
								{#if (searchKind == 'all' || searchKind == 'apps') && filteredAppItems?.length > 0}
									{#each filteredAppItems ?? [] as item}
										<div>
											<div class="text-sm font-semibold"
												><a href="/apps/get/{item.path}">App: {item.path}</a></div
											>
											<div class="flex gap-2 justify-between">
												<pre class="text-xs border p-2 overflow-auto max-h-40 w-full max-w-2xl"
													><code>{@html item.marked}</code></pre
												>
											</div>
										</div>
									{/each}
								{/if}
							</div>
						{:else}
							<div class="flex justify-center items-center h-48">
								<div class="text-tertiary text-center">
									<div class="text-2xl font-bold">Empty Search Filter</div>
									<div class="text-sm"
										>Start writing, search everywhere a path is referenced for instance</div
									>
								</div>
							</div>
						{/if}
					</div>
				</div></div
			></div
		></Portal
	>
{/if}
