<template>
	<!-- #ifdef APP-->
	<view class="l-barcode" ref="barcodeRef"></view>
	<!-- #endif -->
	<!-- #ifndef APP-->
	<view class="l-barcode" :style="[styles, lStyle]">
		<canvas class="l-barcode__canvas" id="barcode"></canvas>
	</view>
	<!-- #endif -->
</template>
<script lang="uts" setup>
	/**
	 * BarCode 条形码组件
	 * @description 用于生成各类条形码的显示组件，支持多种编码格式和样式配置
	 * <br> 插件类型：LBarcodeComponentPublicInstance 
	 * @tutorial https://ext.dcloud.net.cn/plugin?name=lime-barcode
	 * 
	 * @property {string} format 条形码格式（必填）'CODE128' | 'EAN-13' | 'UPC' | 'CODE39' | 'ITF-14' 等标准格式
	 * @value 'CODE128'
	 * @value 'EAN-13'
	 * @value 'UPC'
	 * @value 'CODE39'
	 * @value 'ITF-14'
	 * @property {string | number} lineWidth 条线宽度（单位px）
	 * @property {string | number} lineLength 条线长度（单位px）
	 * @property {boolean} displayValue 是否显示条码下方文本
	 * @property {string} text 自定义显示文本（覆盖默认编码值）
	 * @property {string} fontOptions 字体样式扩展（预留字段）
	 * @property {string} [font] 字体名称（例：'bold 16px Arial'）
	 * @property {'left' | 'center' | 'right'} textAlign 文本水平对齐
	 * @property {'top' | 'bottom'} textPosition 文本相对位置
	 * @property {string | number} textMargin 文本与条码间距（单位px）
	 * @property {string | number} fontSize 文本字号（单位px）
	 * @property {string} background 背景颜色（支持CSS颜色值）
	 * @property {string} lineColor 条线颜色（支持CSS颜色值）
	 * @property {string | number} margin 整体外边距（单位px）
	 * @property {string | number} marginTop 上边距（优先级高于margin）
	 * @property {string | number} marginBottom 下边距（优先级高于margin）
	 * @property {string | number} marginLeft 左边距（优先级高于margin）
	 * @property {string | number} marginRight 右边距（优先级高于margin）
	 * @property {boolean} flat 是否启用扁平样式（去除空白区域）
	 * @property {boolean} ean128 是否启用EAN-128扩展格式
	 * @property {boolean} useCanvasToTempFilePath 是否启用canvas生成临时路径
	 * @property {string} lStyle 预留样式扩展字段
	 * @event {Function} success 条码生成成功时触发
	 */
	import { unitConvert } from '@/uni_modules/lime-shared/unitConvert';
	// #ifdef APP
	import { renderer, LBarcodeGenOptions } from '@/uni_modules/lime-barcodegen';
	// #endif
	// #ifndef APP
	import { addUnit } from '@/uni_modules/lime-shared/addUnit'
	import { useCanvas } from './useCanvas'
	import { CanvasRenderer } from './barcode.ts'
	import { LBarcodeGenOptions } from '@/uni_modules/lime-barcodegen/utssdk/interface';
	// #endif
	import type { LBarcodeFailCallback, LBarcodeCompleteCallback, LBarcodeSuccessCallback, BarCodeProps} from './type'
	// defineOptions({name: 'l-barcode'})
	
	const emits = defineEmits(['success'])
	const props = withDefaults(defineProps<BarCodeProps>(), {
		format:'',
		displayValue: true,
		text: '',
		fontOptions: '',
		textPosition: '',
		flat: false,
		ean128: false,
		useCanvasToTempFilePath: false,
	})
	const barcodeRef = ref<UniElement|null>(null)
	// #ifndef APP
	const canvasId = 'barcode'
	const instance = getCurrentInstance()!.proxy!;
	const canvas = useCanvas(canvasId, instance)
	const styles = computed(() => {
		return {
			width:  addUnit(canvas.width),
			height: addUnit(canvas.height),
		}
	})
	// #endif
	
	const canvasToTempFilePath = (options: UTSJSONObject)=>{
		// #ifdef APP
		const format =   options.getString('format') ?? 'png';
		const fail =     options.get('fail') as LBarcodeFailCallback | null;
		const complete = options.get('complete') as LBarcodeCompleteCallback | null;
		const success =  options.get('success') as LBarcodeSuccessCallback | null;
		
		if(barcodeRef.value == null) {
			fail?.({
				errMsg: '插件未加载完成!'
			})
			return
		}
		
		barcodeRef.value?.takeSnapshot({
			format,
			success(res : TakeSnapshotSuccess) {
				if(success == null) return
				success({
					errMsg: "canvasToTempFilePath:ok",
					tempFilePath: res.tempFilePath
				})
				
			},
			fail(err: TakeSnapshotFail) {
				if(fail == null) return
				fail({
					errMsg: err.errMsg
				})
			},
			complete(res: any) {
				if(complete == null) return
				complete(res)
			}
		})
		// #endif
		// #ifndef APP
		if(canvas.node){
			if(canvas._node){
				const result = {
					errMsg: "canvasToTempFilePath:ok",
					tempFilePath: canvas.node?.toDataURL() 
				}
				options.success?.(result)
			} else {
				uni.canvasToTempFilePath({
					canvasId,
					...options,
				}, instance)
			}
		}
		// #endif
	}
	const callback = ()=>{
		if (props.useCanvasToTempFilePath) {
			setTimeout(() => {
				canvasToTempFilePath({
					success: (res: TakeSnapshotSuccess) => {
						emits('success', res.tempFilePath)
					},
					fail: (_: TakeSnapshotFail) => {
						uni.showToast({
							icon: 'error',
							title: '截图失败'
						})
					}
				})
			},200)
		}
	}
	
	const setOptions = () => {
		const options:LBarcodeGenOptions = {
		 	format: props.format,
		 	displayValue: props.displayValue,
		 	text: props.text,
		 	textPosition: props.textPosition,
		 	lineColor: props.lineColor,
		 	flat: props.flat,
		 	ean128: props.ean128,
		 	fontOptions: props.fontOptions,
		 	width: unitConvert(props.lineWidth ?? 2),
		 	height: unitConvert(props.lineLength ?? 60),
		 	textMargin: props.textMargin ==  null ? null : unitConvert(props.textMargin),
		 	fontSize: props.fontSize ==  null ? null : unitConvert(props.fontSize),
		 	margin: unitConvert(props.margin ?? 10),
		 	marginTop: props.marginTop ==  null ? null : unitConvert(props.marginTop),
		 	marginBottom: props.marginBottom ==  null ? null : unitConvert(props.marginBottom),
		 	marginLeft: props.marginLeft ==  null ? null : unitConvert(props.marginLeft),
		 	marginRight: props.marginRight ==  null ? null : unitConvert(props.marginRight)
		} 
		 // #ifdef APP
		 if(barcodeRef.value == null) return
		 barcodeRef.value?.getBoundingClientRectAsync()?.then(res=>{
			 renderer(barcodeRef.value!, `${props.text}`, options)
			 callback()
		 })
		 // #endif
		// #ifndef APP
		// @ts-ignore
		if(canvas.node == null) return
		// @ts-ignore
		CanvasRenderer(canvas.node, `${props.text}`, options, callback) 
		// #endif
	}
	
	onMounted(()=>{
		 nextTick(()=>{
			 watchEffect(setOptions)
		 })
	 })
	
	defineExpose({
		canvasToTempFilePath
	})
	
</script>
<style lang="scss">
	/* #ifndef APP-ANDROID || APP-IOS || APP-HARMONY */
	:host {
		display: inline-block;
	}
	/* #endif */ 
	
	.l-barcode {
		&__text {
			align-self: flex-start;
		}
		&__canvas {
			width: 100%;
			height: 100%;
		}
		/* #ifdef WEB */
		align-self: start;
		/* #endif */ 
	}
	
</style>

