<script setup lang="ts">
import type { FormItemRule } from "element-plus/es/components/form/src/types"
import type { VbFormItem, VbFormRowItem } from "@@@/form/models"

const props = withDefaults(
	defineProps<{
		options?: any
		url?: string
		templateUrl?: string
		templateName?: string
		isAlertError?: boolean
		showUpdateCheckbox?: boolean // 是否显示 更新复选框
		accept?: string
		fileName?: string
		headers?: any
		title?: string
		saveAutoClose?: boolean
		formData?: any
		formRowItems?: VbFormRowItem[]
		formItems?: VbFormItem[]
		formRules?: Record<string, FormItemRule[]>
		formLabelWidth?: string | number // 表单label宽度
		formSize?: "large" | "default" | "small"
		gutter?: number
		span?: number
		formProps?: object
		formListeners?: object
		modalFormClass?: string
		modalFormStyle?: string
		isValidateForm?: boolean //验证表单
		params?: object | (() => {})
		appendToBody?: boolean
	}>(),
	{
		title: "",
		headers: () => {
			return {
				Authorization: "Bearer " + getToken(),
				ClientId: import.meta.env.VITE_APP_CLIENT_ID
			}
		},
		accept: ".xlsx, .xls",
		templateUrl: "",
		templateName: "",
		fileName: "file",
		isAlertError: true,
		appendToBody: true,
		showUpdateCheckbox: false,
		isValidateForm: true,
		saveAutoClose: true,
		formLabelWidth: "100px",
		formSize: "large",
		modalFormClass: "vb-form",
		modalFormStyle: ""
	}
)
const emits = defineEmits<{
	(e: "modelValue:value", v: string): void
	(e: "update:formData", data: any): boolean
	(e: "onProgress", event: any, file: any, fileList: any): void
	(e: "onSuccess", response: any, file: any, fileList: any): void
	(e: "onError", error: Error, file: any, fileList: any): void
	(e: "onConfirm"): void
}>()
const { formData } = toRefs(props)
const modalFormRef = ref<HTMLFormElement>()
const uploadModalRef = ref()
const uploadRef = ref()
const uploadUpdateSupport = ref(false)
const isUploading = ref(false)
const opts = ref<any>({})

const url = computed(() => {
	let queryParams = "?t=" + new Date().getTime()
	if (opts.value.showUpdateCheckbox) {
		queryParams += `&updateSupport=${uploadUpdateSupport.value}`
	}
	if (opts.value.params) {
		const data =
			typeof opts.value.params === "function"
				? opts.value.params()
				: typeof opts.value.params === "object"
					? props.params
					: {}
		for (const key in data) {
			if (data.hasOwnProperty(key)) {
				queryParams += `&${key}=${data[key]}`
			}
		}
	}
	// if (formData.value) {
	// 	for (const key in formData.value) {
	// 		if (formData.value.hasOwnProperty(key)) {
	// 			queryParams += `&${key}=${formData.value[key]}`
	// 		}
	// 	}
	// }
	return `${opts.value.url}${queryParams}`
})

function submitUpload() {
	if (modalFormRef.value && props.isValidateForm) {
		modalFormRef.value.validate().then((valid: boolean) => {
			if (valid) {
				uploadRef.value.submit()
				emits("onConfirm")
				if (props.saveAutoClose) {
					uploadModalRef.value.hide()
				}
			} else {
				console.error("UPLOAD_FORM 验证失败")
			}
		})
	} else {
		uploadRef.value.submit()
		emits("onConfirm")
		if (props.saveAutoClose) {
			uploadModalRef.value.hide()
		}
	}
}

/** 文件上传中处理 */
function handleFileUploadProgress(event: any, file: any, fileList: any) {
	isUploading.value = true
	message.loading()
	emits("onProgress", event, file, fileList)
}

/** 文件上传成功处理 */
function handleFileSuccess(response: any, file: any, fileList: any) {
	isUploading.value = false
	uploadRef.value.handleRemove(file)
	message.alert(
		"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
			response.msg +
			"</div>",
		"导入结果",
		{ dangerouslyUseHTMLString: true }
	)
	message.closeLoading()
	emits("onSuccess", response, file, fileList)
}
function handleFileError(error: Error, file: any, fileList: any) {
	message.closeLoading()
	if (opts.value.isAlertError) {
		message.msgError(error.message)
	}
	emits("onError", error, file, fileList)
}
function importTemplate() {
	download(
		opts.value.templateUrl,
		`${opts.value.templateName}_TEMPLATE_${new Date().getTime()}.xlsx`
	)
}
function getUploadData() {
	return formData.value
}

//form表单的插槽 需要_form结尾,并去掉_form传递给VbForm组件
function isFormSlot(v: string | number): string | undefined {
	let str
	const formSlotSuffix = "_form"
	v = v as string
	if (v.search(formSlotSuffix) > 0) {
		str = v.substring(0, v.length - formSlotSuffix.length)
	}
	return str
}
function init() {
	opts.value = props.options ? Object.assign({}, props, props.options) : props
	if (!opts.value.url) {
		throw new Error("uploadUrl不能为空！")
	}
}
function show() {
	uploadModalRef.value.show()
}
onMounted(init)
defineExpose({ show })
</script>
<template>
	<VbModal
		v-model:modal="uploadModalRef"
		:title="opts.title"
		:save-auto-close="false"
		@confirm="submitUpload"
		:append-to-body="appendToBody"
		v-bind="$attrs">
		<template #body>
			<slot name="params_form"></slot>
			<VbForm
				v-if="formRowItems || formItems"
				ref="modalFormRef"
				v-model:data="formData"
				:row-items="formRowItems"
				:items="formItems"
				:label-width="formLabelWidth"
				:rules="formRules"
				:size="formSize"
				:class="modalFormClass"
				:style="modalFormStyle"
				:span="span"
				:gutter="gutter"
				v-bind="formProps"
				v-on="formListeners">
				<template v-for="(_, name) in $slots" #[`${isFormSlot(name)}`]>
					<slot v-if="isFormSlot(name)" :name="name" />
				</template>
			</VbForm>
			<el-upload
				ref="uploadRef"
				:limit="1"
				:accept="opts.accept"
				:headers="opts.headers"
				:action="url"
				:name="opts.fileName"
				:data="getUploadData"
				:disabled="isUploading"
				:on-progress="handleFileUploadProgress"
				:on-success="handleFileSuccess"
				:on-error="handleFileError"
				:auto-upload="false"
				drag>
				<el-icon class="el-icon--upload"><upload-filled /></el-icon>
				<div class="el-upload__text">
					将文件拖到此处，或
					<em>点击上传</em>
				</div>
				<template #tip>
					<div class="el-upload__tip text-center">
						<div class="el-upload__tip">
							<el-checkbox v-if="opts.showUpdateCheckbox" v-model="uploadUpdateSupport" />
							是否更新已经存在的数据
						</div>
						<span>仅允许导入{{ opts.accept }}格式文件。</span>
						<el-link
							v-if="opts.templateUrl"
							type="primary"
							:underline="false"
							style="font-size: 12px; vertical-align: baseline"
							@click="importTemplate">
							下载模板
						</el-link>
					</div>
				</template>
			</el-upload>
		</template>
	</VbModal>
</template>
