<script setup lang="ts">
import {nextTick, reactive, ref} from 'vue'
import * as XLSX from 'xlsx';
import {Delete} from '@element-plus/icons-vue'
import Drawer from '@/components/Drawer/index.vue'
import type {FormInstance, FormRules} from 'element-plus'
import {ElMessage} from 'element-plus'
import {Storehouse_Device_Check} from '@/api/storehouse'

type Fn = () => void

interface FormSnType {
	Id?: number
	sn: string
	type?: number
	T_product_id?: number
	T_date?: string
}

const snTable = ref()
const snCount = ref(null)
const SNDataMap = new Map<number, FormSnType[]>()
const tableSnData = ref<FormSnType[]>([])
const ruleSnFormRef = ref<FormInstance>()
const drawerSnRef = ref<InstanceType<typeof Drawer> | null>(null)

const snColumns = [
	{type: 'index', label: '序号', width: 80, align: 'center '},
	{label: 'SN', prop: 'sn', align: 'center '},
	{prop: 'operation', label: '操作', width: 80, fixed: 'right'}
]
const formSn = reactive<FormSnType>({
	Id: undefined,
	sn: '',
	type: undefined,
	T_product_id: undefined,
	T_date: undefined
})
const rulesSn = reactive<FormRules>({
	sn: [{required: true, message: '请输入SN号', trigger: 'blur'}]
})

const addSn = (e: any) => {
	// 阻止默认行为，防止表单提交导致页面跳转
	if (e) {
		e.preventDefault()
		e.stopPropagation()
	}
	addSns(ruleSnFormRef.value)
	return false
}

const addSns = (formEl: FormInstance | undefined) => {
	if (!formEl) return
	formEl.validate(async valid => {
		if (valid) {
			if (snCount.value !== null && snCount.value <= tableSnData.value.length) {
				ElMessage.error('出库数量与扫码数量不一致')
				return
			}
			if (formSn.sn.length === 16 || formSn.sn.length === 24) {
				if (formSn.sn.length == 24) {
					formSn.sn = formSn.sn.substring(2, formSn.sn.length - 6)
				}
				const res: any = await Storehouse_Device_Check({
					T_product_id: formSn.T_product_id,
					T_sn: formSn.sn,
					T_type: formSn.type,
					T_date: formSn.T_date
				})
				if (res.Code === 200) {
					tableSnData.value.unshift({sn: formSn.sn})
					tableSnData.value = tableSnData.value.filter((value, index, self) => {  //去重
						return self.findIndex(t => (t.sn === value.sn)) === index;
					});
					nextTick(() => {
						resetSnForm(ruleSnFormRef.value)
					})
				}
			} else {
				ElMessage.error('扫描设备异常')
				nextTick(() => {
					resetSnForm(ruleSnFormRef.value)
				})
				return
			}
		}
	})
}
const deleteSn = (row: any) => {
	const index = tableSnData.value.findIndex((item: any) => row.sn === item.sn)
	tableSnData.value.splice(index, 1)
}

const callbackSnDrawer = (done: Fn) => {
	SNDataMap.set(formSn.Id as number, tableSnData.value)
	let arrs = tableSnData.value.map((item: any) => item.sn);
	emit('onCount', SNDataMap.get(formSn.Id as number)?.length, formSn.Id as number, arrs)
	done()
	nextTick(() => {
		resetSnForm(ruleSnFormRef.value)
		tableSnData.value = []
	})
}

const emit = defineEmits<{ (event: 'onCount', value: any, id: number, mapArr: any): void }>()

const resetSnForm = (formEl: FormInstance | undefined) => {
	if (!formEl) return
	formEl.resetFields()
}

const addDeviceSn = (id: number, type: number, T_product_id: number, date?: string) => {
	if (!date) {
		ElMessage.warning('请先填写出库日期')
		return
	}
	formSn.Id = id
	formSn.type = type
	formSn.T_product_id = T_product_id
	formSn.T_date = date
	if (SNDataMap.has(id)) {
		tableSnData.value = SNDataMap.get(id) as FormSnType[]
	} else {
		SNDataMap.set(id, [])
	}
	drawerSnRef.value?.openDrawer()
}

const drawer = ref(false)
/**
 * 导入xlsx
 */

// 组件状态变化的回调
const uploadExcelFile = (event: any) => {
	const files = event.target.files;
	if (files.length === 0) return;
	const file = files[0];
	const reader = new FileReader();
	reader.onload = (e: any) => {
		const data = new Uint8Array(e.target.result);
		const workbook = XLSX.read(data, {type: 'array'});
		// 假设我们知道第一个工作表包含我们需要的数据
		const firstSheetName = workbook.SheetNames[0];
		const worksheet: any = workbook.Sheets[firstSheetName];
		// 假设我们知道 t_sn 是第一列
		const tSnColumn = 'A'; // 或者使用 XLSX.utils.decode_col(columnNumber) 来从列号获取列名
		const columnNumber = XLSX.utils.decode_col(tSnColumn); // 但实际上我们可能直接知道列号，如 0
		// 使用 sheet_to_json 但只选择我们需要的列
		const json = XLSX.utils.sheet_to_json(worksheet, {
			header: 1,
			range: XLSX.utils.decode_range(worksheet['!ref'])
		});
		// 如果表头不是第一行，或者你不想要表头，可以调整 header 选项
		// 提取 t_sn 列的数据（假设表头在第一行，且 t_sn 是第一列）
		let tSnData: any = json.map((row: any) => row[0]); // 假设 t_sn 是第一列，所以使用 row[0]
		let snArray = tSnData.map((sn: any) => ({sn: sn}));
		snArray = snArray.slice(1)
		let arrs = [...tableSnData.value, ...snArray]
		// 去重
		let seen = new Set();
		tableSnData.value = arrs.filter((item: any) => {
			return seen.has(item.sn) ? false : seen.add(item.sn) || true;
		});

		console.log('打印', tableSnData.value)
		// 注意：如果 t_sn 列不是第一列，你需要调整索引号
		// 例如，如果 t_sn 是第三列，则使用 row[2]
	};

	reader.readAsArrayBuffer(file);

};
const getDeviceSn = () => SNDataMap
const clearDeviceSn = () => SNDataMap.clear()
const deleteDeviceSn = (id: number) => SNDataMap.delete(id)
defineExpose({
	getDeviceSn,
	addDeviceSn,
	clearDeviceSn,
	deleteDeviceSn, tableSnData, drawerSnRef, snCount
})
</script>

<template>
	<Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" :snCount="snCount"  :closeModal="false" size="50%">
		<el-card class="box-card" shadow="never">
			<template #header>
				<div class="sn-header">
					<el-form ref="ruleSnFormRef" :model="formSn" :rules="rulesSn" @submit.prevent="addSns(ruleSnFormRef)">
						<el-form-item label="SN：" label-width="120px" prop="sn">
							<el-input 
								v-model="formSn.sn" 
								type="text" 
								placeholder="请输入SN"
								@keyup.enter.prevent="addSn" 
								@keydown.enter.prevent
								class="w-50"
							/>
						</el-form-item>
					</el-form>
					<el-button type="primary" @click="addSns(ruleSnFormRef)">添加</el-button>
					<el-button type="success" @click="drawer = true">导入xlsx</el-button>
				</div>
			</template>
			<div>数量：{{ tableSnData.length }}</div>
			<el-table
				ref="snTable"
				:data="tableSnData"
				style="width: 100%; height: 99%"
				:header-cell-style="{
          background: '#dedfe0',
          height: '50px'
        }"
			>
				<template v-for="item in snColumns" :key="item">
					<el-table-column v-if="item.type === 'index'" v-bind="item"/>
					<el-table-column show-overflow-tooltip v-if="item.prop" align="center" v-bind="item">
						<template #default="{ row }">
							<el-button
								v-if="item.prop === 'operation'"
								link
								type="danger"
								size="small"
								:icon="Delete"
								@click="deleteSn(row)"
							>删除
							</el-button
							>
						</template>
					</el-table-column>
				</template>
			</el-table>
		</el-card>
		<el-drawer v-model="drawer" title="导入xlsx" size="50%" :destroy-on-close="true">
			<input type="file" @change="uploadExcelFile" accept=".xlsx, .xls"/>
		</el-drawer>
	</Drawer>

</template>

<style scoped lang="scss">
.box-card {
	height: 100%;

	:deep(.el-card__body) {
		height: calc(100% - 70px);
	}

	.sn-header {
		display: flex;
		justify-content: end;
	}
}
</style>
