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

			<!-- 导出选项 -->
			<div v-if="showOptions" class="export-options">
				<a-form layout="vertical">
					<a-form-item label="导出字段" v-if="showFieldSelect">
						<a-select v-model:value="selectedFields" mode="multiple" :options="fieldOptions" placeholder="请选择要导出的字段" :show-arrow="true">
							<template #dropdownRender="{ menuNode: menu }">
								<v-nodes :vnodes="menu" />
								<a-divider style="margin: 4px 0" />
								<div style="padding: 4px 8px">
									<a-button type="text" size="small" @click="selectAllFields">全选</a-button>
									<a-button type="text" size="small" @click="clearAllFields">清空</a-button>
								</div>
							</template>
						</a-select>
					</a-form-item>

					<a-form-item label="导出格式" v-if="showFormatSelect">
						<a-radio-group v-model:value="exportFormat">
							<a-radio value="xlsx">Excel (.xlsx)</a-radio>
							<a-radio value="xls">Excel (.xls)</a-radio>
							<a-radio value="csv">CSV</a-radio>
						</a-radio-group>
					</a-form-item>

					<a-form-item label="文件名">
						<a-input v-model:value="filename" placeholder="请输入文件名" :max-length="50" show-count />
					</a-form-item>
				</a-form>
			</div>

			<!-- 导出提示 -->
			<div v-if="tip" class="tip-section">
				<a-alert type="info" 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'

const props = defineProps({
	// 是否显示弹窗
	open: {
		type: Boolean,
		default: false,
	},
	// 弹窗标题
	title: {
		type: String,
		default: '导出数据',
	},
	// 导出API接口
	api: {
		type: Function,
		required: true,
	},
	// 是否显示导出选项
	showOptions: {
		type: Boolean,
		default: true,
	},
	// 是否显示字段选择
	showFieldSelect: {
		type: Boolean,
		default: false,
	},
	// 字段选项
	fieldOptions: {
		type: Array,
		default: () => [],
	},
	// 是否显示格式选择
	showFormatSelect: {
		type: Boolean,
		default: false,
	},
	// 默认导出格式
	defaultFormat: {
		type: String,
		default: 'xlsx',
	},
	// 默认文件名
	defaultFilename: {
		type: String,
		default: '',
	},
	// 提示信息
	tip: {
		type: String,
		default: '',
	},
})

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

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

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

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

// 导出选项
const selectedFields = ref([])
const exportFormat = ref(props.defaultFormat)
const filename = ref(props.defaultFilename || '导出数据')

// VNodes 组件（用于 dropdownRender）
const VNodes = (_, { attrs }) => {
	return attrs.vnodes
}

// 监听外部 open 变化
watch(
	() => props.open,
	(val) => {
		visible.value = val
		if (val) {
			// 打开时重置表单
			formData.value = {}
			selectedFields.value = []
			exportFormat.value = props.defaultFormat
			filename.value = props.defaultFilename || '导出数据'
		}
	},
	{ immediate: true },
)

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

// 全选字段
const selectAllFields = () => {
	selectedFields.value = props.fieldOptions.map((item) => item.value)
}

// 清空字段
const clearAllFields = () => {
	selectedFields.value = []
}

// 确认导出
const handleOk = async () => {
	// 构建导出参数
	const exportParams = {}

	// 添加表单参数（如果有）
	if (Object.keys(formData.value).length > 0) {
		Object.assign(exportParams, formData.value)
	}

	// 添加字段选择（如果有）
	if (props.showFieldSelect && selectedFields.value.length > 0) {
		exportParams.fields = selectedFields.value
	}

	// 添加格式选择（如果有）
	if (props.showFormatSelect) {
		exportParams.format = exportFormat.value
	}

	try {
		loading.value = true

		// 调用导出接口
		const blob = await props.api(exportParams)

		// 确定文件扩展名
		let ext = exportFormat.value
		if (!props.showFormatSelect && blob.type) {
			// 如果没有格式选择，根据 blob 类型判断
			if (blob.type.includes('sheet') || blob.type.includes('excel')) {
				ext = 'xlsx'
			} else if (blob.type.includes('csv')) {
				ext = 'csv'
			}
		}

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

		message.success('导出成功')
		emit('success', exportParams)
		handleCancel()
	} catch (error) {
		message.error('导出失败：' + error.message)
		emit('error', error.message, error)
	} finally {
		loading.value = false
	}
}

// 取消导出
const handleCancel = () => {
	visible.value = false
	formData.value = {}
	selectedFields.value = []
	filename.value = props.defaultFilename || '导出数据'
}
</script>

<script>
export default {
	name: 'ScExport',
	components: {
		VNodes: {
			render() {
				return this.$slots.default ? this.$slots.default() : null
			},
		},
	},
}
</script>

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

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

.export-options {
	margin-bottom: 20px;
}

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

:deep(.ant-form-item) {
	margin-bottom: 16px;
}

:deep(.ant-form-item:last-child) {
	margin-bottom: 0;
}
</style>
