<template>
	<a-button type="primary" @click="beiginScan">开始扫码</a-button>
	<a-button type="primary" danger style="left: 20px" @click="clearScanData">全部重扫</a-button>
	<a-input
		ref="snInput"
		v-model:value="value"
		bordered
		size="large"
		placeholder="输入条形码"
		style="margin-top: 20px; margin-bottom: 20px"
		@press-enter="autoInsertOneRow"
	/>
	<slot></slot>
	<a-row style="margin-bottom: 20px">
		<a-col :span="12">
			<a-statistic title="扫码合计" :value="totalValue" style="margin-right: 50px" />
		</a-col>
		<a-col :span="12">
			<a-statistic title="已扫码" :value="remainderValue" />
		</a-col>
	</a-row>
	<!-- Esc键退出编辑功能 -->
	<vxe-table
		ref="applyDetailTableRef"
		border
		stripe
		show-overflow
		max-height="500"
		:column-config="{ resizable: true }"
		:keyboard-config="{ isEsc: true }"
		size="medium"
		empty-text="请先扫码物料体条码"
		:edit-config="{ trigger: 'click', mode: 'cell' }"
	>
		<vxe-column type="seq" title="序号" width="60"></vxe-column>
		<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
		<vxe-column field="barcode" title="物料条码" />
		<vxe-column field="name" title="物料名称" />
		<vxe-column field="code" title="编码" />
		<vxe-column field="spec" title="规格" />
		<vxe-column field="typeName" title="类型" />
		<vxe-column field="times" title="扫码时间" />
		<vxe-column field="oprator" title="操作">
			<template #default="{ row }">
				<vxe-button mode="text" status="error" @click="removeStep2Row(row)">删除</vxe-button>
			</template>
		</vxe-column>
	</vxe-table>
</template>

<script lang="ts" setup>
	import { VxeTableInstance } from 'vxe-table'
	import { useTemplateRef } from 'vue'
	import { api } from '@/api'
	import { message } from 'ant-design-vue'

	// 父组件数据交互
	const props = defineProps({
		totalValue: {
			type: Number,
			default: 0,
		},
		applyId: {
			type: Number,
			required: false,
			default: 0,
		},
	})

	//获取扫码的集合
	const getTableData = () => {
		const $table = applyDetailTableRef.value
		if ($table) {
			return $table.getTableData().fullData.map((item) => ({
				assignRule: item.assignRule,
				materialId: item.id,
				barcode: item.barcode,
				code: item.code,
				date: item.times,
			}))
		}
	}

	// 获取盘点审核的数据
	const getApplyData = () => {
		const $table = applyDetailTableRef.value
		if ($table) {
			return $table.getTableData().fullData.map((item) => ({
				applyId: props.applyId,
				materialId: item.id,
				barcode: item.barcode,
			}))
		}
	}

	defineExpose({ getTableData, getApplyData })

	const remainderValue = ref(0)

	//扫码的条形码字符串
	const value = ref('')
	const input = useTemplateRef('snInput')

	const snListCache = ref<string[]>([]) // 缓存扫码的条形码列表
	// 定义一个map缓存物料信息
	const materialMapCache = ref<Map<string, material.Material>>(new Map<string, material.Material>()) // 缓存物料信息,key是code

	/**
	 * 请求接口获取缓存数据
	 */
	const getCache = () => {
		api.materialApi.material.all({}, (data) => {
			data.forEach((item) => {
				if (item.code) {
					materialMapCache.value.set(item.code, item) // 物料编码定义为6位
				}
			})
		})
	}
	getCache()

	interface TableRowVO {
		id: number
		barcode: string
		assignRule: boolean
		name: string
		code: string
		spec: string
		type: string
		typeName: string
		times: string
	}

	// 扫码点货的table对象
	const applyDetailTableRef = ref<VxeTableInstance<TableRowVO>>()

	// 移除table中的行
	const removeStep2Row = async (row: TableRowVO) => {
		const $table = applyDetailTableRef.value
		if ($table) {
			$table.remove(row)
			//删除缓存的sn
			snListCache.value = snListCache.value.filter((item) => item !== row.barcode)

			// 已扫码数量-1
			remainderValue.value = remainderValue.value - 1
		}
	}

	function beiginScan() {
		// input.value?.focus()
		const el = input.value as HTMLInputElement | null
		if (el) {
			el.focus()
		}
	}

	// 点击开始扫码按钮，自动新增一行 或者 扫码结束后也自动新增一行
	const autoInsertOneRow = async () => {
		const $table = applyDetailTableRef.value
		const sn = value.value.trim()

		/**
		 * 1. 判断sn是否合法
		 * 2. 判断sn是否已经存在于表格中，需要缓存sn列表
		 * 3. 根据sn获取物料信息，并新增一行到表格中,需要缓存物料信息
		 * 4. 插入成功后缓存sn
		 */
		if (sn.length === 0) {
			value.value = ''
			message.warning('【' + sn + '】条形码为空，请重新扫码', 5)
			return
		}
		if (snListCache.value.includes(sn)) {
			value.value = ''
			message.warning('【' + sn + '】条形码重复，请重新扫码', 5)
			return
		}
		// 找到条形码对应的物料编码
		const code = sn.slice(0, 5)
		const materialInfo = materialMapCache.value.get(code)
		if (!materialInfo) {
			value.value = ''
			message.warning('【' + sn + '】条形码不合法，请重新扫码', 5)
			return
		}

		if ($table) {
			const row: TableRowVO = {
				id: materialInfo?.id ?? 0,
				barcode: sn,
				assignRule: materialInfo?.assignRule ?? false,
				name: materialInfo?.name ?? '',
				code: materialInfo?.code ?? '',
				spec: materialInfo?.spec ?? '',
				type: materialInfo?.type ?? '',
				typeName: materialInfo?.typeName ?? '',
				times: new Date().toLocaleString(),
			}
			$table.insert(row)
			// 缓存sn
			snListCache.value.push(sn)
			//已扫码数量+1

			remainderValue.value = remainderValue.value + 1
			// 添加后就清空输入框
			value.value = ''
		}
	}

	// 清空扫码数据
	const clearScanData = () => {
		const $table = applyDetailTableRef.value
		if ($table) {
			$table.remove()
			snListCache.value = []
			remainderValue.value = 0
		}
	}
</script>
