<template>
    <div class="semi-box row" :class="{ vertical: isVertical }" v-show="showSemi && visibleInView && showSearchStatus==0"
        :style="semiHorStyle">
        <div class="items items-center" :class="{ column: isVertical, row: !isVertical }" @click="handleShowSearch">
            <img src="../../../assets/img/resource.png" style="width: 20px; height: 20px" />
            <span class="text-small q-ml-sm">系统资料</span>
        </div>
    </div>
    <Vue3DraggableResizable v-model:x="localtion.x" v-model:y="localtion.y" :draggable="true" :resizable="false"
        v-if="showSearchStatus!=0" class="search-card-box" :class="{ vertical: isVertical }">
        <template v-if="userInfo.isp">
            <source-list-isp v-show="showSearchStatus==1" @close="()=>showSearchStatus=0" @change="handleShowDetail"></source-list-isp>
        </template>
        <template v-else>
            <source-list v-show="showSearchStatus==1" @close="()=>showSearchStatus=0" @change="handleShowDetail"></source-list>
        </template>
        <source-detail  v-if="showSearchStatus==2" :item-info="recentPoi" @close="()=>showSearchStatus=0" @refound="()=>showSearchStatus=1"></source-detail>
    </Vue3DraggableResizable>
</template>

<script lang="ts" setup>
import { useMainStore, useUserStore } from "@/store";
import { calculateCardPosition, isElementVisibleInParent } from "@/utils/common";
import { storeToRefs } from "pinia";
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import SourceList from './SourceList.vue'
import SourceListIsp from './SourceListIsp.vue'
import SourceDetail from './SourceDetail.vue'
import Vue3DraggableResizable from "vue3-draggable-resizable";

const mainStore = useMainStore();
const { handleElementId, handleElement, canvasScale } = storeToRefs(mainStore);
const { userInfo } = storeToRefs(useUserStore())
const semiHorStyle = ref<{ left: string; top: string }>({
    left: "",
    top: "",
});
const localtion = ref<{ x: number, y: number }>({
    x: 0,
    y: 0
})
const showSemi = ref(false);
const showSearchStatus = ref(0);
const showDetail = ref(true)
const visibleInView = ref(true);
const recentElement = ref<Element | null>();
const isVertical = ref(false);
const recentPoi = ref<any>()
let resizeObserver: ResizeObserver | null = null;
let mutationObserver: MutationObserver | null = null;

const props = withDefaults(defineProps<{ scrollId: string }>(), {
    scrollId: "",
});

//#region 监听大小变化
const handleObserver = () => {
    handleDisObserver();

    resizeObserver = new ResizeObserver(() => {
        const rect = recentElement.value!.getBoundingClientRect();
        resetPosition(rect);
    });

    resizeObserver.observe(recentElement.value!);
};

const handleDisObserver = () => {
    if (resizeObserver) {
        resizeObserver.disconnect();
        resizeObserver = null;
    }
};

//#endregion

//#region 监听属性变化
const handleMutationObserver = () => {
    handleDisMutationObserver();
    mutationObserver = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (
                mutation.type === "attributes" &&
                mutation.attributeName === "style"
            ) {
                const rect = recentElement.value!.getBoundingClientRect();
                resetPosition(rect);
            }
        });
    });

    mutationObserver.observe(recentElement.value!, {
        attributes: true,
        attributeFilter: ["style"],
    });
};

const handleDisMutationObserver = () => {
    if (mutationObserver) {
        mutationObserver.disconnect();
        mutationObserver = null;
    }
};
//#endregion
const handleShowSearch = () => {
    showSearchStatus.value = 1;
};
const resetPosition = (rect: DOMRect, w: number = 0, h: number = 0) => {
    if (!isVertical.value) {
        w = w == 0 ? rect.width / 2 : rect.width - w + w / 2;
        h = (h == 0 ? rect.height : h) + 10;
    } else {
        w = (w == 0 ? rect.width : w) + 10;
        h = h == 0 ? rect.height / 2 : rect.height - h + h / 2;
    }
    semiHorStyle.value.left = `${rect.left + w}px`;
    semiHorStyle.value.top = `${rect.top + h}px`;
    calculateCardLocation()
    //localtion.value = { x: rect.left + w, y: rect.top + h }
};
const handleChangeSelect = () => {
    showSemi.value = false;
    showSearchStatus.value = 0
    visibleInView.value = false;
    recentElement.value = null;
    handleDisObserver();
    handleDisMutationObserver();
    if (handleElement.value?.type == "text") {
        const targetDom = document.querySelector(
            `#editable-element-${handleElementId.value} .editable-element-text`
        );
        const rect = targetDom?.getBoundingClientRect();
        if (rect) {
            recentElement.value = targetDom;
            resetPosition(rect);
            handleObserver();
            handleMutationObserver();
            showSemi.value = true;
            visibleInView.value = true;
        }
        isVertical.value =
            ("vertical" in handleElement.value && handleElement.value.vertical) ??
            false;
    }
};
const handleChangeParentScale = () => {
    if (showSemi && recentElement.value) {
        const parentElement = document.querySelector(`#${props.scrollId}`);
        const { isVisible, visibleHeight, visibleWidth } = isElementVisibleInParent(
            recentElement.value,
            parentElement!
        );
        visibleInView.value = isVisible;
        const rect = recentElement.value.getBoundingClientRect();
        resetPosition(rect, visibleWidth, visibleHeight);
    }
};
const handListenterScroll = () => {
    if (props.scrollId != "") {
        document
            .querySelector(`#${props.scrollId}`)
            ?.addEventListener("scroll", handleChangeParentScale);
    }
};
const handleRemoveListenerScroll = () => {
    if (props.scrollId != "") {
        document
            .querySelector(`#${props.scrollId}`)
            ?.removeEventListener("scroll", handleChangeParentScale);
    }
};
const calculateCardLocation = ()=>{
    const {top,left} = calculateCardPosition(recentElement.value!,386,471)
    localtion.value.x=left
    localtion.value.y = top
}
const handleShowDetail = (poi:any) => {
    recentPoi.value = poi
    showSearchStatus.value=2
}

watch(handleElementId, (val: any) => {
    handleChangeSelect();
});

watch(canvasScale, (val: number) => {
    handleChangeParentScale();
});

watch(showSemi, (val) => {
    if (!val) showSearchStatus.value = 0;
});
onMounted(() => {
    handListenterScroll();
});
onBeforeUnmount(() => {
    handleRemoveListenerScroll();
});

</script>

<style scoped>
.semi-box {
    position: absolute;
    z-index: 2000;
    left: 0;
    top: 0;
    border: 1px solid rgba(0, 0, 0, 0.04);
    box-shadow: rgba(0, 0, 0, 0.1) 0px 8px 16px 0px;
    border-radius: 16px;
    height: 32px;
    /* width: 248px; */
    background: #fff;
    padding: 2px;
    transform: translateX(-50%);
}

.semi-box.vertical {
    width: 32px;
    height: auto;
    transform: translateY(-50%);
}

.semi-box .items {
    padding: 3px 7px;
    border-radius: 14px;
    height: 100%;
    cursor: pointer;
}

.semi-box.vertical .items {
    padding: 7px 3px;
}

.semi-box .items:hover {
    background: #f1f2f4;
}

.search-card-box {
    width: 386px;
    padding: 16px;
    padding-top: 14px;
    border-radius: 24px;
    border: 1px solid rgba(0, 0, 0, 0.12) !important;
    backdrop-filter: blur(10px);
    background: hsla(0, 0%, 100%, 0.9);
    box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.1);
    /* transform: translateX(-50%); */
    z-index: 2000;
    user-select: none;
    height: auto !important;
}

.search-card-box.vertical {
    /* transform: translateY(-50%); */
}


</style>