<template>
    <el-dialog v-loading="sliderLoading" v-model="visibleStatus" :show-close="false" :close-on-press-escape="false" :close-on-click-modal="false" style="max-width:650px;">
        <template #header>
            <div class="text-title">导入PSD设计文件</div>
        </template>
        <div v-if="!thumbnails || thumbnails.length==0 || isResolving">
            <el-upload
                v-loading="isResolving"
                ref="upload"
                class="upload-drop-box"
                :on-change="handleChange"
                action=""
                drag
                :limit="1"
                :on-exceed="handleExceed"
                :auto-upload="false"
                accept=".psd,image/vnd.adobe.photoshop"
                :show-file-list="false"
            >
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">
                拖动文件到这里释放或<em>点击上传</em>
                </div>
                <template #tip>
                <div class="el-upload__tip">
                    当前仅支持PSD文件上传解析
                </div>
                </template>
            </el-upload>
            <div class="text-right q-mt-lg">
                <el-button @click="close" :disabled="isResolving">取消导入</el-button>
            </div>
        </div>
        
        <div v-else>
            <div class="text-small text-grey" ref="tiggerRef">已成功解析PSD文件，请核对下方图片是否正确：</div>
            <div class="row" style="flex-wrap:wrap">
                <img v-for="(x,i) in thumbnails" :key="i" style="height:auto;width:calc(25% - 10px);" class="q-mr-md rounded q-mt-md" :src="x" />
            </div>
            <div class="text-small text-grey q-mt-lg" v-if="fonts && fonts.length>0">请完善以下字体信息补充：</div>
            <div class="row items-center q-mt-md" v-for="(x,i) in fonts" :key="x.fontFamily">
                <div class="text-small col" style="user-select: text !important;">字体名称：{{ x.fontFamily }}</div>
                <el-popover :width="150" trigger="click">
                    <template #reference>
                        <el-button v-if="uploadFinishFont?.indexOf(x.fontFamily)==-1 && uploadingIndex!=i" class="q-mr-md" link>{{ !x.uploadType?'选择方式':(x.uploadType==1?'上传本地文件':'选择已有字体') }}</el-button>
                    </template>
                    <el-menu mode="vertical">
                        <el-menu-item index="1" @click="x.uploadType=1,x.selectedFont='',tiggerRef.click()">上传本地文件</el-menu-item>
                        <el-menu-item index="2" @click="x.uploadType=2,x.selectedFont='',tiggerRef.click()">选择已有字体</el-menu-item>
                    </el-menu>
                </el-popover>
                <el-select v-model="x.selectedFont" placeholder="请选择字体" size="mini" style="width: 150px;" filterable v-if="x.uploadType==2">
                    <el-option
                        v-for="item in formatFonts"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                        :style="{'font-family':item.reduce!=''?item.reduce:item.label}"
                    />
                </el-select>
                <el-upload
                    v-loading="uploadingIndex==i"
                    :on-change="(uploadFile:any, uploadFiles:any)=> uploadFontHandler(uploadFile, uploadFiles,x.fontFamily)"
                    action=""
                    :limit="1"
                    v-if='uploadFinishFont?.indexOf(x.fontFamily)==-1 && x.uploadType==1'
                    :auto-upload="false"
                    accept=".ttf, .woff, otf"
                    :show-file-list="false"
                >
                    <template #trigger>
                        <el-button style="color:#0b40fe" link>选择字体</el-button>
                    </template>
                </el-upload>
                <el-tag v-if="uploadFinishFont?.indexOf(x.fontFamily)!=-1" type="success" effect="light"> 已上传 </el-tag>
                <el-button  v-if='uploadFinishFont?.indexOf(x.fontFamily)==-1' type="danger" class="q-ml-md" @click="removeFontHandler(x.fontFamily)" :icon="Delete" link></el-button>
            </div>
            <div class="q-mt-lg row items-center">
                <div class="col">
                    <el-button @click="resetPsdHandler">重新选择</el-button>
                </div>
                <div>
                    <el-button @click="close">取消导入</el-button>
                    <el-button type="primary" class="q-ml-lg" @click="resolveToSliderHandler">确认导入</el-button>
                </div>
            </div>
           
           
        </div>
    </el-dialog>
</template>
<script setup lang="ts">
import {ref,defineProps,watch,inject} from 'vue'
import { UploadFilled,Delete } from '@element-plus/icons-vue'
import type { UploadProps, UploadUserFile,UploadInstance } from 'element-plus'
import PSD from 'psd.js'
import {getFonts, toSlider,getDrawingBoardSize, toThumbnails} from '@/utils/psdParser/index'
import { useSlidesStore } from '@/store'
import { ElMessage, ElMessageBox } from 'element-plus'
import AliyunUpload from '@/utils/upload/aliyun'
import { useFontStore,useScreenStore } from '@/store'
import { CustomerFonts } from '@/store/font'
import { injectKeyDataSource,injectKeyTemplate } from '@/types/injectKey'
import { VIEWPORT_SIZE, VIEWPORT_VER_SIZE } from '@/configs/canvas'
import { reduceFont } from '@/utils/fonts/convertFont'
import FileService from '@/services/FileService'
import { storeToRefs } from 'pinia'

const props = defineProps({
    visible:{
        type:Boolean,
        required:true,
        default:true
    }
})
const emit = defineEmits<{
  (event: 'update:visible', payload: boolean): void
  (event: 'closed'): void
}>()

const visibleStatus = ref(props.visible)
const upload = ref<UploadInstance>()
const isResolving = ref(false)
const sliderLoading = ref(false)
const thumbnails = ref<Array<any>>([])
const sliders = ref<Array<any>>([])
const fonts = ref<{fontFamily:string,uploadType:number,selectedFont?:string}[]>()
const uploadingIndex = ref(-1)
const uploadFinishFont = ref<string[]>([])
const { formatFonts } = storeToRefs(useFontStore())
const queryObj = ref({} as any)
const searchData = ref({} as any)
const tiggerRef = ref()
queryObj.value = inject(injectKeyDataSource).queryObj
searchData.value = inject(injectKeyTemplate)


const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
    isResolving.value=true
    if(uploadFile){
        var url = URL.createObjectURL(uploadFile?.raw)
        try {
            PSD.fromURL(url).then(async (psd:any) => {
                thumbnails.value= await toThumbnails(psd)
                sliders.value = await toSlider(psd)
                let DrawingBoardSize = await getDrawingBoardSize(psd)
                queryObj.value.TempType = DrawingBoardSize.Width>DrawingBoardSize.Height?1:2
                if(searchData.value.TemplateType==2) {
                    queryObj.value.Width = DrawingBoardSize.Width
                    queryObj.value.Height = DrawingBoardSize.Height
                    VIEWPORT_SIZE.Value = queryObj.value.Height
                    VIEWPORT_VER_SIZE.Value = queryObj.value.Width
                    let viewportRatio = queryObj.value.Height/queryObj.value.Width
                    useSlidesStore().setViewportRatio(viewportRatio)
                }else {
                    VIEWPORT_SIZE.Value = 1754
                    VIEWPORT_VER_SIZE.Value = 1240
                    let viewportRatio = 1.414
                    if(queryObj.value.TempType==1) viewportRatio = 0.7069
                    useSlidesStore().setViewportRatio(viewportRatio)
                }
                fonts.value = getFonts(psd)
                if(fonts.value){
                    fonts.value = fonts.value.filter(x=>useFontStore().getFonts.findIndex(y=>y.fontFamily==x.fontFamily)==-1)
                }
                //currentPSD.value = psd
                isResolving.value=false
            })
        } catch (error) {
            isResolving.value=false
        }
    }else{
        isResolving.value=false
    }
}

const uploadFontHandler = async (uploadFile:any, uploadFiles:any, fontName:string) => {
    const ns = uploadFile.name.toLowerCase().split('.')
    const n = ns[ns.length-1]
    const acceptFile = ['ttf','otf','woff']
    if(acceptFile.indexOf(n)==-1){
        ElMessage.error({
            message:`不支持此类文件上传，目前只支持${acceptFile.join(',')}等文件上传`
        })
        return;
    }
    uploadingIndex.value = fonts.value?.findIndex(x=>x.fontFamily==fontName)??-1
    try {
        let info:any = null
        try {
            info = await reduceFont(uploadFile?.raw)
        } catch (error) {
            ElMessage.error({message:'字体无法识别，请更换'})
            uploadingIndex.value=-1
            return
        }

        const flagIndex = formatFonts.value.findIndex(x=>x.label==info.name)
        if(flagIndex>0){
            ElMessage.error({message:`${info.name} 字体已存在，请选择使用已有字体`})
            uploadingIndex.value=-1
            return
        }
        let url = await FileService.uploadToFontServerAsync(uploadFile?.raw)
        if(url && url!=''){
            if(url.indexOf('"')!=-1) url = url.replaceAll('"','')
            let label=uploadFile.name.split('.')[0],reduceName='',reduceUrl=''
            try {
                if(info.file){
                    label = info.name
                    reduceName = `${fontName}_reduce`
                    reduceUrl = await AliyunUpload.UploadAsync(info.file,"tripfont/"+info.file.name)
                }
            } catch (error) { 
            }
            //添加字体
            //uploadFinishFont.value.push(fontName)
            let data:CustomerFonts = {
                fontFamily:fontName,
                label,
                fontUrl:url,
                reduceName,
                reduceUrl
            }
            const result = await useFontStore().uploadFontAsync(data)
            if(result){
                uploadFinishFont.value.push(fontName)
            }else{
                ElMessage({
                    message:'字体上传失败,请重试',
                    type:'error'
                })
            }
        }else{
            ElMessage({
                message:'上传失败，请重试',
                type:'error'
            })
        }
    } catch (error) {
    }
    uploadingIndex.value=-1
}
const removeFontHandler = (fontName:any)=>{
    ElMessageBox.confirm('删除后无法恢复，是否确定执行','提示',{
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(() => {
        if(fonts.value){
            fonts.value?.splice(fonts.value.findIndex(x=>x.fontFamily==fontName),1)
        }
    })
    .catch((error) => { })
}
const handleExceed: UploadProps['onExceed'] = (files) => {
    upload.value!.clearFiles()
    const file = files[0] as UploadRawFile
    upload.value!.handleStart(file)
}
const resolveToSliderHandler = async()=>{
    const replaceFontCount = fonts.value?.filter(x=>x.selectedFont&&x.selectedFont!='')?.length??0
    if((uploadFinishFont.value?.length+replaceFontCount) < (fonts.value?.length??0)){
        ElMessage({
            message:'请完善字体信息',
            type:'error'
        })
    }else{
        replaceFontFamily()
        await useFontStore().loadAllFonts()
        const slidesStore = useSlidesStore()
        const screenSotre = useScreenStore()
        slidesStore.setSlides(sliders.value)
        slidesStore.setLayouts(sliders.value)
        slidesStore.setThumbnails(thumbnails.value)
        slidesStore.updateSlideIndex(0)
        screenSotre.isCoverImg = false
        screenSotre.CoverImg = thumbnails.value[0]
        close()
    }
}
const replaceFontFamily = () => {
    fonts.value?.forEach(item=>{
        sliders.value.forEach(x => {
            x.elements.forEach((y:any)=>{
                if(y.defaultFontName && y.defaultFontName.indexOf(item.fontFamily)!=-1){
                    let dn = y.defaultFontName.split(',')
                    let dni = dn.findIndex((z:string)=>z==item.fontFamily)
                    dn[dni] = item.selectedFont
                    y.defaultFontName=dn.join(',')
                }
            })
        });
    })
    
}
const resetPsdHandler = ()=>{
    thumbnails.value=[]
}
const close = () => {
  visibleStatus.value=false
  resetPsdHandler()
  emit('update:visible', false)
  emit('closed')
}
watch(() => props.visible, () => {
    visibleStatus.value = props.visible
})

</script>