<template>
	<div class="crew-editor">
		<!-- 顶部工具栏 -->
		<div class="toolbar">
			<el-select v-model="selectedCrewId" placeholder="选择集群" @change="onCrewChange" style="width: 200px">
				<el-option v-for="c in crewStore.crewList" :key="c.id" :label="c.label" :value="c.id" />
			</el-select>
			<el-button @click="onNewCrew">新建集群</el-button>
			<el-divider direction="vertical" />
			<el-button type="primary" @click="onSave" :loading="saving">保存</el-button>
			<el-button v-if="crewStore.currentCrew?.status === 0" type="success" @click="onPublish">发布</el-button>
			<el-button v-else-if="crewStore.currentCrew?.status === 1" type="warning" @click="onUnpublish">取消发布</el-button>
			<el-button @click="onTestRun" :disabled="crewStore.currentCrew?.status !== 1">试运行</el-button>
		</div>

		<!-- 主体：左侧栏 + 画布 -->
		<div class="main-area">
			<crew-sidebar
				:agents="crewStore.availableAgents"
				:is-member="crewStore.isMember"
			/>

			<div class="canvas-container" @drop="onDrop" @dragover.prevent>
				<VueFlow
					:nodes="canvasHook.nodes.value"
					:edges="canvasHook.edges.value"
					@node-click="onNodeClick"
					@edge-click="onEdgeClick"
					@pane-click="onPaneClick"
					@connect="onConnect"
					@node-context-menu="onNodeContextMenu"
					@edge-context-menu="onEdgeContextMenu"
					@pane-context-menu="onPaneContextMenu"
				>
					<template #node-crew-agent="{ data }">
						<crew-agent-node :data="data" />
					</template>

					<MiniMap />
					<Controls />
					<Background />
				</VueFlow>

				<!-- 右键菜单 -->
				<crew-context-menu
					:visible="contextMenu.visible"
					:x="contextMenu.x"
					:y="contextMenu.y"
					:target-node="contextMenu.targetNode"
					:target-edge="contextMenu.targetEdge"
					@set-master="onSetMaster(contextMenu.targetNode?.data?.agentId)"
					@remove-node="onRemoveNode(contextMenu.targetNode?.data?.agentId)"
					@delete-edge="onDeleteEdge(contextMenu.targetEdge?.id)"
					@auto-layout="onAutoLayout"
					@fit-view="canvasHook.fitView({ padding: 0.2 })"
					@close="contextMenu.visible = false"
				/>
			</div>
		</div>

		<!-- 底部属性面板 -->
		<crew-property-panel
			:selected-type="selectedType"
			:selected-node="selectedNode"
			:selected-edge="selectedEdge"
			:crew="crewStore.currentCrew"
			@update:crew="onUpdateCrew"
			@update:node="() => {}"
			@update:edge="() => {}"
		/>
	</div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { VueFlow } from '@vue-flow/core';
import { MiniMap } from '@vue-flow/minimap';
import { Controls } from '@vue-flow/controls';
import { Background } from '@vue-flow/background';
import '@vue-flow/core/dist/style.css';
import '@vue-flow/core/dist/theme-default.css';
import '@vue-flow/minimap/dist/style.css';
import '@vue-flow/controls/dist/style.css';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useCrewStore } from '../store/crew';
import { useCrewCanvas } from '../hooks/crew-canvas';
import { canvasToHints } from '../hooks/crew-orchestration';
import CrewSidebar from '../components/crew/crew-sidebar.vue';
import CrewAgentNode from '../components/crew/crew-agent-node.vue';
import CrewPropertyPanel from '../components/crew/crew-property-panel.vue';
import CrewContextMenu from '../components/crew/crew-context-menu.vue';

const router = useRouter();
const crewStore = useCrewStore();
const canvasHook = useCrewCanvas();

const selectedCrewId = ref<number | null>(null);
const selectedNode = ref<any>(null);
const selectedEdge = ref<any>(null);
const selectedType = ref<'node' | 'edge' | 'none'>('none');
const saving = ref(false);

const contextMenu = reactive({
	visible: false,
	x: 0,
	y: 0,
	targetNode: null as any,
	targetEdge: null as any,
});

onMounted(async () => {
	await crewStore.loadCrewList();
	await crewStore.loadAvailableAgents();
});

async function onCrewChange(crewId: number) {
	const detail = await crewStore.loadCrewDetail(crewId);
	if (detail?.canvasData) canvasHook.deserializeCanvas(detail.canvasData);
	if (detail?.masterAgentId) canvasHook.setMasterAgent(detail.masterAgentId);
}

function onNodeClick({ node }: any) {
	selectedNode.value = node;
	selectedEdge.value = null;
	selectedType.value = 'node';
	contextMenu.visible = false;
}

function onEdgeClick({ edge }: any) {
	selectedEdge.value = edge;
	selectedNode.value = null;
	selectedType.value = 'edge';
	if (!edge.data) edge.data = { edgeType: 'serial', note: '' };
	contextMenu.visible = false;
}

function onPaneClick() {
	selectedNode.value = null;
	selectedEdge.value = null;
	selectedType.value = 'none';
	contextMenu.visible = false;
}

function onConnect(params: any) {
	canvasHook.edges.value.push({
		...params,
		id: `e-${params.source}-${params.target}`,
		data: { edgeType: 'serial', note: '' },
	});
}

function onDrop(event: DragEvent) {
	const data = event.dataTransfer?.getData('application/crew-agent');
	if (!data) return;
	const agent = JSON.parse(data);
	const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();
	canvasHook.addAgentNode(agent, {
		x: event.clientX - rect.left,
		y: event.clientY - rect.top,
	});
}

function onNodeContextMenu({ event, node }: any) {
	event.preventDefault();
	contextMenu.visible = true;
	contextMenu.x = event.clientX;
	contextMenu.y = event.clientY;
	contextMenu.targetNode = node;
	contextMenu.targetEdge = null;
}

function onEdgeContextMenu({ event, edge }: any) {
	event.preventDefault();
	contextMenu.visible = true;
	contextMenu.x = event.clientX;
	contextMenu.y = event.clientY;
	contextMenu.targetEdge = edge;
	contextMenu.targetNode = null;
}

function onPaneContextMenu(event: MouseEvent) {
	event.preventDefault();
	contextMenu.visible = true;
	contextMenu.x = event.clientX;
	contextMenu.y = event.clientY;
	contextMenu.targetNode = null;
	contextMenu.targetEdge = null;
}

function onSetMaster(agentId: number) {
	if (!agentId) return;
	canvasHook.setMasterAgent(agentId);
	if (crewStore.currentCrew) crewStore.currentCrew.masterAgentId = agentId;
	contextMenu.visible = false;
	ElMessage.success('已设为主 Agent');
}

function onRemoveNode(agentId: number) {
	if (!agentId) return;
	canvasHook.removeAgentNode(agentId);
	contextMenu.visible = false;
}

function onDeleteEdge(edgeId: string) {
	if (!edgeId) return;
	const idx = canvasHook.edges.value.findIndex(e => e.id === edgeId);
	if (idx >= 0) canvasHook.edges.value.splice(idx, 1);
	contextMenu.visible = false;
}

async function onAutoLayout() {
	contextMenu.visible = false;
	// 简单的网格布局
	const nodes = canvasHook.nodes.value;
	const cols = Math.ceil(Math.sqrt(nodes.length));
	nodes.forEach((n, i) => {
		n.position = { x: (i % cols) * 250 + 50, y: Math.floor(i / cols) * 200 + 50 };
	});
	setTimeout(() => canvasHook.fitView({ padding: 0.2 }), 100);
}

async function onSave() {
	if (!selectedCrewId.value) return ElMessage.warning('请先选择集群');
	saving.value = true;
	try {
		const canvasData = canvasHook.serializeCanvas();
		const members = canvasHook.extractMembers();
		const hints = canvasToHints(canvasHook.nodes.value, canvasHook.edges.value);
		// 同步 masterAgentId：优先取画布 hook 中的值
		const masterAgentId = canvasHook.masterAgentId.value || crewStore.currentCrew?.masterAgentId;
		if (masterAgentId && crewStore.currentCrew) {
			crewStore.currentCrew.masterAgentId = masterAgentId;
		}
		await crewStore.saveCanvas(selectedCrewId.value, canvasData, members, hints);
		ElMessage.success('保存成功');
	} catch (err: any) {
		ElMessage.error(err.message || '保存失败');
	} finally {
		saving.value = false;
	}
}

async function onPublish() {
	if (!selectedCrewId.value) return;
	try {
		await crewStore.publish(selectedCrewId.value);
		ElMessage.success('发布成功');
	} catch (err: any) {
		ElMessage.error(err.message || '发布失败');
	}
}

async function onUnpublish() {
	if (!selectedCrewId.value) return;
	await crewStore.unpublish(selectedCrewId.value);
	ElMessage.success('已取消发布');
}

async function onNewCrew() {
	const { value } = await ElMessageBox.prompt('请输入集群名称', '新建集群', {
		confirmButtonText: '创建',
		cancelButtonText: '取消',
		inputPlaceholder: '集群名称',
	});
	if (!value) return;
	const crew = await crewStore.createCrew({
		name: `crew-${Date.now()}`,
		label: value,
		status: 0,
		triggerConfig: { manual: true, cron: { enabled: false, expression: '', timezone: '' } },
	});
	selectedCrewId.value = crew?.id;
}

async function onTestRun() {
	if (!selectedCrewId.value) return;
	const { value } = await ElMessageBox.prompt('请输入任务指令（主 Agent 将根据此指令协调团队执行）', '试运行', {
		confirmButtonText: '运行',
		cancelButtonText: '取消',
		inputPlaceholder: '例如：分析竞品数据并生成上架方案',
	});
	if (!value) return;
	router.push(`/agent/crew-monitor?crewId=${selectedCrewId.value}&autoRun=1&triggerInput=${encodeURIComponent(value)}`);
}

function onUpdateCrew(data: any) {
	if (crewStore.currentCrew) Object.assign(crewStore.currentCrew, data);
}
</script>

<style scoped lang="scss">
.crew-editor {
	display: flex;
	flex-direction: column;
	height: 100%;
}
.toolbar {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 8px 16px;
	border-bottom: 1px solid #ebeef5;
	background: white;
}
.main-area {
	flex: 1;
	display: flex;
	overflow: hidden;
}
.canvas-container {
	flex: 1;
	position: relative;
}
</style>
