<script lang="ts">
	import { createEventDispatcher, getContext } from 'svelte'
	import type { FlowEditorContext } from '../flows/types'
	import { updateProgress } from '$lib/tutorialUtils'
	import {
		clickButtonBySelector,
		isFlowTainted,
		selectFlowStepKind,
		setInputBySelector,
		triggerAddFlowStep
	} from './utils'
	import Tutorial from './Tutorial.svelte'

	const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
	const dispatch = createEventDispatcher()
	const queue: string[] = []

	let tutorial: Tutorial | undefined = undefined

	export function runTutorial() {
		tutorial?.runTutorial()
	}
</script>

<Tutorial
	bind:this={tutorial}
	index={0}
	name="action"
	tainted={isFlowTainted($flowStore)}
	on:error
	on:skipAll
	getSteps={(driver) => [
		{
			popover: {
				title: 'Welcome to the Windmil Flow editor',
				description:
					'Learn how to build powerful flows in a few steps. You can use arrow keys to navigate.'
			}
		},
		{
			popover: {
				title: 'Flows inputs',
				description: 'Flows have inputs that can be used in the flow',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-virtual-Input')
					setTimeout(() => {
						driver.moveNext()
					})
				}
			},
			element: '#svelvet-Input'
		},
		{
			element: '#flow-editor-add-property',
			popover: {
				title: 'Add a property',
				description: 'Click here to add a property to your schema',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-add-property')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '#schema-modal-name',
			popover: {
				title: 'Name your property',
				description: 'Give a name to your property. Here we will call it firstname',
				onNextClick: () => {
					setInputBySelector('#schema-modal-name', 'firstname')

					driver.moveNext()
				}
			}
		},
		{
			element: '#schema-modal-save',
			popover: {
				title: 'Save your property',
				description: 'Click here to save your property',
				onNextClick: () => {
					queue.push(JSON.stringify($flowStore))

					clickButtonBySelector('#schema-modal-save')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '#flow-editor-add-step-0',
			popover: {
				title: 'Add a step',
				description: 'Click here to add a step to your flow',
				onNextClick: () => {
					triggerAddFlowStep(0)

					setTimeout(() => {
						driver.moveNext()
					})
				},

				onPrevClick: () => {
					driver.moveTo(1)
					$flowStore = JSON.parse(queue.pop() || '{}')
					dispatch('reload')
				}
			}
		},

		{
			popover: {
				title: 'Steps kind',
				description: "Choose the kind of step you want to add. Let's start with a simple action"
			},
			element: '#flow-editor-insert-module'
		},
		{
			popover: {
				title: 'Pick an action',
				description: 'Let’s pick an action to add to your flow',
				onNextClick: () => {
					selectFlowStepKind(1)

					setTimeout(() => {
						driver.moveNext()
					})
				}
			},
			element: '#flow-editor-insert-module > div > button:nth-child(1)'
		},
		{
			element: '#flow-editor-flow-inputs',
			popover: {
				title: 'Action configuration',
				description: 'An action can be inlined, imported from your workspace or the Hub.'
			}
		},
		{
			element: '#flow-editor-action-script',
			popover: {
				title: 'Supported languages',
				description: 'Windmill support the following languages/runtimes.'
			}
		},
		{
			element: '#flow-editor-action-script > button:nth-child(1)',
			popover: {
				title: 'Typescript',
				description: "Let's pick an action to add to your flow",
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-action-script > button > div > button:nth-child(1)')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},

		{
			element: '#flow-editor-editor',
			popover: {
				title: 'Action editor',
				description: 'Windmill provides a full code editor to write your actions'
			}
		},

		{
			element: '#flow-editor-step-input',
			popover: {
				title: 'Autogenerated schema',
				description: 'The schema and the UI is autogenerated from your code'
			}
		},

		{
			element: '#flow-editor-plug',
			popover: {
				title: 'Connect',
				description:
					'You can provide static values or connect to other nodes result. Here we will connect to the firstname input',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-plug')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '.key',
			popover: {
				title: 'Connection mode',
				description: 'Once you pressed the connect button, you can choose what to connect to.',
				onNextClick: () => {
					if ($flowStore.value.modules[0].value.type === 'rawscript') {
						$flowStore.value.modules[0].value.input_transforms = {
							x: {
								type: 'javascript',
								expr: 'flow_input.firstname'
							}
						}
					}

					$flowStore = $flowStore
					dispatch('reload')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},

		{
			element: '#flow-editor-step-input',
			popover: {
				title: 'Input connected!',
				description: 'The input is now connected to the firstname input'
			}
		},

		{
			element: '#flow-editor-test-flow',
			popover: {
				title: 'Test your flow',
				description: 'We can now test our flow',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-test-flow')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},

		{
			element: '#flow-preview-content',
			popover: {
				title: 'Flow input',
				description: 'Let’s provide an input to our flow',
				onNextClick: () => {
					setInputBySelector('textarea.w-full', 'Hello World!')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '#flow-editor-test-flow-drawer',
			popover: {
				title: 'Test your flow',
				description: 'Finally we can test our flow, and view the results!',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-test-flow-drawer')

					setTimeout(() => {
						driver.moveNext()

						updateProgress(0)
					})
				}
			}
		}
	]}
/>
