<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></slot>
  </view>
</template>

<script setup lang="ts">

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

export interface TouchableFlexProps extends FlexProps {
  /**
   * 是否可以点击
   * @default true
   */
  touchable?: boolean,
  /**
   * 按下时的颜色
   * @default 'background.press'
   */
  pressedColor?: string,
  /**
   * 按下时的透明度（仅在 pressedColor 未设置时有效）
   * @default 0.7
   */
  activeOpacity?: number,
}

const props = withDefaults(defineProps<TouchableFlexProps>(), {
  activeOpacity: 0.7,
  touchable: 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 = {
    ...commonStyle.value,
    ...obj
  } 
  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)

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 (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>