<template>
  <view
    :id="innerId ?? id"
    :class="[
      'nana-flex-layout',
      innerClass,
    ]"
    :style="finalStyle"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
    @mousedown="handleTouchStart"
    @mouseup="handleTouchEnd"
    @touchstart="handleTouchStart"
    @touchend="handleTouchEnd"
    @click.native.stop="handleClick"
  >
    <slot />
  </view>
</template>

<script setup lang="ts">

/**
 * 组件说明：Flex组件，用于一些布局中快速写容器，是一系列盒子的基础组件。
 */
import { computed, getCurrentInstance, inject, onMounted, ref, type Ref } from 'vue';
import { useTheme } from '../theme/ThemeDefine';
import { RandomUtils } from '@imengyu/imengyu-utils';
import { useBaseViewStyleBuilder } from '../layout/BaseView';
import { TouchableClickEventInceptorKey, type TouchableFlexProps } from './Touchable';

const props = withDefaults(defineProps<TouchableFlexProps>(), {
  activeOpacity: 0.7,
  touchable: true,
  setCursor: true,
});

const themeContext = useTheme();
const { commonStyle } = useBaseViewStyleBuilder(props);

const finalStyle = computed(() => {
  const obj : Record<string, any> = {};
  if (props.pressedColor != undefined) { 
    if (isPressed.value)
      obj.backgroundColor = themeContext.resolveThemeColor(props.pressedColor);
  } else if (props.activeOpacity != undefined) 
    obj.opacity = isPressed.value ? props.activeOpacity : 1;
  const o : Record<string, any> = {
    ...commonStyle.value,
    ...obj,
    cursor: props.setCursor ? (props.touchable ? 'pointer' : 'not-allowed') : 'default',
  } 
  for (const key in o) {
    if (o[key] === undefined)
      delete o[key]; 
  }
  return o;
})

defineOptions({
  options: {
    styleIsolation: "shared",
    virtualHost: true
  }
})
const emit = defineEmits([ "click", "state" ]);
const isPressed = ref(false);
const clickEventInceptor = inject<(Ref<() => void>)|null>(TouchableClickEventInceptorKey, null);

function handleTouchStart() {
  if (props.touchable) {
    isPressed.value = true; // 按下时改变状态
    emit('state', 'active');
  }
}
function handleMouseEnter() {
  if (props.touchable)
    emit('state', 'active')
}
function handleMouseLeave() {
  if (props.touchable)
    emit('state', 'default')
}
function handleClick(e: Event) {
  if (clickEventInceptor && clickEventInceptor.value) {
    clickEventInceptor.value();
    return;
  }
  if (props.touchable) {
    emit('state', 'default')
    emit('click', e);
  }
}
function handleTouchEnd() {
  if (props.touchable) {
    isPressed.value = false; // 释放时恢复状态
    emit('state', 'default');
  }
}

onMounted(() => {
  emit('state', 'default')
})
    
const instance = getCurrentInstance();
const id = 'flex-item-' + RandomUtils.genNonDuplicateID(15);

defineExpose({
  measure() {
    return new Promise((resolve) => {
      const tabItem = uni.createSelectorQuery()
        .in(instance)
        .select(`#${id}`);
      tabItem.boundingClientRect().exec((res) => {
        resolve(res)
      })
    });
  },
})
</script>