<script lang="ts">
	import HighlightCode from './HighlightCode.svelte'
	import InputTransformsViewer from './InputTransformsViewer.svelte'
	import IconedPath from './IconedPath.svelte'
	import type { FlowModule } from '$lib/gen'
	import { Badge, Button, Drawer, DrawerContent } from './common'
	import { Highlight } from 'svelte-highlight'
	import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
	import typescript from 'svelte-highlight/languages/typescript'
	import FlowPathViewer from './flows/content/FlowPathViewer.svelte'
	import SchemaViewer from './SchemaViewer.svelte'
	import { scriptPathToHref } from '$lib/scripts'
	import { cleanExpr, copyToClipboard } from '$lib/utils'
	import { hubBaseUrlStore } from '$lib/stores'

	import { twMerge } from 'tailwind-merge'
	import FlowModuleScript from './flows/content/FlowModuleScript.svelte'
	import { Copy, Expand } from 'lucide-svelte'
	import HighlightTheme from './HighlightTheme.svelte'
	import LanguageIcon from './common/languageIcons/LanguageIcon.svelte'

	interface Props {
		schema?: any | undefined
		stepDetail?: FlowModule | string | undefined
		jobScriptHash?: string | undefined
		hideDefaultInputs?: boolean
	}

	let { schema = undefined, stepDetail = undefined, jobScriptHash = undefined, hideDefaultInputs = false }: Props = $props()
	let codeViewer: Drawer | undefined = $state()
</script>

<HighlightTheme />

<Drawer bind:this={codeViewer} size="900px">
	<DrawerContent title={'Expanded Code'} on:close={codeViewer?.closeDrawer}>
		{#if stepDetail && typeof stepDetail != 'string'}
			{#if stepDetail.value.type == 'script'}
				<div class="mb-4">
					<a
						rel="noreferrer"
						target="_blank"
						href={scriptPathToHref(stepDetail?.value?.path ?? '', $hubBaseUrlStore)}
						class=""
					>
						<IconedPath path={stepDetail?.value?.path ?? ''} />
					</a>
				</div>
				<div class="text-xs mb-4 mt-2">
					<h3 class="mb-1 text-xs font-semibold text-emphasis">Step inputs</h3>

					<InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
				</div>
				<div class="mt-6">
					<h3 class="mb-1 mt-6 text-xs font-semibold text-emphasis">Code</h3>
					<FlowModuleScript path={stepDetail.value.path} hash={jobScriptHash} />
				</div>
			{:else if stepDetail.value.type == 'rawscript'}
				<div class="text-2xs mb-4 mt-2">
					<h3 class="mb-1 text-xs font-semibold text-emphasis">Step inputs</h3>
					<InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
				</div>

				<div class="mb-1 mt-6 flex items-center gap-1">
					<h3 class="text-xs font-semibold text-emphasis">Code</h3>
					<LanguageIcon lang={stepDetail.value.language} size={14} />
				</div>
				<div class="!text-xs rounded-md p-2 border bg-surface-input">
					<HighlightCode language={stepDetail.value.language} code={stepDetail.value.content} />
				</div>
				<h3 class="mt-8 mb-1 text-xs font-normal text-primary">Lockfile</h3>
				<div>
					{#if stepDetail.value.lock}
						<pre class="bg-surface-secondary text-sm p-2 h-full overflow-auto w-full"
							>{stepDetail.value.lock}</pre
						>
					{:else}
						<p class="bg-surface-secondary text-sm p-2"> There is no lock file for this script </p>
					{/if}
				</div>
			{/if}
		{/if}
	</DrawerContent>
</Drawer>

<div class={twMerge('p-2 overflow-y-scroll')}>
	{#if stepDetail == undefined}
		<div>
			<p class="text-secondary text-xs italic px-2 pt-2">
				Click on a step to see its details
			</p>
			{#if schema && !hideDefaultInputs}
				<h3 class="mb-2 font-semibold">Flow Inputs</h3>
				<SchemaViewer {schema} />
			{/if}
		</div>
	{:else if stepDetail == 'Input'}
		{#if schema}
			<SchemaViewer {schema} />
		{:else}
			<p class="font-medium text-secondary text-center pt-4 pb-8"> No input schema </p>
		{/if}
	{:else if stepDetail == 'Result'}
		<p class="font-medium text-secondary text-center pt-4 pb-8"> End of the flow </p>
	{:else if typeof stepDetail != 'string' && stepDetail.value}
		<div class="">
			<div class="sticky top-0 bg-surface w-full flex items-center py-2">
				{#if stepDetail.id && stepDetail.id != 'failure' && stepDetail.id != 'preprocessor'}
					<Badge color="indigo">
						{stepDetail.id}
					</Badge>
				{/if}
				<span
					class={twMerge(
						'font-semibold text-emphasis text-sm',
						stepDetail.id !== 'failure' && stepDetail.id !== 'preprocessor' ? 'ml-2' : ''
					)}
				>
					{#if stepDetail.summary}
						{stepDetail.summary}
					{:else if stepDetail.value.type == 'identity'}
						Identity
					{:else if stepDetail.value.type == 'forloopflow'}
						For loop {#if stepDetail.value.parallel}(parallel){/if}
						{#if stepDetail.value.skip_failures}(skip failures){/if}
						{#if stepDetail.value.squash}(squash){/if}
					{:else if stepDetail.value.type == 'branchall'}
						Run all branches {#if stepDetail.value.parallel}(parallel){/if}
					{:else if stepDetail.value.type == 'branchone'}
						Run one branch
					{:else if stepDetail.value.type == 'flow'}
						Inner flow
					{:else if stepDetail.value.type == 'whileloopflow'}
						While loop {#if stepDetail.value.skip_failures}(skip failures){/if}
						{#if stepDetail.value.squash}(squash){/if}
					{:else if stepDetail.id === 'failure'}
						Error handler
					{:else if stepDetail.id === 'preprocessor'}
						Preprocessor
					{:else if stepDetail.value.type == 'rawscript'}
						Inline {stepDetail.value.language} script
					{:else if stepDetail.value.type == 'script'}
						Workspace script
					{:else if stepDetail.value.type == 'aiagent'}
						AI Agent
					{/if}
				</span>
			</div>
			{#if stepDetail.value.type == 'script'}
				<div class="pb-2">
					<a
						rel="noreferrer"
						target="_blank"
						href={scriptPathToHref(stepDetail?.value?.path ?? '', $hubBaseUrlStore)}
						class=""
					>
						<IconedPath path={stepDetail?.value?.path ?? ''} />
					</a>
				</div>
			{/if}
		</div>
		{#if stepDetail.value.type == 'identity'}
			<p class="font-medium text-secondary text-center pt-4 pb-8">
				An identity step returns its inputs as outputs
			</p>
		{:else if stepDetail.value.type == 'rawscript'}
			{#if stepDetail.id !== 'preprocessor'}
				<div class="text-xs">
					<h3 class="mb-1 font-semibold mt-2 text-xs text-emphasis">Step inputs</h3>
					<InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
				</div>
			{/if}

			<div>
				<div class="mb-1 mt-6 flex justify-between items-center">
					<div class="flex items-center gap-2">
						<h3 class="font-semibold text-xs text-emphasis">Code</h3>
						<LanguageIcon lang={stepDetail.value.language} width={14} height={14} />
					</div>
					<Button
						unifiedSize="sm"
						variant="subtle"
						onClick={codeViewer?.openDrawer}
						startIcon={{ icon: Expand }}>Expand</Button
					>
				</div>
				<div class="border p-2 rounded-md bg-surface-input">
					<HighlightCode
						language={stepDetail.value.language}
						code={stepDetail.value.content}
						className="whitespace-pre-wrap"
					/>
				</div>
				<h3 class="mb-1 mt-6 text-xs font-semibold text-emphasis">Lockfile</h3>
				<div>
					{#if stepDetail.value.lock}
						<pre class="bg-surface-input rounded-md border text-xs p-2 h-full overflow-auto w-full"
							>{stepDetail.value.lock}</pre
						>
					{:else}
						<p class="bg-surface-secondary text-xs italic p-2 rounded">
							There is no lockfile for this inline script
						</p>
					{/if}
				</div>
			</div>
		{:else if stepDetail.value.type == 'script'}
			{#if stepDetail.id !== 'preprocessor'}
				<div class="text-xs">
					<h3 class="mb-1 font-semibold mt-2 text-xs text-emphasis">Step inputs</h3>
					<InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
				</div>
			{/if}
			<div class="mb-1 mt-6 flex justify-between items-center">
				<h3 class="font-semibold text-xs text-emphasis">Code</h3>
				<Button
					unifiedSize="sm"
					variant="subtle"
					onClick={codeViewer?.openDrawer}
					startIcon={{ icon: Expand }}>Expand</Button
				>
			</div>
			<FlowModuleScript path={stepDetail.value.path} hash={jobScriptHash} />
		{:else if stepDetail.value.type == 'aiagent'}
			<div class="text-xs">
				<h3 class="mb-1 font-semibold mt-2 text-xs text-emphasis">Step inputs</h3>
				<InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
			</div>
		{:else if stepDetail.value.type == 'forloopflow'}
			<div>
				<p class="font-medium text-secondary pb-2"> Iterator expression: </p>
				{#if stepDetail.value.iterator.type == 'static'}
					<ObjectViewer json={stepDetail.value.iterator.value} />
				{:else if stepDetail.value.iterator.type == 'javascript'}
					<span class="text-xs">
						<Highlight language={typescript} code={cleanExpr(stepDetail.value.iterator.expr)} />
					</span>
				{/if}
			</div>
		{:else if stepDetail.value.type == 'whileloopflow'}
			<div>
				{#if stepDetail.stop_after_if}
					<p class="font-medium text-secondary pb-2 pt-4">Stop after if expr:: </p>
					<span class="text-xs">
						<Highlight language={typescript} code={cleanExpr(stepDetail.stop_after_if?.expr)} />
					</span>
				{/if}
			</div>
			<div>
				{#if stepDetail.stop_after_all_iters_if}
					<p class="font-medium text-secondary pb-2 pt-4">Stop after all iters if expr:: </p>
					<span class="text-xs">
						<Highlight
							language={typescript}
							code={cleanExpr(stepDetail.stop_after_all_iters_if?.expr)}
						/>
					</span>
				{/if}
			</div>
		{:else if stepDetail.value.type == 'branchall'}
			<p class="font-medium text-secondary text-center pt-4 pb-8">
				All branches will run, regardless of the inputs
			</p>
		{:else if stepDetail.value.type == 'branchone'}
			<p class="font-medium text-secondary text-center pt-4 pb-8">
				Only one branch will run based on a predicate
			</p>
			<div class="flex-col flex gap-2">
				<div class="flex flex-row gap-4 text-sm p-2">
					<Badge large={true} color="blue">Default branch</Badge>
					<p class="italic text-primary"
						>If none of the predicates' expressions evaluated in-order match, this branch is chosen</p
					>
				</div>
				{#each stepDetail.value.branches as v, i}
					<div class="flex flex-col gap-4-2 items-center">
						<div class="w-full flex gap-2 px-2 pt-4 pb-2">
							<Badge large={true} color="blue">Branch {i + 1}</Badge>
							<span>{v.summary}</span>
						</div>
						<div class="w-full border p-2">
							<HighlightCode language="frontend" code={v.expr} />
						</div>
					</div>
				{/each}
			</div>
		{:else if stepDetail.value.type == 'flow'}
			<div class="text-sm mb-1 flex justify-between flex-row items-center">
				<span class="text-xs font-normal text-secondary"
					>Flow path: <span class="text-emphasis">{stepDetail.value.path}</span>
				</span>
				<Button
					unifiedSize="sm"
					startIcon={{ icon: Copy }}
					variant="subtle"
					on:click={() => {
						if (typeof stepDetail !== 'string') {
							const val = stepDetail?.value
							if (val?.type == 'flow') {
								copyToClipboard(val.path)
							}
						}
					}}
				>
					Copy path
				</Button>
			</div>
			<FlowPathViewer noSide path={stepDetail.value.path} />
		{/if}
	{:else}
		<p class="font-medium text-secondary text-center pt-4 pb-8">
			Step {stepDetail} selected
		</p>
	{/if}
</div>
