<template>
	<l-overlay
		:visible="innerValue" 
		:zIndex="overlayZIndex"
		:appear="true"
		:preventScrollThrough="preventScrollThrough"
		:l-style="overlayStyle"
		@click="handleOverlayClick"
		v-if="destroyOnClose ? display && overlay : overlay">
	</l-overlay>
	<view class="l-popup" 
		ref="popupRef"
		v-if="destroyOnClose ? display : inited"
		:class="rootClass" 
		:style="[styles, lStyle]"
		@transitionend="finished">
		<slot></slot>
		<view class="l-popup__close" v-if="closeable" @click="handleClose">
			<slot name="close-btn">
				<l-icon class="l-popup__close-icon" :name="closeIcon" size="27px" :color="iconColor" />
			</slot>
		</view>
	</view>
</template>
<script lang="uts" setup>
	/**
	 * Popup 弹出层组件
	 * @description 提供多种位置的弹窗展示能力，支持自定义内容和动画效果
	 * <br>插件类型：LPopupComponentPublicInstance 
	 * @tutorial https://ext.dcloud.net.cn/plugin?name=lime-popup
	 * 
	 * @property {boolean} closeable 显示关闭按钮（默认：false）
	 * @property {boolean} closeOnClickOverlay 点击遮罩关闭（默认：true）
	 * @property {boolean} destroyOnClose 关闭时销毁内容（默认：false）
	 * @property {string} overlayStyle 遮罩层样式（支持CSS字符串）
	 * @property {'top' | 'left' | 'right' | 'bottom' | 'center' | ''} position 弹出位置
	 * @value top    从顶部滑入
	 * @value bottom 从底部滑入
	 * @value left   从左侧滑入  
	 * @value right  从右侧滑入
	 * @value center 居中显示（默认）
	 * @property {boolean} preventScrollThrough 阻止滚动穿透（默认：true）
	 * @property {boolean} overlay 显示遮罩层（默认：true）
	 * @property {string} transitionName 自定义动画名称（配合transition使用）
	 * @property {string|number|Array} radius 圆角 可以是字符，数值，数组
	 * @property {boolean} visible 控制显示/隐藏（支持v-model）
	 * @property {number} zIndex 组件层级（默认：999）
	 * @property {number} duration 动画时长（单位ms，默认：300）
	 * @property {string} bgColor 内容区域背景色（默认：#ffffff）
	 * @property {string} closeIcon 关闭图标名称/路径（默认：'close'）
	 * @property {string} iconColor 关闭图标颜色（默认：#333）
	 * @property {string} lStyle 自定义内容区样式（支持CSS字符串）
	 * @property {boolean} safeAreaInsetBottom 适配底部安全区域（默认：true）
	 * @property {boolean} safeAreaInsetTop 适配顶部安全区域（默认：true）
	 * @event {Function} close 关闭时触发（返回触发来源：'close-btn' | 'overlay'）
	 * @event {Function} change 切换时触发
	 * @event {Function} click-overlay 点击遮罩触发
	 * @event {Function} click-close 点击关闭触发
	 * @event {Function} open 打开触发
	 * @event {Function} opened 打开完成触发
	 * @event {Function} closed 关闭完成触发
	 * @event {Function} before-enter
	 * @event {Function} enter 
	 * @event {Function} after-enter
	 * @event {Function} before-leave
	 * @event {Function} leave
	 * @event {Function} after-leave
	 */
	import { useTransition, type UseTransitionOptions, type TransitionEmitStatus } from '@/uni_modules/lime-transition';
	import { convertRadius } from './utils'
	import { PopupProps } from './type';
	
	const emit = defineEmits(['change', 'click-overlay', 'click-close', 'open', 'opened','close','closed', 'before-enter', 'enter', 'after-enter', 'before-leave', 'leave', 'after-leave'])
	const props = withDefaults(defineProps<PopupProps>(),{
		closeable: false,
		overlay: true,
		closeOnClickOverlay: true,
		preventScrollThrough: true,
		destroyOnClose: false,
		safeAreaInsetBottom: true,
		safeAreaInsetTop: false,
		position: 'center',
		zIndex: 999,
		duration: 300,
		closeIcon: 'close'
	})
	
	const modelValue = defineModel({type: Boolean});
	const innerValue = computed({
		set(value: boolean) {
			modelValue.value = value;
			emit('change', value)
		},
		get():boolean {
			// #ifdef APP-ANDROID
			return (props.visible ?? false) || modelValue.value// ?? false
			// #endif
			// #ifndef APP-ANDROID
			return props.visible || modelValue.value
			// #endif
		}
	} as WritableComputedOptions<boolean>)
	// const hosKey = ref(0)
	const status = ref<TransitionEmitStatus>('before-enter')
	const {inited, display, classes, finished} = useTransition({
		defaultName: props.transitionName ?? 'popup-fade',
		appear: innerValue.value,
		emits: (name:TransitionEmitStatus) => { 
			status.value = name
			if(name == 'before-enter') {
				emit('open')
				
			} else if(name == 'after-enter') {
				emit('opened')
				// setTimeout(()=>{
				// 	if(hosKey.value > 0) return
				// 	hosKey.value++
				// },5)
			} else if(name == 'before-leave') {
				emit('close')
			} else if(name == 'after-leave') {
				emit('closed')
			}
			emit(name) 
		},
		visible: (): boolean => innerValue.value,
		duration: props.duration,
	} as UseTransitionOptions)
	
	const overlayZIndex = computed(():number => props.zIndex > 0 ? props.zIndex - 1: 998);
	
	const rootClass = computed(():string=>{
		const safe = props.safeAreaInsetTop && props.position == 'top' 
			?  'l-popup--safe-top' 
			:  props.safeAreaInsetBottom && props.position == 'bottom' 
				? 'l-popup--safe-bottom'
				: ''
			
		return `l-popup--${props.position} ${safe} ${classes.value}`
	})
	
	const {safeAreaInsets} = uni.getWindowInfo()
	
	const styles = computed<Map<string,any>>(():Map<string,any> => {
		const style = new Map<string,any>();
		// #ifdef UNI-APP-X && APP
		style.set('transition-duration', (['after-leave', 'before-enter'].includes(status.value) ? 0 : props.duration) + 'ms')
		// #endif
		// #ifndef UNI-APP-X && APP
		style.set('transition-duration', props.duration + 'ms')
		// #endif
		if (props.bgColor != null) {
			style.set("background", props.bgColor!)
		}
		if (props.zIndex > 0) {
			style.set("z-index", props.zIndex)
		}
		
		// if(props.safeAreaInsetBottom && props.position == 'bottom') {
		// 	style.set('padding-bottom', safeAreaInsets.bottom + 'px')
		// }
		// if(props.safeAreaInsetTop && props.position == 'top') {
		// 	style.set('padding-top', safeAreaInsets.top + 'px')
		// }
		
		if(props.radius != null) {
			const values = convertRadius(props.radius!)
			style.set('border-top-left-radius', values[0])
			style.set('border-top-right-radius', values[1])
			style.set('border-bottom-right-radius', values[2])
			style.set('border-bottom-left-radius', values[3])
		}
		
		// #ifndef APP
		if (!display.value) {
			// 会导致picker触发pick
			// style.set("display", "none")
			style.set("pointer-events", "none")
		}
		// #endif
		
		return style
	})
	const handleOverlayClick = () => {
		if(props.closeOnClickOverlay) {
			innerValue.value = false;
			emit('click-overlay')
		}
	}
	const handleClose = () => {
		innerValue.value = false;
		emit('click-close')
	}
	
	// #ifdef APP 
	const popupRef = ref<UniElement|null>(null)
	
	watchEffect(()=>{
		// 会导致picker触发pick
		if(!display.value) {
			// popupRef.value?.style.setProperty('display', 'none')
			popupRef.value?.style.setProperty('pointer-events', 'none')
			popupRef.value?.style.setProperty('z-index', -10000)
		} else {
			// popupRef.value?.style.setProperty('display', 'flex')
			popupRef.value?.style.setProperty('pointer-events', 'auto')
			popupRef.value?.style.setProperty('z-index', props.zIndex)
		}
	})
	
	// #endif
</script>
<style lang="scss">
	@import "./index-u";
</style>