<template>
	<div class="management-container">
		<div class="page-header">
			<div class="header-title">
				<h1>{{ t('sidebar.menu.orchestration') }}</h1>
				<p>{{ t('pages.webSearch.subtitle') }}</p>
			</div>
		</div>

		<div class="stats-grid">
			<div class="stat-card">
				<div class="stat-icon coral">
					<SvgIcon name="platForm" size="20" />
				</div>
				<div>
					<div class="stat-value">{{ pageData.totalCount }}</div>
					<div class="stat-label">{{ t('pages.management.totalWorkflowCount') }}</div>
				</div>
			</div>
			<div class="stat-card">
				<div class="stat-icon blue">
					<SvgIcon name="workflow" size="20" />
				</div>
				<div>
					<div class="stat-value">{{ agents.length }}</div>
					<div class="stat-label">{{ t('pages.management.stats.currentPageCount') }}</div>
				</div>
			</div>
			<div class="stat-card">
				<div class="stat-icon green">
					<SvgIcon name="service" size="20" />
				</div>
				<div>
					<div class="stat-value">{{ totalConversationVariables }}</div>
					<div class="stat-label">{{ t('pages.management.stats.conversationVariables') }}</div>
				</div>
			</div>
			<div class="stat-card">
				<div class="stat-icon orange">
					<SvgIcon name="setting" size="20" />
				</div>
				<div>
					<div class="stat-value">{{ totalEnvVariables }}</div>
					<div class="stat-label">{{ t('pages.management.stats.envVariables') }}</div>
				</div>
			</div>
		</div>

		<div class="panel">
			<div class="toolbar">
				<div class="toolbar-left">
					<el-input
						v-model="keyword"
						:placeholder="t('pages.management.searchPlaceholder')"
						clearable
						class="search-input"
					>
						<template #prefix>
							<el-icon><Search /></el-icon>
						</template>
					</el-input>
					<div class="toolbar-actions">
						<el-button type="primary" @click="loadAgents(pageIndex)">
							<el-icon><Search /></el-icon>
							{{ t('common.search') }}
						</el-button>
						<el-button :loading="loading" @click="loadAgents(pageIndex)">
							<el-icon><RefreshRight /></el-icon>
							{{ t('common.refresh') }}
						</el-button>
					</div>
				</div>
				<div class="toolbar-right">
					<el-button type="primary" @click="openCreateWorkflow">
						<el-icon><Plus /></el-icon>
						{{ t('shared.createWorkflow.title') }}
					</el-button>
				</div>
			</div>

			<div v-loading="loading" class="card-grid">
				<div
					v-for="row in filteredAgents"
					:key="row.id"
					class="agent-card"
					@click="handleRowClick(row)"
				>
					<div class="card-actions" @click.stop>
						<el-dropdown trigger="click">
							<span class="card-actions__trigger">
								<el-icon>
									<MoreFilled />
								</el-icon>
							</span>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item @click="openEditWorkflow(row)">{{
										t('common.edit')
									}}</el-dropdown-item>
									<el-dropdown-item @click="confirmDeleteWorkflow(row.id)" divided>
										<span class="danger-text">{{ t('common.delete') }}</span>
									</el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
					</div>

					<div class="cover">
						<el-image
							:src="row.profilePhoto ? `/File/GetImage?fileId=${row.profilePhoto}` : undefined"
							:alt="row.name"
							class="cover-image"
						>
							<template #error>
								<div class="image-viewer-slot image-slot"></div>
							</template>
						</el-image>

						<div class="cover-gradient"></div>
					</div>

					<div class="cover-bottom">
						<el-avatar :size="56" :src="row.profilePhoto || undefined" class="cover-avatar">
							{{ row.name?.slice(0, 1) || 'A' }}
						</el-avatar>
					</div>

					<div class="card-body">
						<div class="card-head">
							<div class="card-title-wrap">
								<div class="agent-name" :title="row.name || fallbackText.unnamed">
									{{ row.name || fallbackText.unnamed }}
								</div>
								<div class="agent-id" :title="row.id">{{ row.id }}</div>
							</div>
						</div>

						<div class="card-footer">
							<el-button type="primary" @click.stop="openAgent(row.id)">
								{{ t('common.open') }}
							</el-button>
						</div>
					</div>
				</div>

				<el-empty
					v-if="!filteredAgents.length && !loading"
					:description="keyword ? emptyText.filtered : emptyText.default"
					class="empty-state"
				/>
			</div>

			<div v-if="pageData.totalCount" class="pagination">
				<el-pagination
					background
					layout="total, prev, pager, next"
					:current-page="pageIndex"
					:page-size="pageData.pageSize || 10"
					:total="pageData.totalCount"
					@current-change="handlePageChange"
				/>
			</div>
		</div>

		<CreateWorkflowModal
			:visible="createWorkflowVisible"
			:mode="workflowModalMode"
			:initial-data="workflowInitialData"
			@close="createWorkflowVisible = false"
			@success="handleWorkflowSaved"
		/>
	</div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { MoreFilled, Plus, RefreshRight, Search } from '@element-plus/icons-vue'
import { agent, agentApplication } from '@repo/api-service'

import SvgIcon from '@/components/SvgIcon/index.vue'
import { useI18n } from '@/composables/useI18n'
import CreateWorkflowModal from '@/features/createModal/index.vue'

type AgentListResponse = Awaited<ReturnType<typeof agent.postAgentGetAgentList>>
type AgentListResult = NonNullable<AgentListResponse['result']>
type AgentListItem = AgentListResult['model'][number]

const createEmptyPageData = (): AgentListResult => ({
	currentPage: 1,
	hasNextPage: false,
	hasPreviousPage: false,
	model: [],
	pageSize: 10,
	totalCount: 0,
	totalPages: 0
})

const { t } = useI18n()

const fallbackText = computed(
	() =>
		({
			unnamed: t('pages.management.fallback.unnamed'),
			notConfiguredConversation: t('pages.management.fallback.notConfiguredConversation'),
			notConfiguredEnv: t('pages.management.fallback.notConfiguredEnv')
		}) as const
)

const emptyText = computed(
	() =>
		({
			default: t('pages.management.emptyDefault'),
			filtered: t('pages.management.empty.filtered')
		}) as const
)

const loading = ref(false)
const keyword = ref('')
const pageIndex = ref(1)
const pageData = ref<AgentListResult>(createEmptyPageData())
const createWorkflowVisible = ref(false)
const workflowModalMode = ref<'create' | 'edit'>('create')
const workflowInitialData = ref<Record<string, any>>({})

const agents = computed(() => pageData.value.model)

const filteredAgents = computed(() => {
	const searchValue = keyword.value.trim().toLowerCase()

	if (!searchValue) {
		return agents.value
	}

	return agents.value.filter((item) => {
		const name = item.name.toLowerCase()
		const id = item.id.toLowerCase()
		return name.includes(searchValue) || id.includes(searchValue)
	})
})

const totalConversationVariables = computed(() =>
	agents.value.reduce((total, item) => total + item.conversation_variables.length, 0)
)

const totalEnvVariables = computed(() =>
	agents.value.reduce((total, item) => total + item.env_variables.length, 0)
)

const openAgent = (id: string) => {
	// 新窗口打开
	window.open(`#/workflow/${id}`, '_blank')
}

const openCreateWorkflow = () => {
	workflowModalMode.value = 'create'
	workflowInitialData.value = {}
	createWorkflowVisible.value = true
}

const openEditWorkflow = async (row: AgentListItem) => {
	try {
		const res = await agent.postAgentGetAgentInfo({ id: row.id })
		if (!res.isSuccess || !res.result) {
			throw new Error('load workflow detail failed')
		}

		const detail = res.result as Record<string, any>
		workflowInitialData.value = {
			id: detail.id,
			name: detail.name || row.name,
			remark: detail.remark || '',
			profilePhoto: detail.profilePhoto || row.profilePhoto || '',
			viewPort: detail.viewPort || row.viewPort || { x: 0, y: 0, zoom: 1 }
		}
		workflowModalMode.value = 'edit'
		createWorkflowVisible.value = true
	} catch (error) {
		console.error('openEditWorkflow error', error)
		ElMessage.error(t('pages.management.loadFailed'))
	}
}

const confirmDeleteWorkflow = async (id: string) => {
	try {
		await ElMessageBox.confirm(
			t('pages.management.deleteConfirmMessage'),
			t('common.confirmDelete.title'),
			{
				type: 'warning',
				confirmButtonText: t('common.delete'),
				cancelButtonText: t('common.cancel')
			}
		)
		const res = await agent.postAgentDoDeleteAgent({ id })
		if (!res.isSuccess) throw new Error('delete failed')
		ElMessage.success(t('pages.management.deleteSuccess'))
		await loadAgents(pageIndex.value)
	} catch (error) {
		if (error !== 'cancel' && error !== 'close') {
			console.error('confirmDeleteWorkflow error', error)
		}
	}
}

const handleRowClick = (row: AgentListItem) => {
	openAgent(row.id)
}

const handleWorkflowSaved = async () => {
	createWorkflowVisible.value = false
	await loadAgents(pageIndex.value)
}

const loadAgents = async (targetPage = 1) => {
	loading.value = true

	try {
		const response = await agent.postAgentGetAgentList({
			pageIndex: targetPage
		})

		if (!response.isSuccess || !response.result) {
			throw new Error(t('pages.management.errors.fetchFailed'))
		}

		pageData.value = response.result
		pageIndex.value = response.result.currentPage || targetPage
	} catch (error) {
		console.error('loadAgents error', error)
		ElMessage.error(t('pages.management.errors.loadFailed'))
		pageData.value = createEmptyPageData()
	} finally {
		loading.value = false
	}
}

const handlePageChange = (nextPage: number) => {
	pageIndex.value = nextPage
	loadAgents(nextPage)
}

onMounted(() => {
	loadAgents(pageIndex.value)
})
</script>

<style lang="less" scoped>
.management-container {
	margin: 0 auto;
	padding: 24px;
}

.page-header {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 24px;

	.header-title {
		h1 {
			margin: 0;
			font-size: 28px;
			color: var(--text-primary);
		}

		p {
			margin: 6px 0 0;
			font-size: 14px;
			color: var(--text-secondary);
		}
	}
}

.eyebrow {
	display: inline-flex;
	align-items: center;
	padding: 6px 10px;
	border-radius: 999px;
	background: rgba(255, 107, 107, 0.1);
	color: var(--el-color-primary);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.stats-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 16px;
	margin-bottom: 22px;
}

.stat-card {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 18px;
	border: 1px solid var(--border-light);
	border-radius: 18px;
	background: var(--bg-base);
	box-shadow: var(--shadow-sm);
}

.stat-icon {
	width: 46px;
	height: 46px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 14px;

	&.coral {
		background: #fff1f0;
		color: #810042;
	}

	&.blue {
		background: #eef4ff;
		color: #3b82f6;
	}

	&.green {
		background: #ecfdf3;
		color: #10b981;
	}

	&.orange {
		background: #fff7ed;
		color: #f97316;
	}
}

.stat-value {
	font-size: 24px;
	font-weight: 700;
	color: var(--text-primary);
}

.stat-label {
	margin-top: 2px;
	font-size: 13px;
	color: var(--text-secondary);
}

.panel {
	padding: 22px;
	border: 1px solid var(--border-light);
	border-radius: 22px;
	background: var(--bg-base);
	box-shadow: var(--shadow-sm);
}

.toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 20px;
}

.toolbar-left,
.toolbar-right {
	display: flex;
	align-items: center;
	gap: 10px;
}

.toolbar-actions {
	display: flex;
	align-items: center;
	gap: 8px;

	.el-button + .el-button {
		margin-left: 0;
	}
}

.search-input {
	max-width: 340px;
}

.meta-pill {
	display: inline-flex;
	align-items: center;
	padding: 8px 12px;
	border: 1px solid var(--border-light);
	border-radius: 999px;
	background: var(--bg-container);
	font-size: 12px;
	color: var(--text-secondary);
}

.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: 20px;
	min-height: 240px;
}

.agent-card {
	display: flex;
	flex-direction: column;
	min-height: 100%;
	overflow: hidden;
	border: 1px solid var(--border-light);
	border-radius: 22px;
	background: var(--bg-base);
	box-shadow: var(--shadow-sm);
	cursor: pointer;
	position: relative;
	transition:
		transform 0.18s ease,
		box-shadow 0.18s ease,
		border-color 0.18s ease;

	&:hover {
		transform: translateY(-6px);
		border-color: rgba(255, 107, 107, 0.24);
		box-shadow: var(--shadow-md);
	}
}

.cover {
	position: relative;
	height: 188px;
	overflow: hidden;
	background: var(--card-bg-unselected);
}

.cover-image,
.cover-fallback {
	width: 100%;
	height: 100%;
}

.cover-image {
	display: block;
	object-fit: cover;
}

.cover-fallback {
	display: flex;
	align-items: center;
	justify-content: center;
}

.fallback-monogram {
	width: 84px;
	height: 84px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 24px;
	background: var(--bg-overlay);
	backdrop-filter: blur(10px);
	font-size: 38px;
	font-weight: 800;
	color: #810042;
}

.cover-gradient {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(10, 10, 10, 0.02), rgba(10, 10, 10, 0.5));
}

.cover-top {
	position: absolute;
	top: 14px;
	left: 14px;
	right: 14px;
	display: flex;
	justify-content: space-between;
	gap: 8px;
}

.cover-badge {
	display: inline-flex;
	align-items: center;
	padding: 6px 10px;
	border-radius: 999px;
	background: var(--bg-overlay);
	color: var(--text-primary);
	font-size: 12px;
	font-weight: 600;
	backdrop-filter: blur(10px);

	&.subtle {
		background: var(--text-strong);
		color: var(--bg-base);
	}
}

.cover-bottom {
	position: absolute;
	left: 18px;
	top: 160px;
}

.cover-avatar {
	border: 4px solid var(--bg-base);
	box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
}

.card-body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: 40px 18px 18px;
}

.card-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 12px;
}

.card-title-wrap {
	min-width: 0;
}

.agent-name {
	overflow: hidden;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--text-primary);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.agent-id {
	margin-top: 6px;
	overflow: hidden;
	font-size: 12px;
	color: var(--text-secondary);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.enter-link {
	padding-right: 0;
	padding-left: 0;
}

.metric-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
	margin-top: 18px;
}

.metric-card {
	padding: 12px 14px;
	border: 1px solid var(--border-light);
	border-radius: 16px;
	background: var(--bg-container);
}

.metric-label {
	font-size: 12px;
	color: var(--text-tertiary);
}

.metric-value {
	margin-top: 6px;
	font-size: 20px;
	font-weight: 700;
	line-height: 1;
	color: var(--text-primary);
}

.detail-panel {
	display: grid;
	gap: 12px;
	margin-top: 16px;
	padding: 14px;
	border-radius: 18px;
	background: var(--bg-container);
}

.detail-item {
	padding-bottom: 12px;
	border-bottom: 1px solid var(--border-light);

	&:last-child {
		padding-bottom: 0;
		border-bottom: 0;
	}
}

.detail-label {
	font-size: 12px;
	color: var(--text-tertiary);
}

.detail-value {
	margin-top: 6px;
	font-size: 13px;
	line-height: 1.65;
	color: var(--text-secondary);
	word-break: break-word;
}

.card-footer {
	display: flex;
	justify-content: flex-end;
	margin-top: auto;
	padding-top: 18px;
}

.empty-state {
	grid-column: 1 / -1;
	padding: 30px 0 18px;
}

.pagination {
	display: flex;
	justify-content: flex-end;
	margin-top: 20px;
}

.card-actions {
	position: absolute;
	right: 12px;
	top: 12px;
	z-index: 1;
}

.card-actions__trigger {
	width: 30px;
	height: 30px;
	border-radius: 999px;
	display: grid;
	place-items: center;
	color: var(--text-secondary);
	background: var(--bg-overlay);
	transition:
		background 0.2s ease,
		color 0.2s ease;
}

.danger-text {
	color: var(--el-color-danger);
}

.card-actions__trigger:hover {
	background: var(--bg-container);
	color: var(--text-strong);
}

@media (max-width: 960px) {
	.page-header,
	.toolbar {
		flex-direction: column;
		align-items: stretch;
	}

	.search-input {
		max-width: none;
	}

	.toolbar-meta,
	.pagination {
		justify-content: flex-start;
	}
}

@media (max-width: 640px) {
	.management-container {
		padding: 18px 14px 24px;
	}

	.panel {
		padding: 16px;
		border-radius: 18px;
	}

	.card-grid {
		grid-template-columns: 1fr;
	}

	.cover {
		height: 172px;
	}

	.card-head {
		flex-direction: column;
	}

	.enter-link,
	.card-footer :deep(.el-button) {
		width: 100%;
	}
}
</style>
