<script lang="ts" setup>
import { computed, nextTick, ref, watch } from 'vue'

import InputTab from '@/features/RunWorkflow/components/InputTab.vue'
import Chat from './Chat.vue'
import ResizableDrawer from '@/components/ResizableDrawer/index.vue'
import { useI18n } from '@/composables/useI18n'
import { Icon, IconButton } from '@repo/ui'

import type { IWorkflow, IWorkflowNode } from '@repo/workflow'
import type { StartVariable } from '@/nodes/src/start'

const props = withDefaults(
	defineProps<{
		visible: boolean
		workflow: IWorkflow
		startNode: IWorkflowNode | null
		visibleVariables: StartVariable[]
		inputValues: Record<string, any>
		jsonDrafts: Record<string, string>
		validationErrors: Record<string, string>
		baseParams: Record<string, any>
		isRunning: boolean
	}>(),
	{
		visible: false,
		startNode: null,
		baseParams: () => ({})
	}
)

const emit = defineEmits<{
	'update:visible': [value: boolean]
	'validate-send': [done: (params: Record<string, any> | false) => void]
	'run-started': [nodeId: string]
	cancel: []
}>()

const { t } = useI18n()
const showForm = ref(false)
const chatContainerRef = ref<InstanceType<typeof Chat>>()
const hasVisibleForm = computed(() => props.visibleVariables.length > 0)

const closeDrawer = () => {
	handleDrawerUpdate(false)
}

const handleValidateSend = () =>
	new Promise<Record<string, any> | false>((resolve) => {
		emit('validate-send', resolve)
	})

const handleDrawerUpdate = (value: boolean) => {
	if (!value) {
		handleCancel()
	}
	emit('update:visible', value)
}

const handleFirstSend = () => {
	if (hasVisibleForm.value) {
		showForm.value = false
	}
}

const handleResetConversation = () => {
	chatContainerRef.value?.resetConversation?.()
	if (hasVisibleForm.value) {
		showForm.value = true
	}
}

const handleCancel = () => {
	emit('cancel')
}

watch(
	() => [props.visible, hasVisibleForm.value],
	([visible, hasForm]) => {
		if (!visible) return
		showForm.value = !!hasForm
	},
	{ immediate: true }
)

defineExpose({
	scrollToBottom: () => {
		nextTick(() => {
			chatContainerRef.value?.scrollToBottom?.()
		})
	}
})
</script>

<template>
	<div class="chat-drawer">
		<ResizableDrawer
			:visible="visible"
			:default-width="520"
			:min-width="420"
			:max-width-ratio="0.82"
			:z-index="1002"
			class="chat-drawer__panel"
		>
			<header class="chat-drawer__header">
				<h4>{{ t('pages.runWorkflow.chatDialogTitle') }}</h4>
				<span class="flex items-center gap-16px">
					<!-- 重置按钮 -->
					<Icon
						icon="lucide:refresh-ccw"
						height="18"
						width="18"
						class="cursor-pointer"
						@click="handleResetConversation"
					/>
					<!-- 展示/隐藏表单 -->
					<IconButton
						v-if="hasVisibleForm"
						icon="lucide:sliders-horizontal"
						:type="showForm ? 'primary' : 'default'"
						:icon-color="showForm ? '#fff' : undefined"
						height="18"
						width="18"
						@click="showForm = !showForm"
						size="small"
						square
					/>
					<!-- 关闭 -->
					<Icon
						icon="lucide:x"
						height="18"
						width="18"
						class="cursor-pointer"
						@click="closeDrawer"
					/>
				</span>
			</header>

			<div class="chat-drawer__body">
				<div v-if="hasVisibleForm && showForm" class="chat-drawer__form">
					<el-card>
						<InputTab
							:start-node="startNode"
							:visible-variables="visibleVariables"
							:input-values="inputValues"
							:json-drafts="jsonDrafts"
							:validation-errors="validationErrors"
							:is-running="isRunning"
							:show-action-bar="false"
							:paneStyle="{ height: 'auto' }"
						/>
					</el-card>
				</div>

				<div class="chat-drawer__chat">
					<Chat
						ref="chatContainerRef"
						:node="startNode || undefined"
						:workflow-id="workflow.id"
						:base-params="baseParams"
						:validate-before-send="handleValidateSend"
						:on-first-send="handleFirstSend"
						show-workflow-trace
						@run-started="emit('run-started', $event)"
					/>
				</div>
			</div>
		</ResizableDrawer>
	</div>
</template>

<style lang="less" scoped>
.chat-drawer {
	z-index: 1002;
}

.chat-drawer__header {
	height: 66px;
	padding: 16px 16px 0;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	color: var(--text-primary);

	h4 {
		margin: 0;
		font-size: 15px;
		font-weight: 600;
	}
}

.chat-drawer__body {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
	overflow: hidden;
	border-radius: 8px;
	overflow-y: auto;
}

.chat-drawer__form {
	padding: 12px;
	flex-shrink: 0;
	max-height: 60%;
	overflow-y: auto;
}

.chat-drawer__chat {
	flex: 1;
	min-height: 0;
}
</style>
