<script lang="ts">
	import { getContext } from 'svelte'
	import type { AppEditorContext, AppViewerContext, HiddenRunnable } from '../../types'
	import { Pane, Splitpanes } from 'svelte-splitpanes'
	import InlineScriptsPanelList from './InlineScriptsPanelList.svelte'
	import InlineScriptEditor from './InlineScriptEditor.svelte'
	import InlineScriptsPanelWithTable from './InlineScriptsPanelWithTable.svelte'
	import { findGridItem } from '../appUtils'
	import InlineScriptHiddenRunnable from './InlineScriptHiddenRunnable.svelte'
	import { BG_PREFIX } from '../../utils'
	import { sendUserToast } from '$lib/toast'
	import type { RunnableByName } from '../../inputType'
	import { ScriptService } from '$lib/gen'
	import { workspaceStore } from '$lib/stores'
	import { findNextAvailablePath } from '$lib/path'
	import { twMerge } from 'tailwind-merge'

	const { app, runnableComponents } = getContext<AppViewerContext>('AppViewerContext')
	const { selectedComponentInEditor } = getContext<AppEditorContext>('AppEditorContext')

	function deleteBackgroundScript(index: number) {
		// remove the script from the array at the index
		if ($app.hiddenInlineScripts.length - 1 == index) {
			$app.hiddenInlineScripts.splice(index, 1)
			$app.hiddenInlineScripts = [...$app.hiddenInlineScripts]
		} else {
			$app.hiddenInlineScripts[index] = {
				hidden: true,
				inlineScript: undefined,
				name: `Background Runnable ${index}`,
				fields: {},
				type: 'runnableByName',
				recomputeIds: undefined
			}
			$app.hiddenInlineScripts = $app.hiddenInlineScripts
		}

		$selectedComponentInEditor = undefined
		delete $runnableComponents[BG_PREFIX + index]
		$runnableComponents = $runnableComponents
	}

	$: gridItem =
		$selectedComponentInEditor && !$selectedComponentInEditor.startsWith(BG_PREFIX)
			? findGridItem($app, $selectedComponentInEditor?.split('_')?.[0])
			: undefined

	$: hiddenInlineScript = $app?.hiddenInlineScripts?.findIndex((k_, index) => {
		const [prefix, id] = $selectedComponentInEditor?.split('_') || []

		if (prefix !== 'bg') return false

		return Number(id) === index
	})

	$: unusedInlineScript = $app?.unusedInlineScripts?.findIndex(
		(k_, index) => `unused-${index}` === $selectedComponentInEditor
	)

	async function createScriptFromInlineScript(
		id: string,
		runnable: HiddenRunnable | RunnableByName
	) {
		if (runnable.type != 'runnableByName') {
			sendUserToast('Only inline scripts can be saved to workspace', true)
			return
		}
		if (!runnable.inlineScript) {
			sendUserToast('No inline script found', true)
			return
		}
		let path = `${runnable.inlineScript.path}/inline_${id}`
		path = await findNextAvailablePath(path)
		let language = runnable.inlineScript.language
		if (language == 'frontend') {
			sendUserToast('Frontend scripts can not be saved to workspace', true)
			return
		}
		await ScriptService.createScript({
			workspace: $workspaceStore!,
			requestBody: {
				path: path,
				summary: runnable.name ?? '',
				description: '',
				content: runnable.inlineScript.content,
				parent_hash: undefined,
				schema: runnable.inlineScript.schema,
				is_template: false,
				language: language!
			}
		})

		Object.assign(runnable, {
			type: 'runnableByPath',
			schema: runnable.inlineScript.schema,
			runType: 'script',
			recomputeIds: undefined,
			path
		})

		$app = $app
	}

	export let width: number | undefined = undefined
</script>

<Splitpanes
	class={twMerge('!overflow-visible')}
	style={width !== undefined ? `width:${width}px;` : 'width: 100%;'}
>
	<Pane size={25}>
		<InlineScriptsPanelList on:hidePanel />
	</Pane>
	<Pane size={75}>
		{#if !$selectedComponentInEditor}
			<div class="text-sm text-secondary text-center py-8 px-2">
				Select a script on the left panel
			</div>
		{:else if gridItem}
			{#key gridItem?.id}
				<InlineScriptsPanelWithTable
					on:createScriptFromInlineScript={(e) => {
						createScriptFromInlineScript(gridItem?.id ?? 'unknown', e.detail)
					}}
					bind:gridItem
				/>
			{/key}
		{:else if unusedInlineScript > -1 && $app.unusedInlineScripts?.[unusedInlineScript]}
			{#key unusedInlineScript}
				<InlineScriptEditor
					on:createScriptFromInlineScript={() =>
						sendUserToast('Cannot save to workspace unused scripts', true)}
					id={`unused-${unusedInlineScript}`}
					bind:name={$app.unusedInlineScripts[unusedInlineScript].name}
					bind:inlineScript={$app.unusedInlineScripts[unusedInlineScript].inlineScript}
					on:delete={() => {
						// remove the script from the array at the index
						$app.unusedInlineScripts.splice(unusedInlineScript, 1)
						$app.unusedInlineScripts = [...$app.unusedInlineScripts]
					}}
				/>
			{/key}
		{:else if hiddenInlineScript > -1}
			{#key hiddenInlineScript}
				{#if $app.hiddenInlineScripts?.[hiddenInlineScript]}
					<InlineScriptHiddenRunnable
						on:createScriptFromInlineScript={(e) => {
							createScriptFromInlineScript(BG_PREFIX + hiddenInlineScript, e.detail)
						}}
						transformer={$selectedComponentInEditor?.endsWith('_transformer')}
						on:delete={() => deleteBackgroundScript(hiddenInlineScript)}
						id={BG_PREFIX + hiddenInlineScript}
						bind:runnable={$app.hiddenInlineScripts[hiddenInlineScript]}
					/>{/if}{/key}
		{:else}
			<div class="text-sm text-tertiary text-center py-8 px-2">
				No script found at id {$selectedComponentInEditor}
			</div>
		{/if}
	</Pane>
</Splitpanes>
