<template>
  <view class=" h-full">
    <view :id="`dropdown-trigger-${config.prop}`" class="w-full flex items-center justify-center gap-10 h-full relative"
      @click="handleClick">
      <view class="relative">
        <view class="text-xs text-center ellipsis-1" :class="[show ? 'text-primary' : 'text-fore-title ']">
          {{ config.label }}
        </view>
        <view class="absolute -top-4 -right-4 w-6 h-6 bg-red-500 rounded-full" v-if="hasValue"></view>
      </view>
      <view :class="['transition-transform duration-300 ease-out', { 'rotate-180': show }]">
        <uv-icon name="arrow-down" :color="show ? 'primary' : 'info'" size="14" />
      </view>
    </view>
    <view v-show="isOpen" class="fixed left-0 right-0 z-[9999]" :style="containerStyle">
      <view class="fixed z-0 overflow-hidden" :id="`dropdown-content-${config.prop}`" :style="maskStyle"
        @click="handleMaskClick">
      </view>
      <view class="relative z-1 overflow-hidden ">
        <view class="left-0 right-0 z-1 w-full bg-white box-border transition-transform duration-300 ease-out"
          :style="contentStyle" @click="">
          <scroll-view class="relative max-h-[300px]" scroll-y>
            <uv-checkbox-group v-model="checkboxValue" placement="column" iconPlacement="right" borderBottom>
              <uv-checkbox :customStyle="{ marginBottom: '0', paddingBottom: '0', height: '38px', padding: '0 10px' }"
                v-for="(item, index) in config.options" :key="index" :label="item.label"
                :name="item.value"></uv-checkbox>
            </uv-checkbox-group>
          </scroll-view>
          <view class="flex items-center justify-between gap-24 p-[12px]">
            <view class="flex-1">
              <uv-button type="primary" plain shape="circle" @click="handleReset">重置</uv-button>
            </view>
            <view class="flex-1">
              <uv-button type="primary" shape="circle" @click="handleSubmit">
                <text>确定</text>
                <text v-if="checkboxValue.length > 0">({{ checkboxValue.length }})</text>
              </uv-button>
            </view>
          </view>
        </view>
      </view>
    </view>

  </view>
</template>
<script lang="ts" setup>
import { type Dropdown } from '@/types';
import { DROPDOWN_SYMBOL } from './ie-dropdown-hooks';
import { getCurrentInstance } from 'vue';

const instance = getCurrentInstance();

const props = defineProps<{
  config: Dropdown.DropdownItem;
  index: number;
  // 是否使用绝对定位
  absolute?: boolean;
}>();
const dropdown = inject(DROPDOWN_SYMBOL);
const triggerSelector = `#dropdown-trigger-${props.config.prop}`;
const isOpen = ref(false);
const show = ref(false);
const isMeasuringHeight = ref(false);
const top = ref(0);
const hasValue = computed(() => {
  return dropdown?.form.value[props.config.prop] && dropdown?.form.value[props.config.prop].length > 0;
});

const checkboxValue = ref([]);
const containerStyle = computed(() => {
  return {
    top: `${top.value + 1}px`,
  }
});
const maskStyle = computed(() => {
  return {
    top: `${top.value + 1}px`,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'rgba(0, 0, 0, 0.3)',
    opacity: show.value ? 1 : 0,
    transition: 'opacity 0.3s ease-out',
  }
});
const contentStyle = computed(() => {
  return {
    transform: `translateY(${show.value ? '0' : '-100%'})`,
  }
});

watch(() => dropdown?.openIndex.value, (newVal) => {
  if (newVal === props.index) {
    open();
  } else {
    if (isOpen.value) {
      close();
    }
  }
});

const handleReset = () => {
  checkboxValue.value = [];
}
const handleSubmit = () => {
  dropdown?.submit(props.index, checkboxValue.value);
  dropdown?.close();
}

const open = async () => {
  checkboxValue.value = dropdown?.form.value[props.config.prop] || [];
  isOpen.value = true;
  const triggerRect = await getRect(triggerSelector);
  if (props.absolute) {
    top.value = triggerRect.height;
  } else {
    top.value = triggerRect.top + triggerRect.height;
  }
  setTimeout(() => {
    nextTick(() => {
      show.value = true;
    });
  }, 20);
}

const close = () => {
  show.value = false;
  setTimeout(() => {
    isOpen.value = false;
  }, 300);
}

const getRect = (selector: string) => {
  return new Promise((resolve: (rect: { top: number, height: number }) => void) => {
    const query = uni.createSelectorQuery().in(instance?.proxy);
    query.select(selector).boundingClientRect(function (rect) {
      resolve(rect as { top: number, height: number });
    }).exec();
  });
}

const measureHeight = (selector: string) => {
  return new Promise((resolve: (height: number) => void) => {
    isMeasuringHeight.value = true;
    setTimeout(() => {
      nextTick(() => {
        getRect(selector).then((res: any) => {
          isMeasuringHeight.value = false;
          setTimeout(() => {
            nextTick(() => {
              resolve(res?.height ?? 0);
            });
          }, 50);
        });
      });
    }, 50);
  });
}

const handleMaskClick = () => {
  if (isOpen.value) {
    dropdown?.close();
  }
}

const handleClick = () => {
  if (isOpen.value) {
    dropdown?.close();
  } else {
    dropdown?.open(props.index);
  }
}
</script>
<style lang="scss" scoped></style>