<template>
	<div class="asset-group-page">
		<section class="ag-panel">
			<div class="ag-head">
				<h3 class="ag-title">资源组管理</h3>
				<a-button type="primary" @click="openCreateDialog">新增资源组</a-button>
			</div>
			<div class="ag-filter">
				<div class="ag-field">
					<label>名称</label>
					<a-input v-model="filters.name" placeholder="按名称过滤" />
				</div>
				<div class="ag-field">
					<label>资源组编号</label>
					<a-input v-model="filters.groupIdsText" placeholder="多个编号用英文逗号分隔" />
				</div>
				<div class="ag-field">
					<label>资源组类型</label>
					<a-select v-model="filters.groupType">
						<a-option value="AIGC">AIGC（生成类）</a-option>
					</a-select>
				</div>
				<div class="ag-field">
					<label>排序字段</label>
					<a-select v-model="filters.sortBy">
						<a-option value="CreateTime">创建时间</a-option>
						<a-option value="UpdateTime">更新时间</a-option>
					</a-select>
				</div>
				<div class="ag-field">
					<label>排序方向</label>
					<a-select v-model="filters.sortOrder">
						<a-option value="Desc">从新到旧</a-option>
						<a-option value="Asc">从旧到新</a-option>
					</a-select>
				</div>
				<div class="ag-actions">
					<a-button type="primary" :loading="listLoading" @click="search(1)">查询</a-button>
					<a-button @click="resetFilters">重置</a-button>
				</div>
			</div>

			<a-spin :loading="listLoading">
				<div class="ag-total">总数：{{ totalCount }}</div>
				<div class="ag-table-wrap">
					<table class="ag-table">
						<colgroup>
							<col class="ag-col-id" />
							<col class="ag-col-name" />
							<col class="ag-col-desc" />
							<col class="ag-col-type" />
							<col class="ag-col-project" />
							<col class="ag-col-time" />
							<col class="ag-col-time" />
							<col class="ag-col-action" />
						</colgroup>
						<thead>
							<tr>
								<th>编号</th>
								<th>名称</th>
								<th>描述</th>
								<th>类型</th>
								<th>项目名称</th>
								<th>创建时间</th>
								<th>更新时间</th>
								<th>操作</th>
							</tr>
						</thead>
						<tbody>
							<tr v-for="item in items" :key="item.Id || item.id">
								<td>{{ item.Id || item.id }}</td>
								<td>{{ item.Name || item.name }}</td>
								<td>{{ item.Description || item.description || '-' }}</td>
								<td>{{ formatGroupTypeLabel(item) }}</td>
								<td>{{ item.ProjectName || item.projectName || '-' }}</td>
								<td>{{ item.CreateTime || item.createTime || '-' }}</td>
								<td>{{ item.UpdateTime || item.updateTime || '-' }}</td>
								<td>
									<a-button
										size="mini"
										type="outline"
										:loading="detailLoadingId === (item.Id || item.id)"
										@click="getDetail(item)">
										详情
									</a-button>
								</td>
							</tr>
							<tr v-if="!items.length">
								<td colspan="8" class="ag-empty">暂无数据</td>
							</tr>
						</tbody>
					</table>
				</div>
				<div class="ag-pagination">
					<a-pagination
						:total="totalCount"
						:current="filters.pageNumber"
						:page-size="filters.pageSize"
						show-total
						show-jumper
						show-page-size
						:page-size-options="listPageSizeOptions"
						@change="onGroupPageChange"
						@page-size-change="onPageSizeChange" />
				</div>
			</a-spin>
		</section>

		<a-modal v-model:visible="detailVisible" title="资源组详情" :footer="false" width="680px">
			<pre class="ag-detail">{{ prettyDetail }}</pre>
		</a-modal>
		<a-modal
			v-model:visible="createVisible"
			title="新增资源组"
			width="520px"
			:confirm-loading="createLoading"
			@ok="createGroup">
			<!-- 弹层 teleported 到 body，使用 FormItem 保证标签与 dark 样式生效 -->
			<a-form :model="createForm" layout="horizontal" auto-label-width class="ag-create-modal-form">
				<a-form-item label="名称" required>
					<a-input
						v-model="createForm.name"
						placeholder="请输入资源组名称（≤64 字符）"
						:max-length="64"
						allow-clear />
				</a-form-item>
				<a-form-item label="描述">
					<a-textarea
						v-model="createForm.description"
						:max-length="300"
						show-word-limit
						:auto-size="{ minRows: 3, maxRows: 8 }"
						placeholder="请输入描述（≤300 字符）" />
				</a-form-item>
			</a-form>
		</a-modal>
	</div>
</template>

<script>
import { byteApiItems, byteApiTotalCount } from '@/utils/byteAssetApi'

const LIST_PAGE_NUMBER_MAX = 100
const LIST_PAGE_SIZE_OPTIONS = [10, 20, 50, 100]

export default {
	name: 'AssetGroupManage',
	data() {
		return {
			createLoading: false,
			createVisible: false,
			listLoading: false,
			detailLoadingId: '',
			detailVisible: false,
			detailData: null,
			createForm: {
				name: '',
				description: '',
				groupType: 'AIGC'
			},
			filters: {
				name: '',
				groupIdsText: '',
				groupType: 'AIGC',
				pageNumber: 1,
				pageSize: 10,
				sortBy: 'CreateTime',
				sortOrder: 'Desc'
			},
			totalCount: 0,
			items: [],
			listPageSizeOptions: LIST_PAGE_SIZE_OPTIONS
		}
	},
	computed: {
		prettyDetail() {
			return this.detailData ? JSON.stringify(this.detailData, null, 2) : '{}'
		}
	},
	mounted() {
		this.search(1)
	},
	methods: {
		formatGroupTypeLabel(item) {
			const t = String(item?.GroupType || item?.groupType || '').trim()
			if (!t) return '-'
			if (t === 'AIGC') return 'AIGC（生成类）'
			return t
		},
		clampGroupPage(n) {
			const page = Number(n) || 1
			const size = Number(this.filters.pageSize) || 10
			let maxPage = LIST_PAGE_NUMBER_MAX
			if (this.totalCount > 0) {
				const totalPages = Math.ceil(this.totalCount / size)
				maxPage = Math.min(LIST_PAGE_NUMBER_MAX, Math.max(1, totalPages))
			}
			return Math.min(Math.max(1, page), maxPage)
		},
		onGroupPageChange(page) {
			this.search(this.clampGroupPage(page))
		},
		openCreateDialog() {
			this.createVisible = true
		},
		buildGroupIds() {
			return String(this.filters.groupIdsText || '')
				.split(',')
				.map((x) => x.trim())
				.filter((x) => !!x)
		},
		async createGroup() {
			const name = String(this.createForm.name || '').trim()
			if (!name) {
				this.$message.error('请填写名称')
				return
			}
			this.createLoading = true
			try {
				const res = await this.$axios({
					url: 'api/byteAssetGroup/createAssetGroup',
					method: 'POST',
					data: {
						name,
						description: String(this.createForm.description || '').trim()
					}
				})
				if (res.code === 200) {
					this.$message.success('新增成功')
					this.createForm.name = ''
					this.createForm.description = ''
					this.createVisible = false
					this.search(1)
				} else {
					this.$message.error(res.msg || '新增失败')
				}
			} catch (e) {
				this.$message.error(e?.message || '新增失败')
			} finally {
				this.createLoading = false
			}
		},
		async search(page = this.filters.pageNumber) {
			this.filters.pageNumber = this.clampGroupPage(page)
			this.listLoading = true
			try {
				const payload = {
					filter: {
						groupType: this.filters.groupType || 'AIGC'
					},
					pageNumber: this.filters.pageNumber,
					pageSize: this.filters.pageSize,
					sortBy: this.filters.sortBy,
					sortOrder: this.filters.sortOrder
				}
				const name = String(this.filters.name || '').trim()
				if (name) payload.filter.name = name
				const ids = this.buildGroupIds()
				if (ids.length) payload.filter.groupIds = ids

				const res = await this.$axios({
					url: 'api/byteAssetGroup/listAssetGroups',
					method: 'POST',
					data: payload
				})
				const data = res.data || {}
				this.totalCount = byteApiTotalCount(data)
				this.items = byteApiItems(data)
				if (res.code !== 200) {
					this.$message.error(res.msg || '查询失败')
				}
			} catch (e) {
				this.$message.error(e?.message || '查询失败')
			} finally {
				this.listLoading = false
			}
		},
		onPageSizeChange(size) {
			const s = Number(size) || 10
			this.filters.pageSize = LIST_PAGE_SIZE_OPTIONS.includes(s) ? s : 10
			this.search(1)
		},
		resetFilters() {
			this.filters = {
				name: '',
				groupIdsText: '',
				groupType: 'AIGC',
				pageNumber: 1,
				pageSize: 10,
				sortBy: 'CreateTime',
				sortOrder: 'Desc'
			}
			this.search(1)
		},
		async getDetail(item) {
			const id = item?.Id || item?.id
			if (!id) return
			this.detailLoadingId = id
			try {
				const res = await this.$axios({
					url: 'api/byteAssetGroup/getAssetGroup',
					method: 'POST',
					data: { id: id }
				})
				if (res.code === 200) {
					this.detailData = res.data || {}
					this.detailVisible = true
				} else {
					this.$message.error(res.msg || '查询详情失败')
				}
			} catch (e) {
				this.$message.error(e?.message || '查询详情失败')
			} finally {
				this.detailLoadingId = ''
			}
		}
	}
}
</script>

<style scoped lang="less">
.asset-group-page {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 18px;
	background: #0a0b0d;
	color: rgba(255, 255, 255, 0.88);
	min-height: 100%;
}

.ag-panel {
	background: rgba(22, 24, 30, 0.92);
	border: 1px solid rgba(255, 255, 255, 0.08);
	border-radius: 14px;
	padding: 14px;
}

.ag-title {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
}
.ag-head {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 14px;
}

.ag-form,
.ag-filter {
	display: grid;
	grid-template-columns: repeat(3, minmax(180px, 1fr));
	gap: 12px;
}
.ag-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.ag-field label {
	font-size: 12px;
	color: rgba(255, 255, 255, 0.65);
}

.ag-actions {
	display: flex;
	align-items: flex-end;
	gap: 8px;
}

.ag-total {
	margin: 6px 0 10px;
	font-size: 12px;
	color: rgba(255, 255, 255, 0.65);
}

.ag-table-wrap {
	width: 100%;
	max-width: 100%;
	box-sizing: border-box;
	overflow-x: auto;
	border: 1px solid rgba(255, 255, 255, 0.08);
	border-radius: 10px;
}

.ag-table {
	width: 100%;
	max-width: 100%;
	table-layout: fixed;
	border-collapse: collapse;
	font-size: 12px;
}

/* 列宽按百分比分配，随容器（100% 宽）随分辨率伸缩 */
.ag-col-id {
	width: 10%;
}
.ag-col-name {
	width: 12%;
}
.ag-col-desc {
	width: 24%;
}
.ag-col-type {
	width: 8%;
}
.ag-col-project {
	width: 12%;
}
.ag-col-time {
	width: 11%;
}
.ag-col-action {
	width: 12%;
}

.ag-table th,
.ag-table td {
	padding: 10px;
	border-bottom: 1px solid rgba(255, 255, 255, 0.06);
	text-align: left;
	vertical-align: top;
	word-break: break-word;
	overflow-wrap: anywhere;
}

.ag-table th {
	color: rgba(255, 255, 255, 0.7);
	font-weight: 600;
	background: rgba(255, 255, 255, 0.02);
}

.ag-empty {
	text-align: center;
	color: rgba(255, 255, 255, 0.5);
}

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

.ag-detail {
	margin: 0;
	padding: 12px;
	border-radius: 8px;
	background: rgba(0, 0, 0, 0.35);
	color: #d8f4f7;
	max-height: 420px;
	overflow: auto;
	white-space: pre-wrap;
	word-break: break-all;
}

@media (max-width: 960px) {
	.ag-form,
	.ag-filter {
		grid-template-columns: 1fr;
	}
}
</style>
