<template>
	<a-modal v-model:open="visible" :title="title" :width="600" :confirm-loading="loading" :ok-button-props="{ disabled: !fileList.length }" @ok="handleOk" @cancel="handleCancel">
		<div class="import-modal">
			<!-- 表单参数插槽 -->
			<div v-if="$slots.formParams" class="form-params">
				<slot name="formParams" :form-data="formData" />
			</div>

			<!-- 上传区域 -->
			<div class="upload-section">
				<a-upload-dragger v-model:file-list="fileList" :custom-request="customUpload" :before-upload="beforeUpload" :accept="accept" :max-count="1" :disabled="loading" @change="handleChange" @drop="handleDrop">
					<p class="ant-upload-drag-icon">
						<inbox-outlined />
					</p>
					<p class="ant-upload-text">点击或拖拽文件到此区域上传</p>
					<p class="ant-upload-hint">
						{{ acceptTip }}
					</p>
				</a-upload-dragger>
			</div>

			<!-- 下载模板链接 -->
			<div v-if="showTemplate" class="template-section">
				<a-alert type="info" show-icon>
					<template #message>
						<span>请先下载模板，按照模板格式填写数据后上传</span>
					</template>
					<template #action>
						<a-button type="link" size="small" :loading="templateLoading" @click="handleDownloadTemplate"> <download-outlined /> 下载模板 </a-button>
					</template>
				</a-alert>
			</div>

			<!-- 上传提示 -->
			<div v-if="tip" class="tip-section">
				<a-alert type="warning" show-icon>
					<template #message>{{ tip }}</template>
				</a-alert>
			</div>
		</div>
	</a-modal>
</template>

<script setup>
import { ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { InboxOutlined, DownloadOutlined } from '@ant-design/icons-vue'

const props = defineProps({
	// 是否显示弹窗
	open: {
		type: Boolean,
		default: false,
	},
	// 弹窗标题
	title: {
		type: String,
		default: '导入数据',
	},
	// 导入API接口
	api: {
		type: Function,
		required: true,
	},
	// 下载模板API接口
	templateApi: {
		type: Function,
		default: null,
	},
	// 接受的文件类型
	accept: {
		type: String,
		default: '.xlsx,.xls,.csv',
	},
	// 文件大小限制（MB）
	maxSize: {
		type: Number,
		default: 10,
	},
	// 是否显示下载模板
	showTemplate: {
		type: Boolean,
		default: true,
	},
	// 提示信息
	tip: {
		type: String,
		default: '',
	},
	// 文件名（用于下载）
	filename: {
		type: String,
		default: '导入数据',
	},
})

const emit = defineEmits(['update:open', 'success', 'error', 'change'])

// 弹窗显示状态
const visible = ref(false)

// 文件列表
const fileList = ref([])

// 加载状态
const loading = ref(false)
const templateLoading = ref(false)

// 表单数据（用于插槽）
const formData = ref({})

// 文件类型提示
const acceptTip = ref(props.accept || '支持 .xlsx, .xls, .csv 格式文件')

// 监听外部 open 变化
watch(
	() => props.open,
	(val) => {
		visible.value = val
		if (val) {
			// 打开时重置表单
			fileList.value = []
			formData.value = {}
		}
	},
	{ immediate: true },
)

// 监听内部 visible 变化，同步到外部
watch(visible, (val) => {
	emit('update:open', val)
})

// 自定义上传
const customUpload = (options) => {
	const { onSuccess } = options
	// 这里不直接上传，只是标记为准备上传
	onSuccess({}, options.file)
}

// 上传前校验
const beforeUpload = (file) => {
	// 文件类型校验
	const acceptTypes = props.accept.split(',').map((type) => type.trim().toLowerCase())
	const fileName = file.name.toLowerCase()
	const isValidType = acceptTypes.some((type) => fileName.endsWith(type))

	if (!isValidType) {
		message.error(`文件格式不正确，仅支持 ${props.accept} 格式`)
		return false
	}

	// 文件大小校验
	const maxSizeBytes = props.maxSize * 1024 * 1024
	if (file.size > maxSizeBytes) {
		message.error(`文件大小不能超过 ${props.maxSize}MB`)
		return false
	}

	return true
}

// 处理文件变化
const handleChange = ({ fileList: newFileList }) => {
	fileList.value = newFileList
	emit('change', newFileList)
}

// 拖拽相关
const handleDrop = (e) => {
	e.preventDefault()
}

// 下载模板
const handleDownloadTemplate = async () => {
	if (!props.templateApi) {
		message.error('未配置模板下载接口')
		return
	}

	try {
		templateLoading.value = true
		const blob = await props.templateApi()

		// 创建下载链接
		const url = window.URL.createObjectURL(blob)
		const link = document.createElement('a')
		link.href = url
		link.download = `${props.filename}-模板.xlsx`
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		window.URL.revokeObjectURL(url)

		message.success('模板下载成功')
	} catch (error) {
		message.error('模板下载失败：' + error.message)
	} finally {
		templateLoading.value = false
	}
}

// 确认导入
const handleOk = async () => {
	if (fileList.value.length === 0) {
		message.error('请选择要导入的文件')
		return
	}

	const file = fileList.value[0]
	const formDataObj = new FormData()

	// 添加文件
	if (file.originFileObj) {
		formDataObj.append('file', file.originFileObj)
	} else if (file.url) {
		// 如果是已有文件，可能需要重新处理
		message.error('请重新选择文件')
		return
	}

	// 添加表单参数（如果有）
	if (Object.keys(formData.value).length > 0) {
		Object.keys(formData.value).forEach((key) => {
			const value = formData.value[key]
			if (value !== null && value !== undefined && value !== '') {
				if (Array.isArray(value)) {
					formDataObj.append(key, JSON.stringify(value))
				} else if (typeof value === 'object') {
					formDataObj.append(key, JSON.stringify(value))
				} else {
					formDataObj.append(key, value)
				}
			}
		})
	}

	try {
		loading.value = true
		const res = await props.api(formDataObj)

		if (res.code === 200 || res.success) {
			message.success('导入成功')
			emit('success', res.data, res)
			handleCancel()
		} else {
			message.error(res.message || '导入失败')
			emit('error', res.message, res)
		}
	} catch (error) {
		message.error('导入失败：' + error.message)
		emit('error', error.message, error)
	} finally {
		loading.value = false
	}
}

// 取消导入
const handleCancel = () => {
	visible.value = false
	fileList.value = []
	formData.value = {}
}
</script>

<style scoped>
.import-modal {
	padding: 10px 0;
}

.form-params {
	margin-bottom: 20px;
	padding: 16px;
	background-color: #fafafa;
	border-radius: 4px;
}

.upload-section {
	margin-bottom: 20px;
}

.template-section {
	margin-bottom: 16px;
}

.tip-section {
	margin-bottom: 16px;
}

.ant-upload-drag-icon {
	margin-bottom: 8px;
	font-size: 48px;
}

.ant-upload-text {
	margin-bottom: 8px;
	font-size: 14px;
}

.ant-upload-hint {
	font-size: 12px;
	color: rgba(0, 0, 0, 0.45);
}
</style>
