<template>
    <div class="element-data-mapping" v-if="currentId!=0">
        <divider />
        <div class="q-mb-md row items-center">
            <div class="text-small col">数据绑定</div>
            <el-checkbox v-model="updateUnionElement" label="更新关联数据" size="small"/>
        </div>
        <Select 
            class="col"
            :value="currentId" 
            @update:value="value => changeDataSourceHandler(value)"
            :options="selectDataSource"
        />
        <div class="row items-center wrap" v-if="handleElement && handleElement.type=='image' && currentImages && currentImages.length>0">
            <div class="item-image-box" v-for="(x,i) in currentImages" :key="i" @click="setImageHandler(x,handleElement,handleElement.dataMapping)">
                <img :src="x" />
                <div class="opera-box" v-if="x == handleElement.src">
                    <el-icon color="#67C23A" size="32"><SuccessFilled /></el-icon>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">
import Divider from '@/components/Divider.vue'
import { VIEWPORT_SIZE, VIEWPORT_VER_SIZE } from '@/configs/canvas';
import useHistorySnapshot from '@/hooks/useHistorySnapshot';
import FileService from '@/services/FileService';
import { useMainStore, useSlidesStore } from '@/store';
import { SlideDataSource, TravelDetail, injectKeyDataSource } from '@/types/injectKey';
import { PPTImageElement } from '@/types/slides';
import { getHtmlPlainText } from '@/utils/common';
import { storeToRefs } from 'pinia';
import { inject, onMounted, ref } from 'vue';
const trip = ref<SlideDataSource>()
const { addHistorySnapshot } = useHistorySnapshot()
trip.value = inject(injectKeyDataSource)
const mainStore = useMainStore()
const slidesStore = useSlidesStore()
const { hotelInfo, scenicInfo, dinnerInfo } = trip.value?.TravelAatas??{}
const resources:Array<TravelDetail[]> = [[],hotelInfo??[],scenicInfo??[],dinnerInfo??[]]
const { handleElement }  = storeToRefs(mainStore)
const slide = slidesStore.currentSlide
const selectDataSource = ref<{label:string,value:string|number}[]>([])
const currentId = ref<number>(0)
const currentImages = ref<string[]>()
const updateUnionElement = ref<boolean>(true)
let maxWidth = VIEWPORT_SIZE,maxHeight = VIEWPORT_VER_SIZE, viewportRatio = slidesStore.viewportRatio
if(viewportRatio<1){
    maxWidth = VIEWPORT_VER_SIZE
    maxHeight = VIEWPORT_SIZE
}

if(handleElement.value?.dataMapping){
    currentId.value = handleElement.value.dataMapping.id
    resources[slide.pageType-1].forEach(x=>{
        selectDataSource.value.push({
            label:x.Name,
            value:x.Id
        })
    })
}

const changeDataSourceHandler = (value:number) => {
    currentId.value = value
    const data = resources[slide.pageType-1].find(x=>x.Id==value)
   
    if(data && handleElement.value && handleElement.value.dataMapping){
        updateUnionElementsHanlder(value)
    }
    loadCurrentImages()
    addHistorySnapshot()
}

const updateUnionElementsHanlder = (newValue:number) => {
    let elements = slide.elements.filter(x=>x.dataMapping && x.below == handleElement.value?.below)
    if(!updateUnionElement.value) elements = elements.filter(x=>x.id==handleElement.value?.id)
    if(elements) {
        const data = resources[slide.pageType-1].find(x=>x.Id==newValue)
        elements.forEach(x => {
            if(x.dataMapping){
                const newDataMapping = {id:newValue, filed:x.dataMapping.filed}
                if(x.type == 'text'){
                    const content = x.content.replace(getHtmlPlainText(x.content),data[x.dataMapping.filed])
                    const props = {content,dataMapping:newDataMapping}
                    slidesStore.updateElement({ id: x.id, props})
                }else if(x.type == 'image'){
                    const urls = data[x.dataMapping.filed] as Array<string> ?? ['']
                    setImageHandler(urls[0],x as PPTImageElement,newDataMapping)
                }
            }
        })
    }
}

const setImageHandler = async (url:string, element:PPTImageElement, mapping:any) => {
    let props = {
        src: url,
        width: element.width,
        height: element.height,
        left: element.left,
        top: element.top,
        dataMapping:mapping
    }
    if(url!='' && url!=handleElement.value?.src){
        try {
            let tempSize = await FileService.getImageSizeWithoutDownloading(url)
            if(tempSize.width>maxWidth){
                let ratio = maxWidth/tempSize.width
                tempSize.width = maxWidth
                tempSize.height = tempSize.height*ratio
            }
            if(tempSize.height>maxHeight){
                let ratio = maxHeight/tempSize.height
                tempSize.height = maxHeight
                tempSize.width = tempSize.width*ratio
            }

            props = {
                src: url,
                width: tempSize.width,
                height: tempSize.height,
                left: element.left,
                top: element.top,
                dataMapping:mapping
            }
            
            if(props.left<0)props.left=0
            if(props.top<0)props.top=0
        } catch (error) {
            
        }
    }
    
    slidesStore.updateElement({ id: element.id, props})
}

const loadCurrentImages = () => {
    if(handleElement.value && handleElement.value.dataMapping){
        currentImages.value = []
        const data = resources[slide.pageType-1].find(x=>x.Id==currentId.value)
        if(data){
            currentImages.value = data[handleElement.value.dataMapping.filed] as Array<string> ?? []
        }
    }
}

loadCurrentImages()
</script>
<style scoped>
.item-image-box{
    width:calc(33% - 5px);
    height:50px; 
    position:relative;
    border-radius: 5px;
    background-color: #333;
    margin-right: 5px;
    margin-top: 5px;
    overflow: hidden;
    cursor: pointer;
}
.item-image-box img{
    object-fit: cover;
    width: 100%;
    height: auto;
}
.item-image-box .opera-box{
    background-color: rgba(0,0,0,.3);
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 3;
    left: 0;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
</style>