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

	const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
	const dispatch = createEventDispatcher()

	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: 'Flow builder tutorial',
				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: 'input[placeholder="Field name"]',
			popover: {
				title: 'Name your property',
				description: 'Give a name to your property. Here we will call it firstname',
				onNextClick: () => {
					setInputBySelector('input[placeholder="Field name"]', 'firstname')
					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '#flow-editor-add-property',
			popover: {
				title: 'Add your property',
				description: 'Click here to save your property',
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-add-property')
					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: () => {
					triggerPointerDown(`#flow-editor-add-step-0`)
					setTimeout(() => {
						driver.moveNext()
					})
				}
			}
		},
		{
			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: () => {
					triggerPointerDown('#flow-editor-insert-module > div > div > button:nth-child(1)')

					setTimeout(() => {
						driver.moveNext()
					})
				}
			},
			element: '#flow-editor-insert-module > div > div > button:nth-child(1)'
		},
		{
			element: '#flow-editor-flow-providers',
			popover: {
				title: 'Action configuration',
				description: 'An action can be inlined, imported from your workspace or the Hub.'
			}
		},
		{
			element: '#flow-editor-flow-atoms',
			popover: {
				title: 'Supported languages',
				description: 'Windmill support the following languages/runtimes.'
			}
		},
		{
			element: '#flow-editor-new-bun',
			popover: {
				title: 'Typescript',
				description: "Let's write a script for your flow",
				onNextClick: () => {
					clickButtonBySelector('#flow-editor-new-bun')
					waitForElementLoading('#flow-editor-editor', () => {
						driver.moveNext()
					})
				}
			}
		},
		{
			element: '#flow-editor-editor',
			popover: {
				title: 'Action editor',
				description: 'Windmill provides a full code editor to write your actions',
				onPrevClick: () => {
					triggerPointerDown(`#flow-editor-add-step-0`)
					setTimeout(() => {
						driver.movePrevious()
					})
				}
			}
		},
		{
			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)
					})
				}
			}
		}
	]}
/>
