<template>
	<picker-view 
		class="l-picker-item__group"
		:style="{opacity: options.length > 0 ? 1 : 0}"
		:mask-style="maskStyle"
		:mask-top-style="maskTopStyle"
		:mask-bottom-style="maskBottomStyle"
		:indicator-style="indicatorStyles" 
		mask-class="l-picker-item__mask"
		:value="innerIndex" 
		@change="handlePick"
		indicator-class="l-picker-item__indicator">
		<picker-view-column class="l-picker-item__wrapper">
			<!-- #ifdef APP-ANDROID -->
			<view ref="itemRef"></view>
			<!-- #endif -->
			<!-- #ifndef APP-ANDROID -->
			<text class="l-picker-item__group-item" v-for="(item, i) in options"
				:style="[itemStyles, curIndex == i ? itemActiveStyles: {}]"
				:class="{'l-picker-item__group-item--active': curIndex == i}" :key="item.value">{{item.label}}</text>
			<!-- #endif -->
		</picker-view-column>
	</picker-view>
</template>
<script lang="uts" setup>
	/**
	 * PickerItem 选择器子项组件
	 * @description 用于构建多列选择器的单个列项，通常作为 Picker 组件的子组件使用
	 * <br>插件类型：LPickerItemComponentPublicInstance 
	 * @tutorial https://ext.dcloud.net.cn/plugin?name=lime-picker
	 * 
	 * @property {PickerColumnItem[]} options 当前列的选项列表（必填）
	 * @property {PickerValue} value 当前选中值
	 * @property {number} column 列索引标识（从0开始计数）
	 * @property {string | number} name 列名称标识符
	 */
	import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
	import { clamp } from '@/uni_modules/lime-shared/clamp'
	const themeMode = inject('limeConfigProviderTheme', computed(()=> 'light'))
	// import { isDarkMode } from '@/uni_modules/lime-style'
	import type { PickerItemProps, ManageChildInList, OnPick, UpdateItems } from './type';
	import type { PickerColumnItem, PickerValue } from '../l-picker/type';
	const instance = getCurrentInstance()!;
	const props = withDefaults(defineProps<PickerItemProps>(), {
		options: [] as PickerColumnItem[],
		column: -1,
		resetIndex: false
	})
	const picker = inject<LPickerComponentPublicInstance | null>('limePicker', null);
	const pickerItemInstanceArray = inject<LPickerItemComponentPublicInstance[] | null>('limePickerItems', null);
	const manageChildInList = inject<ManageChildInList | null>('limePickerManageChildInList', null);
	manageChildInList?.(instance.proxy! as LPickerItemComponentPublicInstance, true)
	const onPick = inject<OnPick | null>('limePickerOnPick', null);
	const updateItems = inject<UpdateItems | null>('limePickerUpdateItems', null);
	// web 如果初始是0 当数据加载后 无法指向0
	// #ifdef WEB
	const curIndex = ref(-1)
	// #endif
	// #ifndef WEB
	const curIndex = ref(0)
	// #endif
	const curValue = ref<PickerValue | null>(props.value);
	const column = computed(() : number => props.column != -1 ? props.column : pickerItemInstanceArray?.indexOf(instance.proxy! as LPickerItemComponentPublicInstance) ?? props.column);

	const elementPosition = computed(() : boolean[] => {
		const totalElements = pickerItemInstanceArray?.length ?? 0;
		return [column.value == 0, column.value == totalElements - 1]
	});
	const innerIndex = computed(() : number[] => [curIndex.value])
	const isDarkMode = computed(() : boolean => themeMode.value == 'dark')
	const maskStyle = computed(()=>{
		if (isDarkMode.value) {
			return `background-image: 
				linear-gradient(180deg, #242424, rgba(36, 36, 36, 0)),
				linear-gradient(0deg,   #242424, rgba(36, 36, 36, 0))`
			}
			return " ";
	})
	const maskTopStyle = computed(()=>{
		// #ifndef APP-IOS
		if (isDarkMode.value) {
			return `background-image: linear-gradient(
				to bottom,
				#242424,
				rgba(36, 36, 36, 0)
			)`;
		}
		return `background-image: linear-gradient(
				to bottom,
				#fff,
				rgba(255, 255, 255, 0)
			)`;
		// #endif
		
		// #ifdef APP-IOS
		if (isDarkMode.value) {
			return `background-color: rgba(0,0,0,0)`;
		}
		return ``;
		// #endif
	})
	const maskBottomStyle = computed(()=>{
		// #ifndef APP-IOS
		if (isDarkMode.value) {
			return `background-image: linear-gradient(
				to top,
				#242424,
				rgba(36, 36, 36, 0)
			)`;
		}
		return `background-image: linear-gradient(
			to top,
			#fff,
			rgba(255, 255, 255, 0)
		)`;
		// #endif
		// #ifdef APP-IOS
		if (isDarkMode.value) {
			return `background-color: rgba(0,0,0,0)`;
		}
		return ``;
		// #endif
		
	})
	
	const indicatorStyles = computed(() : string => {
		const [isFirst, isLast] = elementPosition.value
		let style = `border-width: 0;`
		
		if(isFirst) {
			style+= `
				border-top-left-radius:6px; 
				border-bottom-left-radius:6px;
				border-top-right-radius: 0px;
				border-bottom-right-radius: 0px;
			`
		}
		if(isLast) {
			style+= `
				border-top-left-radius: 0px;
				border-bottom-left-radius: 0px;
				border-top-right-radius:6px; 
				border-bottom-right-radius:6px;
			`
		}
		const color = isDarkMode.value ? `rgba(255, 255, 255, 0.06)`: `rgba(0, 0, 0, 0.04)`
		return `
			${style}
			height: ${picker?.itemHeight ?? '50px'};
			background-color: ${color}; ${picker?.indicatorStyle ?? ''}`
	})
	const itemStyles = computed(() : Map<string, any> => {
		const style = new Map<string, any>();
		if (picker?.itemColor != null) {
			style.set('color', picker.itemColor!)
		}
		if (picker?.itemFontSize != null) {
			style.set('font-size', picker.itemFontSize!)
		}
		if(picker?.itemHeight != null) {
			style.set('line-height', picker.itemHeight!)
			style.set('height', picker.itemHeight!)
		}
		return style
	})
	const itemActiveStyles = computed(() : Map<string, any> => {
		const style = new Map<string, any>();
		if (picker?.itemActiveColor != null) {
			style.set('color', picker.itemActiveColor!)
		}
		if (picker?.itemActiveFontWeight != null) {
			style.set('font-weight', picker.itemActiveFontWeight!)
		}
		return style
	})


	const getIndexByValue = (val : PickerValue | null) => {
		let defaultIndex = 0;
		if (val != null) {
			defaultIndex = props.options.findIndex((item) => item.value == val);
		}
		return defaultIndex < 0 ? 0 : defaultIndex;
	};

	const setIndex = (index : number) => {
		// setTimeout(()=>{
			let lastIndex = curIndex.value
			let _index = clamp(index, 0,  props.options.length - 1)
			if(props.options.length > _index) {
				curIndex.value = _index;
				curValue.value = props.options[_index].value
			}
			// #ifdef WEB
			if(lastIndex == _index || lastIndex == -1) return
			if (instance.proxy!.$el) {
				const childs = Array.from(instance.proxy!.$el.parentElement.children).slice(column.value + 1);
				childs.forEach((child) => {
					(child as HTMLElement).style.setProperty('--picker-duration', '300ms');
					setTimeout(function () {
						(child as HTMLElement).style.setProperty('--picker-duration', '0ms');
					}, 299);
				})
			}
			// #endif
		// },250)
		
		
	}
	const setValue = (value : PickerValue | null) => {
		if (value == curValue.value) return
		curValue.value = value
		const index = getIndexByValue(value)
		setIndex(index)
	}
	const setOptions = () => { }
	const setUpdateItems = () => {
		const index = clamp(curIndex.value, 0,  props.options.length - 1)
		const curItem = props.options.length > index ? props.options[index] : null;
		if (curItem == null) return
		updateItems?.(curItem, index, column.value);
	}
	
	const handlePick = (e : UniPickerViewChangeEvent) => {
		if(props.options.length == 0) return
		const index = clamp(e.detail.value[0], 0,  props.options.length - 1);
		const curItem = props.options[index];
		if(index == curIndex.value) return
		setIndex(index)
		onPick?.(curItem, index, column.value);
	}

	const stopValue = watch(() : PickerValue | null => props.value, (v : PickerValue | null) => {
		setValue(v);
		setUpdateItems();
	}, { immediate: true })

	// #ifdef APP-ANDROID
	const itemRef = ref<UniElement | null>(null)
	const updateItemStyle = () => {
		if (itemRef.value != null) {
			const ctx = itemRef.value!.getDrawableContext()!
			const height = unitConvert(picker?.itemHeight ?? 50);
			const fontSize = unitConvert(picker?.itemFontSize ?? '32rpx');
			const rect = itemRef.value!.getBoundingClientRect()
			const x = itemRef.value!.offsetWidth / 2;
			const itemActiveFontWeight = picker?.itemActiveFontWeight ?? 700
			itemRef.value!.style.setProperty('height', height * props.options.length);
			ctx.reset()
			
			const color = picker?.itemColor ?? (isDarkMode.value ?  `rgba(255,255,255,0.88)` : 'rgba(0,0,0,0.88)');
			const itemActiveColor = picker?.itemActiveColor ?? (isDarkMode.value ?  `rgba(255,255,255,0.88)` : 'rgba(0,0,0,0.88)');
			
			ctx.font = `${fontSize}px`;
			ctx.textAlign = 'center'
			ctx.lineWidth = 0.5
			props.options.forEach((item, index) => {
				const y = height * index + fontSize + (height - fontSize) * 0.4;  //(height - fontSize * 1.1)
				// 设置选中和未选中的颜色
				const isActive = index == curIndex.value && itemActiveFontWeight > 600;
				ctx.fillStyle = isActive ? itemActiveColor : color;
				ctx.strokeStyle = isActive ? itemActiveColor : color;
				
				ctx.fillText(item.label, x, y)
				if (isActive) {
					ctx.strokeText(item.label, x, y)
				}
			})
			ctx.update()
		}
	}
	// 防止更新后尺寸不对
	watchEffect(()=> {
		if(curIndex.value > 0){}
		if(isDarkMode.value) {
			nextTick(updateItemStyle)
		} else {
			nextTick(updateItemStyle)
		}
		
	})
	const stop = watch(() : PickerColumnItem[] => props.options, (v : PickerColumnItem[], o : PickerColumnItem[]) => {
		nextTick(updateItemStyle)
	})
	
	const resizeObserver = new UniResizeObserver((entries : Array<UniResizeObserverEntry>) => {
		updateItemStyle()
	}) 
	const stopWatch = watch(():UniElement|null => itemRef.value, (el:UniElement|null) => {
		if(el== null) return
		resizeObserver.observe(el)
	})
	// onMounted(() => {
	// 	nextTick(updateItemStyle)
	// })
	
	// #endif
	
	
	onBeforeUnmount(() => {
		manageChildInList?.(instance.proxy! as LPickerItemComponentPublicInstance, false)
		
		// #ifdef APP-ANDROID
		stop()
		stopWatch()
		resizeObserver.disconnect()
		// #endif
	})
	// onMounted(()=>{
	// 	if(props.options.length > 0 && curIndex.value == -1) {
	// 		curIndex.value = 0
	// 	}
	// })
	defineExpose({
		setIndex,
		setValue,
		// setOptions,
		// setUpdateItems,
		getIndexByValue
	})
</script>
<style lang="scss">
	@import './index';
</style>