<template>
	<div class="assets-edit-asset-container">
		<el-dialog :title="isEdit ? '修改资产' : '新增资产'" v-model="isShowDialog" width="1000px" destroy-on-close>
			<el-form ref="formRef" :model="ruleForm" :rules="rules" size="default" label-width="100px" v-loading="formLoading">
				<!-- 基础信息 -->
				<el-divider content-position="left">基础信息</el-divider>
				<el-row :gutter="24">
					<el-col :span="8">
						<el-form-item label="资产名称" prop="name">
							<el-input v-model="ruleForm.name" placeholder="请输入资产名称" clearable />
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="资产类型" prop="type">
							<el-select v-model="ruleForm.type" placeholder="请选择资产类型" class="w100" :disabled="isEdit">
								<el-option label="实物" value="physical" />
								<el-option label="虚拟" value="virtual" />
								<el-option label="服务" value="service" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="第三方资产">
							<el-switch v-model="ruleForm.sourceType" inline-prompt active-text="是" inactive-text="否" />
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="24">
					<el-col :span="8">
						<el-form-item label="资产分类" prop="categoryId">
							<el-cascader
								v-model="ruleForm.categoryId"
								:options="categoryOptions"
								:props="{ checkStrictly: true, emitPath: false, value: 'id', label: 'name', children: 'children' }"
								placeholder="请选择资产分类"
								clearable
								class="w100"
								@change="onCategoryChange"
							/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="上线时间">
							<el-date-picker
								v-model="ruleForm.onlineTime"
								type="datetime"
								placeholder="请选择上线时间"
								format="YYYY-MM-DD HH:mm:ss"
								value-format="YYYY-MM-DD HH:mm:ss"
								class="w100"
							/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="下线时间">
							<el-date-picker
								v-model="ruleForm.offlineTime"
								type="datetime"
								placeholder="请选择下线时间"
								format="YYYY-MM-DD HH:mm:ss"
								value-format="YYYY-MM-DD HH:mm:ss"
								class="w100"
							/>
						</el-form-item>
					</el-col>
				</el-row>

				<!-- 分类属性值选择 -->
				<template v-if="categoryAttrs.length > 0">
					<el-divider content-position="left">分类属性</el-divider>
					<el-row :gutter="24">
						<el-col :span="8" v-for="(attr, index) in categoryAttrs" :key="index">
							<el-form-item :label="getAttrLabel(attr)">
								<!-- 单选类型 -->
								<el-select
									v-if="attr.type === 'select'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
									:placeholder="'请选择' + getAttrLabel(attr)"
									class="w100"
									clearable
								>
									<el-option
										v-for="opt in attr.options"
										:key="opt.value"
										:label="opt.label"
										:value="opt.value"
									/>
								</el-select>
								<!-- 多选类型 -->
								<el-select
									v-else-if="attr.type === 'multi_select'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
									:placeholder="'请选择' + getAttrLabel(attr)"
									class="w100"
									multiple
									clearable
								>
									<el-option
										v-for="opt in attr.options"
										:key="opt.value"
										:label="opt.label"
										:value="opt.value"
									/>
								</el-select>
								<!-- 文本类型 -->
								<el-input
									v-else-if="attr.type === 'text'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
									:placeholder="'请输入' + getAttrLabel(attr)"
								/>
								<!-- 数字类型 -->
								<el-input-number
									v-else-if="attr.type === 'number'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
									class="w100"
								/>
								<!-- 日期类型 -->
								<el-date-picker
									v-else-if="attr.type === 'date'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
									type="date"
									:placeholder="'请选择' + getAttrLabel(attr)"
									class="w100"
								/>
								<!-- 布尔类型 -->
								<el-switch
									v-else-if="attr.type === 'boolean'"
									v-model="ruleForm.metadata[getAttrKey(attr)]"
								/>
								<!-- 图片类型 -->
								<el-upload
									v-else-if="attr.type === 'image'"
									class="attr-image-uploader"
									:show-file-list="false"
									:auto-upload="false"
									accept="image/*"
								>
									<el-button type="primary" size="small">上传图片</el-button>
								</el-upload>
							</el-form-item>
						</el-col>
					</el-row>
				</template>

				<!-- 资产描述 -->
				<el-divider content-position="left">资产描述</el-divider>
				<el-form-item label="描述内容" label-width="100px">
					<div class="editor-wrapper">
						<Editor v-model="ruleForm.description" height="200px" placeholder="请输入资产描述" />
					</div>
				</el-form-item>

				<!-- 图片上传 -->
				<el-divider content-position="left">图片信息</el-divider>
				<el-row :gutter="24">
					<el-col :span="8">
						<el-form-item label="主图">
							<el-upload
								class="avatar-uploader"
								:show-file-list="false"
								:auto-upload="false"
								:on-change="handleMainImageChange"
								accept="image/*"
							>
								<img v-if="mainImagePreview" :src="mainImagePreview" class="avatar" />
								<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
							</el-upload>
						</el-form-item>
					</el-col>
					<el-col :span="16">
						<el-form-item label="图片列表">
							<el-upload
								v-model:file-list="imageFileList"
								list-type="picture-card"
								:auto-upload="false"
								:on-preview="handlePictureCardPreview"
								:on-remove="handleRemove"
								accept="image/*"
								multiple
							>
								<el-icon><Plus /></el-icon>
							</el-upload>
						</el-form-item>
					</el-col>
				</el-row>

				<!-- 实物资产配置 -->
				<template v-if="ruleForm.type === 'physical'">
					<el-divider content-position="left">实物资产配置</el-divider>
					<el-row :gutter="24">
						<el-col :span="8">
							<el-form-item label="无库存限制">
								<el-switch v-model="ruleForm.physicalAssetConfig.unlimitedStock" inline-prompt active-text="是" inactive-text="否" />
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="配送方式">
								<el-select v-model="ruleForm.physicalAssetConfig.shipping.deliveryMethod" placeholder="请选择配送方式" class="w100">
									<el-option label="快递" value="express" />
									<el-option label="自提" value="self_pickup" />
								</el-select>
							</el-form-item>
						</el-col>
						<el-col :span="8" v-if="ruleForm.physicalAssetConfig.shipping.deliveryMethod === 'express'">
							<el-form-item label="发货周期">
								<el-input-number v-model="ruleForm.physicalAssetConfig.shipping.deliveryTime" :min="1" :max="720" class="w100" />
								<span class="unit-text">小时</span>
							</el-form-item>
						</el-col>
					</el-row>
				</template>

				<!-- 虚拟资产配置 -->
				<template v-if="ruleForm.type === 'virtual'">
					<el-divider content-position="left">虚拟资产配置</el-divider>
					<el-row :gutter="24">
						<el-col :span="12">
							<el-form-item label="虚拟资产ID">
								<el-input v-model="ruleForm.virtualAssetConfig.virtualAssetId" placeholder="请输入虚拟资产ID" />
							</el-form-item>
						</el-col>
					</el-row>
				</template>

				<!-- 服务资产配置 -->
				<template v-if="ruleForm.type === 'service'">
					<el-divider content-position="left">服务资产配置</el-divider>
					
					<!-- 预订配置 -->
					<el-row :gutter="24">
						<el-col :span="6">
							<el-form-item label="最小提前">
								<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minAdvance" :min="0" class="w100" />
								<span class="unit-text">分钟</span>
							</el-form-item>
						</el-col>
						<el-col :span="6">
							<el-form-item label="最小时长">
								<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minDuration" :min="0" class="w100" />
								<span class="unit-text">分钟</span>
							</el-form-item>
						</el-col>
						<el-col :span="6">
							<el-form-item label="取消提前">
								<el-input-number v-model="ruleForm.serviceAssetConfig.booking.cancelWindow" :min="0" class="w100" />
								<span class="unit-text">分钟</span>
							</el-form-item>
						</el-col>
						<el-col :span="6">
							<el-form-item label="最大用户">
								<el-input-number v-model="ruleForm.serviceAssetConfig.capacity.maxUsers" :min="0" class="w100" />
								<span class="unit-text">0=无限</span>
							</el-form-item>
						</el-col>
					</el-row>

					<!-- 时间段配置 -->
					<el-form-item label="时间段">
						<div class="config-list-container">
							<div v-for="(slot, index) in ruleForm.serviceAssetConfig.schedule.timeSlots" :key="index" class="config-list-item">
								<el-select v-model="slot.dayOfWeek" placeholder="星期" style="width: 100px">
									<el-option v-for="d in 7" :key="d" :label="'周' + ['一','二','三','四','五','六','日'][d-1]" :value="String(d)" />
								</el-select>
								<el-time-picker v-model="slot.startTime" format="HH:mm" value-format="HH:mm" placeholder="开始" style="width: 100px" />
								<span class="separator">-</span>
								<el-time-picker v-model="slot.endTime" format="HH:mm" value-format="HH:mm" placeholder="结束" style="width: 100px" />
								<el-input-number v-model="slot.capacity" :min="1" placeholder="容量" style="width: 100px" controls-position="right" />
								<el-button type="danger" :icon="Delete" circle size="small" @click="removeTimeSlot(index)" />
							</div>
							<el-button type="primary" :icon="Plus" size="small" @click="addTimeSlot">添加时间段</el-button>
						</div>
					</el-form-item>

					<!-- 例外日期配置 -->
					<el-form-item label="例外日期">
						<div class="config-list-container">
							<div v-for="(exc, index) in ruleForm.serviceAssetConfig.schedule.exceptions" :key="index" class="config-list-item">
								<el-date-picker v-model="exc.date" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="日期" style="width: 130px" />
								<el-select v-model="exc.dayOfWeek" placeholder="星期" style="width: 90px">
									<el-option v-for="d in 7" :key="d" :label="'周' + ['一','二','三','四','五','六','日'][d-1]" :value="String(d)" />
								</el-select>
								<el-select v-model="exc.status" placeholder="状态" style="width: 90px">
									<el-option label="可用" :value="1" />
									<el-option label="不可用" :value="0" />
								</el-select>
								<el-input v-model="exc.reason" placeholder="原因" style="width: 120px" />
								<el-button type="danger" :icon="Delete" circle size="small" @click="removeException(index)" />
							</div>
							<el-button type="primary" :icon="Plus" size="small" @click="addException">添加例外</el-button>
						</div>
					</el-form-item>
				</template>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="onCancel" size="default">取 消</el-button>
					<el-button type="primary" @click="onSubmit" size="default" :loading="submitLoading">{{ isEdit ? '修 改' : '添 加' }}</el-button>
				</span>
			</template>
		</el-dialog>

		<!-- 图片预览 -->
		<el-dialog v-model="dialogVisible" title="图片预览">
			<img :src="dialogImageUrl" style="width: 100%" />
		</el-dialog>
	</div>
</template>

<script lang="ts">
export default {
	name: 'assetsEditAsset',
};
</script>

<script setup lang="ts">
import { ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus, Delete } from '@element-plus/icons-vue';
import { getAsset, createAsset, updateAsset } from '/@/api/assets/asset';
import { getCategoryTree, getCategory } from '/@/api/assets/category';
import Editor from '/@/components/editor/index.vue';
import type { UploadFile, UploadUserFile } from 'element-plus';

// 类型定义
interface TimeSlot {
	dayOfWeek: string;
	startTime: string;
	endTime: string;
	capacity: number;
}

interface Exception {
	date: string;
	status: number;
	reason: string;
	dayOfWeek: string;
}

interface CategoryAttr {
	name: string;
	type: string;
	options?: { label: string; value: string }[];
	description?: string;
}

interface RuleForm {
	id: string;
	name: string;
	sourceType: boolean;
	type: string;
	categoryId: string;
	description: string;
	onlineTime: string;
	offlineTime: string;
	physicalAssetConfig: {
		unlimitedStock: boolean;
		shipping: {
			deliveryMethod: string;
			deliveryTime: number;
		};
	};
	virtualAssetConfig: {
		virtualAssetId: string;
	};
	serviceAssetConfig: {
		schedule: {
			timeSlots: TimeSlot[];
			exceptions: Exception[];
		};
		booking: {
			minAdvance: number;
			minDuration: number;
			cancelWindow: number;
		};
		capacity: {
			maxUsers: number;
		};
	};
	metadata: Record<string, any>;
}

const emit = defineEmits(['getAssetList']);

const formRef = ref();
const isShowDialog = ref(false);
const isEdit = ref(false);
const submitLoading = ref(false);
const formLoading = ref(false);
const categoryOptions = ref<any[]>([]);
const categoryAttrs = ref<CategoryAttr[]>([]);

// 获取属性的key
const getAttrKey = (attr: CategoryAttr): string => {
	return attr.name || attr.description || `attr_${categoryAttrs.value.indexOf(attr)}`;
};

// 获取属性的显示名称
const getAttrLabel = (attr: CategoryAttr): string => {
	return attr.description || attr.name || '属性';
};

// 图片相关
const mainImageFile = ref<File | null>(null);
const mainImagePreview = ref('');
const imageFileList = ref<UploadUserFile[]>([]);
const dialogVisible = ref(false);
const dialogImageUrl = ref('');

// 初始表单数据
const getInitialForm = (): RuleForm => ({
	id: '',
	name: '',
	sourceType: false,
	type: 'physical',
	categoryId: '',
	description: '',
	onlineTime: '',
	offlineTime: '',
	physicalAssetConfig: {
		unlimitedStock: false,
		shipping: {
			deliveryMethod: 'express',
			deliveryTime: 24,
		},
	},
	virtualAssetConfig: {
		virtualAssetId: '',
	},
	serviceAssetConfig: {
		schedule: {
			timeSlots: [],
			exceptions: [],
		},
		booking: {
			minAdvance: 60,
			minDuration: 30,
			cancelWindow: 30,
		},
		capacity: {
			maxUsers: 0,
		},
	},
	metadata: {},
});

const ruleForm = reactive<RuleForm>(getInitialForm());

const rules = {
	name: [{ required: true, message: '资产名称不能为空', trigger: 'blur' }],
	type: [{ required: true, message: '请选择资产类型', trigger: 'change' }],
	categoryId: [{ required: true, message: '请选择资产分类', trigger: 'change' }],
};

// 主图上传处理
const handleMainImageChange = (file: UploadFile) => {
	if (file.raw) {
		mainImageFile.value = file.raw;
		mainImagePreview.value = URL.createObjectURL(file.raw);
	}
};

// 图片列表预览
const handlePictureCardPreview = (file: UploadFile) => {
	dialogImageUrl.value = file.url || '';
	dialogVisible.value = true;
};

// 图片列表移除
const handleRemove = (file: UploadFile) => {
	const index = imageFileList.value.findIndex((f) => f.uid === file.uid);
	if (index > -1) {
		imageFileList.value.splice(index, 1);
	}
};

// 时间段操作
const addTimeSlot = () => {
	ruleForm.serviceAssetConfig.schedule.timeSlots.push({
		dayOfWeek: '1',
		startTime: '09:00',
		endTime: '18:00',
		capacity: 100,
	});
};

const removeTimeSlot = (index: number) => {
	ruleForm.serviceAssetConfig.schedule.timeSlots.splice(index, 1);
};

// 例外日期操作
const addException = () => {
	ruleForm.serviceAssetConfig.schedule.exceptions.push({
		date: '',
		status: 1,
		reason: '',
		dayOfWeek: '1',
	});
};

const removeException = (index: number) => {
	ruleForm.serviceAssetConfig.schedule.exceptions.splice(index, 1);
};

// 重置表单
const resetForm = () => {
	const initial = getInitialForm();
	Object.assign(ruleForm, initial);
	mainImageFile.value = null;
	mainImagePreview.value = '';
	imageFileList.value = [];
	categoryAttrs.value = [];
};

// 获取分类数据
const fetchCategories = () => {
	getCategoryTree()
		.then((res: any) => {
			const tree = res.data?.tree ?? [];
			categoryOptions.value = tree.length > 0 && tree[0].children ? tree[0].children : tree;
		})
		.catch(() => {
			categoryOptions.value = [];
		});
};

// 分类变更时获取分类属性
const onCategoryChange = (categoryId: string) => {
	categoryAttrs.value = [];
	ruleForm.metadata = {};
	if (!categoryId) return;

	getCategory(categoryId)
		.then((res: any) => {
			const data = res.data;
			if (data?.attrs && Array.isArray(data.attrs)) {
				categoryAttrs.value = data.attrs;
			}
		})
		.catch(() => {
			categoryAttrs.value = [];
		});
};

// 打开弹窗
const openDialog = (row?: any, edit?: boolean) => {
	resetForm();
	isEdit.value = edit || false;
	fetchCategories();

	if (row && edit) {
		// 修改模式：获取详情
		formLoading.value = true;
		getAsset(row.id)
			.then((res: any) => {
				const data = res.data;
				ruleForm.id = data.id || '';
				ruleForm.name = data.name || '';
				ruleForm.sourceType = data.sourceType || false;
				ruleForm.type = data.type || 'physical';
				ruleForm.categoryId = data.categoryId || '';
				ruleForm.description = data.description || '';
				ruleForm.onlineTime = data.onlineTime || '';
				ruleForm.offlineTime = data.offlineTime || '';

				// 主图预览
				if (data.imageUrl) {
					mainImagePreview.value = data.imageUrl;
				}

				// 图片列表
				if (data.images && Array.isArray(data.images)) {
					imageFileList.value = data.images.map((url: string, index: number) => ({
						name: `image-${index}`,
						url: url,
					}));
				}

				// 根据类型加载配置
				if (data.type === 'physical' && data.physicalAssetConfig) {
					Object.assign(ruleForm.physicalAssetConfig, data.physicalAssetConfig);
				}
				if (data.type === 'virtual' && data.virtualAssetConfig) {
					Object.assign(ruleForm.virtualAssetConfig, data.virtualAssetConfig);
				}
				if (data.type === 'service' && data.serviceAssetConfig) {
					Object.assign(ruleForm.serviceAssetConfig, data.serviceAssetConfig);
				}

				// 元数据
				if (data.metadata) {
					Object.assign(ruleForm.metadata, data.metadata);
				}

				// 加载分类属性
				if (data.categoryId) {
					getCategory(data.categoryId)
						.then((catRes: any) => {
							const catData = catRes.data;
							if (catData?.attrs && Array.isArray(catData.attrs)) {
								categoryAttrs.value = catData.attrs;
							}
						})
						.catch(() => {
							categoryAttrs.value = [];
						});
				}
			})
			.finally(() => {
				formLoading.value = false;
			});
	}

	isShowDialog.value = true;
};

// 关闭弹窗
const closeDialog = () => {
	isShowDialog.value = false;
};

// 取消
const onCancel = () => {
	closeDialog();
};

// 构建FormData
const buildFormData = (): FormData => {
	const formData = new FormData();

	// 基础字段
	if (isEdit.value && ruleForm.id) {
		formData.append('id', ruleForm.id);
	}
	formData.append('name', ruleForm.name);
	formData.append('sourceType', String(ruleForm.sourceType));
	formData.append('type', ruleForm.type);
	formData.append('categoryId', ruleForm.categoryId);
	formData.append('description', ruleForm.description || '');
	if (ruleForm.onlineTime) {
		formData.append('onlineTime', ruleForm.onlineTime);
	}
	if (ruleForm.offlineTime) {
		formData.append('offlineTime', ruleForm.offlineTime);
	}

	// 主图
	if (mainImageFile.value) {
		formData.append('imageUrl', mainImageFile.value);
	}

	// 图片列表
	imageFileList.value.forEach((file) => {
		if (file.raw) {
			formData.append('images', file.raw);
		}
	});

	// 根据类型添加配置
	if (ruleForm.type === 'physical') {
		formData.append('physicalAssetConfig', JSON.stringify(ruleForm.physicalAssetConfig));
	} else if (ruleForm.type === 'virtual') {
		formData.append('virtualAssetConfig', JSON.stringify(ruleForm.virtualAssetConfig));
	} else if (ruleForm.type === 'service') {
		formData.append('serviceAssetConfig', JSON.stringify(ruleForm.serviceAssetConfig));
	}

	// 元数据（分类属性值）
	if (Object.keys(ruleForm.metadata).length > 0) {
		formData.append('metadata', JSON.stringify(ruleForm.metadata));
	}

	return formData;
};

// 提交
const onSubmit = () => {
	formRef.value.validate((valid: boolean) => {
		if (valid) {
			submitLoading.value = true;
			const formData = buildFormData();

			const request = isEdit.value ? updateAsset(formData) : createAsset(formData);

			request
				.then(() => {
					ElMessage.success(isEdit.value ? '修改成功' : '添加成功');
					closeDialog();
					emit('getAssetList');
				})
				.finally(() => {
					submitLoading.value = false;
				});
		}
	});
};

// 暴露方法
defineExpose({
	openDialog,
});
</script>

<style scoped lang="scss">
.w100 {
	width: 100%;
}

.ml10 {
	margin-left: 10px;
}

.mx5 {
	margin: 0 5px;
}

.text-muted {
	color: #909399;
	font-size: 12px;
}

.avatar-uploader {
	:deep(.el-upload) {
		border: 1px dashed var(--el-border-color);
		border-radius: 6px;
		cursor: pointer;
		position: relative;
		overflow: hidden;
		transition: var(--el-transition-duration-fast);

		&:hover {
			border-color: var(--el-color-primary);
		}
	}
}

.avatar-uploader-icon {
	font-size: 28px;
	color: #8c939d;
	width: 100px;
	height: 100px;
	text-align: center;
	line-height: 100px;
}

.avatar {
	width: 100px;
	height: 100px;
	display: block;
	object-fit: cover;
}

.config-list-container {
	width: 100%;

	.config-list-item {
		display: flex;
		align-items: center;
		gap: 8px;
		margin-bottom: 10px;
		flex-wrap: wrap;

		.separator {
			color: #909399;
		}

		.el-button.is-circle {
			:deep(.el-icon) {
				margin-right: 0 !important;
			}
		}
	}
}

.unit-text {
	margin-left: 8px;
	color: #909399;
	font-size: 12px;
	white-space: nowrap;
}

.editor-wrapper {
	width: 100%;
	border: 1px solid #dcdfe6;
	border-radius: 4px;

	:deep(.editor-toolbar) {
		border-bottom: 1px solid #dcdfe6;
	}
}

.attr-image-uploader {
	:deep(.el-upload) {
		border: 1px dashed var(--el-border-color);
		border-radius: 6px;
		cursor: pointer;
	}
}
</style>
