<template>
  <view 
    :id="id"
    :class="[
      'nana-dropdown-menu-item', 
      extra || isExtra ? 'extra' : 'normal',
      disabled ? 'disabled' : '',
      activeState ? 'active' : '',
      openState ? 'open' : '',
    ]"
    :hover-class="openState ? '' : 'pressed'"
    :style="{
      backgroundColor: topContext.backgroundColor.value,
      ...((extra || isExtra) ? itemExtraStyle : itemStyle),
      ...((extra || isExtra) ? topContext.itemExtraStyle.value : topContext.itemStyle.value),
      ...((extra || isExtra) && activeState ? itemExtraActiveStyle : {}),
      ...((extra || isExtra) && openState ? itemExtraOpenStyle : {}),
    }"
    @click="handleClick"
  >
    <view class="inner">
      <slot name="icon">
        <Icon 
          v-if="icon"
          :icon="icon" 
          :size="iconSize"
          :color="textStyle.color"
          :innerStyle="textStyle"
        />
      </slot>
      <slot name="title">
        <text :style="textStyle">{{ titleText }}</text> 
      </slot>  
      <slot name="arrow">
        <Icon 
          v-if="canOpen"
          :innerStyle="{
            transform: topContext.direction.value === 'up' ? 
              (openState ? 'rotate(1deg)' : 'rotate(180deg)') : 
              (openState ? 'rotate(180deg)' : 'rotate(-1deg)'),
            ...textStyle,
          }"
          :size="iconSize"
          :color="textStyle.color"
          icon="arrow-down-bold" 
        />
      </slot>  
    </view>
    <Popup 
      v-model:show="openState"
      :position="topContext.direction.value === 'up' ? 'bottom' : 'top'"
      :closeIcon="false"
      :closeable="true"
      :safeArea="false"
      :inset="popupMargin"
      :duration="topContext.duration.value"
      size="auto"
    >
      <slot>
        <SimpleList
          v-if="type?.endsWith('check')"
          :data="options ?? []"
          :checkedItems="checkedItems"
          :mode="(type as any) "
          dataKey="value"
          dataDisplayProp="text"
          @selectedItemChanged="handleSelectedItemChanged"
        />
        <FlexCol
          v-if="type === 'mulit-check'" :padding="10">
          <Button type="primary" shape="round" @click="close()">确定</Button>
        </FlexCol>
      </slot>
    </Popup>
  </view>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, inject, ref, useSlots, type Ref } from 'vue';
import Icon from '../basic/Icon.vue';
import Popup from '../dialog/Popup.vue';
import { useTheme } from '../theme/ThemeDefine';
import type { DropdownMenuContext } from './DropdownMenu.vue';
import { DynamicColor, DynamicSize, DynamicSize2, DynamicVar } from '../theme/ThemeTools';
import { RandomUtils } from '@imengyu/imengyu-utils';
import SimpleList from '../list/SimpleList.vue';
import FlexCol from '../layout/FlexCol.vue';
import Button from '../basic/Button.vue';

export interface DropdownMenuItem {
  /**
   * 文字
   */
  text: string,
  /**
   * 标识符
   */
  value: number | string,
  /**
   * 左侧图标名称或图片链接，等同于 Icon 组件的 icon 属性
   */
  icon?: string,
}
export interface DropdownMenuItemProps {
  modelValue?: string|number|boolean|undefined|(string|number)[],
  /**
   * 条目标题文字
   */
  title?: string;
  /**
   * 条目左侧图标名称或图片链接，等同于 Icon 组件的 icon 属性
   */
  icon?: string;
  /**
   * 是否禁用
   * @default false
   */
  disabled?: boolean;
  /**
   * 选项。如果为空，且传入boolean则为开关，否则点击条目，其他属性为下拉菜单
   */
  options?: DropdownMenuItem[];
  /**
   * 类型
   * @default 'single-check'
   */
  type?: 'button' | 'toggle' | "single-check" | "mulit-check";
  /**
   * 设置条目激活状态的方式
   * - default: 默认使用 modelValue 计算状态，不为空数组或者不为第一条数据则激活
   * - none: 没有激活状态
   * - true/false：手动设置激活状态
   * @default 'default'
   */
  activated?: boolean|'default'|'none';

  extra?: boolean;
}

const id = `dropItem${RandomUtils.genNonDuplicateID(20)}`;
const theme = useTheme();

const props = withDefaults(defineProps<DropdownMenuItemProps>(), {
  activated: 'default',
  type: 'single-check',
});
const emit = defineEmits(['update:modelValue', 'click']);
const slots = useSlots();

const instance = getCurrentInstance()!;
const isExtra = inject<Ref<boolean>>('dropdownMenuisExtra', ref(false));
const topContext = inject<DropdownMenuContext>('DropdownMenuContext')!;

const openState = ref(false);
const activeState = computed(() => {
  if (props.activated === 'none')
    return false;
  if (openState.value)
    return true;
  if (props.type === 'toggle')
    return props.modelValue;
  if (props.activated === 'default') {
    if (props.type === 'mulit-check' && props.modelValue instanceof Array && props.modelValue.length)
      return true;
    if (props.type === 'single-check' && props.modelValue && (props.options?.length && props.modelValue !== props.options[0].value))
      return true;
  } else if (typeof props.activated === 'boolean')
    return props.activated;
  return false;
});
const checkedItems = computed(() => {
  if (props.options ) {
    if (typeof props.modelValue === 'string' || typeof props.modelValue === 'number')
      return [ props.options.find((item) => item.value === props.modelValue) ];
    if (props.modelValue && Array.isArray(props.modelValue))
      return props.options.filter((item) => (props.modelValue as any[])!.includes(item.value));
  }
  return [];
});
const titleText = computed(() => {
  if (props.title)
    return props.title;
  if (props.options 
    && (typeof props.modelValue === 'string' || typeof props.modelValue === 'number')) {
    return props.options.find((item) => item.value === props.modelValue)?.text ?? '';
  }
  return '';
});
const canOpen = computed(() => {
  return props.type?.endsWith('check') || slots.default;
});


const textStyle = computed(() => {
  return {
    color: props.disabled ? theme.resolveThemeColor('text.second') : 
      (activeState.value ? theme.resolveThemeColor(topContext.activeColor.value) : theme.resolveThemeColor('text')),
    margin: theme.resolveThemeSize('DropdownMenuItemTextMargin', 6),
  }
});
const iconSize = computed(() => {
  return theme.resolveThemeSize('DropdownMenuItemIconSize', 25);
});
const itemStyle = theme.useThemeStyle({
  padding: DynamicSize2('DropdownMenuItemVerticalPadding', 'DropdownMenuItemHorizontalPadding', 20, 0)
});
const itemExtraStyle = theme.useThemeStyle({
  borderStyle: DynamicVar('DropdownMenuItemExtraBorderStyle', 'solid'),
  borderWidth: DynamicSize('DropdownMenuItemExtraBorderWidth', 2),
  borderColor: DynamicVar('DropdownMenuItemExtraBorderColor', 'transparent'),
  borderRadius: DynamicSize('DropdownMenuItemExtraRadius', 40),
  marginRight: DynamicSize('DropdownMenuItemExtraMarginRight', 10),
  padding: DynamicSize2('DropdownMenuItemExtraVerticalPadding', 'DropdownMenuItemExtraHorizontalPadding', 2, 10),
});
const itemExtraActiveStyle = theme.useThemeStyle({
  borderColor: DynamicColor('DropdownMenuItemExtraBorderColor', topContext.activeColor.value),
});
const itemExtraOpenStyle = theme.useThemeStyle({
  borderBottomLeftRadius: 0,
  borderBottomRightRadius: 0,
  border: 'none',
});

const popupMargin = ref<(undefined|string)[]>([ undefined,undefined,undefined,undefined ]);

async function updateDialogMargin() {
  popupMargin.value[0] = undefined;
  popupMargin.value[2] = undefined;

  const d = await new Promise<UniApp.NodeInfo>((resolve, reject) => {
    uni.createSelectorQuery()
      .in(instance)
      .select(`#${id}`)
      .fields({
        id: true,
        rect: true,
        size: true
      }, (data) => {
        const d = data as UniApp.NodeInfo;
        if (d) {
          resolve(d);
        } else {
          reject(new Error('获取元素位置失败'));
        }
      })
      .exec();
  });
  const systemInfo = uni.getWindowInfo();
  const pages = getCurrentPages();
  let v = 0
  if (topContext.direction.value === 'up') {
    if (topContext.includeNavBarSpace.value) {
      v += 44;
      v += systemInfo.statusBarHeight || 0;
    }

    v += d.top ?? 0;
    v = systemInfo.screenHeight - v;
    popupMargin.value[2] = `${v}px`;
  } else {
    if (topContext.includeNavBarSpace.value) {
      //H5 浏览器需要额外添加44px
      // #ifdef H5
      v += 44;
      // #endif
    }
    v += (d.height ?? 0);
    v += d.top ?? 0;
    popupMargin.value[0] = `${v}px`;
  }
}
function handleClick() {
  if (props.disabled)
    return;
  if (props.type === 'button') {
    emit('click');
    return;
  }
  if (props.type === 'toggle') {
    emit('update:modelValue', !activeState.value);
    return;
  }
  toggle();
}
function handleSelectedItemChanged(item: DropdownMenuItem[]) {
  if (props.type === 'single-check') {
    emit('update:modelValue', item[0].value);
    setTimeout(close, 200);
  }
  else if (props.type === 'mulit-check') {
    const values = item.map((i) => i.value);
    console.log(values);
    
    emit('update:modelValue', values);
  }
}

function toggle() {
  if (openState.value) {
    close();
  } else {
    open();
  }
}
function close() {
  openState.value = false;
}
function open() {
  if (!openState.value) {
    updateDialogMargin().then(() => {
      topContext.setCurrentOpen(() => {
        openState.value = false;
      });
      openState.value = true;
    });
  }
}

defineExpose({
  close,
  open,
  toggle,
})
defineOptions({
  options: {
    inheritAttrs: false,
    virtualHost: true,
  }
})
</script>

<style lang="scss">


.nana-dropdown-menu-item {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;

  &.normal {
    flex: 1;
  }

  &.pressed {
    opacity: 0.7;
  }

  .inner {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
  }
}
</style>