<template>
	<div class="w-full h-full flex flex-col">
		<div
			class="h-60px shrink-0 border-b border-b-solid border-gray-200 flex items-center justify-between px-12px"
		>
			<div class="left flex items-center gap-4">
				<el-breadcrumb separator="/">
					<el-breadcrumb-item>Workspace</el-breadcrumb-item>
					<el-breadcrumb-item>workflow_1</el-breadcrumb-item>
				</el-breadcrumb>
				<IconButton icon="iconoir:plus" type="primary" link>标签</IconButton>
			</div>
			<div class="right flex items-center gap-2">
				<el-button type="default" size="small">发布</el-button>
				<IconButton icon="lucide:history" type="default" link></IconButton>
				<el-dropdown placement="bottom-end" popper-class="w-120px">
					<IconButton icon="fluent-mdl2:more" type="default" link></IconButton>
					<template #dropdown>
						<el-dropdown-item>描述</el-dropdown-item>
						<el-dropdown-item>复用</el-dropdown-item>
						<el-dropdown-item>重命名</el-dropdown-item>
						<el-dropdown-item divided>删除</el-dropdown-item>
					</template>
				</el-dropdown>
			</div>
		</div>
		<el-splitter layout="vertical" class="flex-1">
			<el-splitter-panel>
				<Workflow
					:workflow="workflow"
					@click:node="handleNodeClick"
					@create:node="handleNodeCreate"
					@create:connection="onCreateConnection"
					@drop="handleDrop"
					@run="handleRunWorkflow"
					@update:nodes:position="handleUpdateNodesPosition"
					@update:node:attrs="handleUpdateNodeProps"
					class="bg-#f5f5f5"
				/>
				<RunWorkflow v-model:visible="runVisible" />
				<Setter
					:id="nodeID"
					:workflow="workflow"
					@update:node:data="hangleUpdateNodeData"
					v-model:visible="setterVisible"
				/>
			</el-splitter-panel>

			<el-splitter-panel v-model:size.lazy="footerHeight" :min="32">
				<EditorFooter @toggle="handleFooterToggle" />
			</el-splitter-panel>
		</el-splitter>
	</div>
</template>

<script setup lang="ts">
import { ref, inject, type CSSProperties, onBeforeUnmount } from 'vue'
import { startNode, endNode, httpNode, conditionNode, databaseNode, codeNode } from '@repo/nodes'
import { Workflow, type IWorkflow, type XYPosition, type Connection } from '@repo/workflow'
import { v4 as uuid } from 'uuid'

import Setter from '@/components/setter/index.vue'
import RunWorkflow from '@/components/RunWorkflow/index.vue'
import EditorFooter from '@/features/editorFooter/index.vue'

import { IconButton } from '@repo/ui'

import type { SourceType } from '@repo/nodes'

const layout = inject<{ setMainStyle: (style: CSSProperties) => void }>('layout')

layout?.setMainStyle({
	padding: '0px'
})

const footerHeight = ref(32)

const workflow = ref<IWorkflow>({
	id: uuid(),
	nodes: [startNode, endNode],
	edges: []
})

/**
 * Editor
 */
const handleFooterToggle = (open: boolean) => {
	footerHeight.value = open ? 200 : 32
}

/**
 * Workflow
 */
const nodeID = ref('')
const setterVisible = ref(false)
const runVisible = ref(false)
const handleRunWorkflow = () => {
	runVisible.value = true
	console.log('run workflow')
}
const handleNodeCreate = (value: SourceType | string) => {
	const id = uuid()
	if (typeof value === 'string') {
		if (value === 'stickyNote') {
			workflow.value.nodes.push({
				id,
				type: 'canvas-node',
				zIndex: -1,
				position: { x: 600, y: 300 },
				data: {
					id,
					version: ['1.0.0'],
					inputs: [],
					outputs: [],
					renderType: 'stickyNote',
					content: '注释内容，可以使用 **Markdown** 语法进行格式化, 双击进入编辑。',
					width: 400,
					height: 200,
					color: '#fff5d6'
				}
			})
		}
		return
	}

	const nodeMap: Record<string, any> = {
		start: startNode,
		end: endNode,
		http: httpNode,
		condition: conditionNode,
		code: codeNode,
		database: databaseNode
	}
	const nodeToAdd = nodeMap[value.type]

	// 如果存在对应节点则添加
	if (nodeToAdd) {
		workflow.value.nodes.push({
			...nodeToAdd,
			data: {
				...nodeToAdd.data,
				id
			},
			zIndex: 1,
			id: uuid()
		})
	}
	console.log(workflow.value.nodes, 'workflow.nodes')
}
const handleNodeClick = (id: string, position: XYPosition) => {
	nodeID.value = id
	setterVisible.value = true
}

const handleDrop = (position: XYPosition, event: DragEvent) => {
	console.log('drag and drop at', position, event)
}

/**
 * 创建连线
 */
const onCreateConnection = (connection: Connection) => {
	const { source, target } = connection

	if (!workflow.value.edges.some((edge) => edge.source === source && edge.target === target)) {
		workflow.value.edges.push({
			id: `edge-${source}-${target}`,
			source,
			target,
			type: 'canvas-edge',
			data: {}
		})
	}
}

/**
 * 移动位置
 */
const handleUpdateNodesPosition = (events: { id: string; position: XYPosition }[]) => {
	events?.forEach(({ id, position }) => {
		const node = workflow.value.nodes.find((node) => node.id === id)
		if (node) {
			node.position = position
		}
	})
}

/**
 * 修改节点数据
 */
const hangleUpdateNodeData = (id: string, data: any) => {
	const node = workflow.value.nodes.find((node) => node.id === id)
	if (node) {
		node.data = {
			...node.data,
			...data
		}
	}
	console.log('hangleUpdateNodeData', id, data)
}

/**
 * 修改节点属性
 */
const handleUpdateNodeProps = (id: string, attrs: Record<string, unknown>) => {
	const node = workflow.value.nodes.find((node) => node.id === id)
	if (node) {
		if (node.data?.renderType === 'stickyNote') {
			Object.assign(node.data, attrs)
		} else {
			Object.assign(node, attrs)
		}
	}
}

onBeforeUnmount(() => {
	layout?.setMainStyle({})
})
</script>
