<template>
<div class="page_dialog">
    <!-- v-model="previewVisible" -->
    <el-dialog
        @close="HandleDialogClose"
        class="preview_dialog el_button"
        :model-value="props.previewVisible"
        style="max-height: 90vh;overflow: auto;max-width: 900px;"
        :width="dialogWidth ? dialogWidth : '80%'"
        :title="props.title || '附件预览'"
        append-to-body
        :align-center="true"
    >
        <div class="custom">
            <!-- 内部 class="preview_introduce" -->
            <slot></slot>
        </div>

        <div v-if="filePreviewList.includes(previewType)" class="preview_item">
            <VuePdfEmbed 
                class="preview_main"
                v-if="previewType == 'pdf'"
                annotation-layer 
                :scale="1"
                text-layer 
                :source="fileUrl" 
            />
            <vue-office-excel
                v-else-if="previewType == 'xlsx'"
                :src="fileUrl"
                :options="excelOptions"
                style="height: 100vh;"
                @rendered="renderedHandler"
                @error="errorHandler"
            />
            <vue-office-docx
                class="preview_main"
                v-else-if="previewType == 'docx'"
                :src="fileUrl"
                @rendered="renderedHandler"
                @error="errorHandler"
            />
            <video  class="preview_main"  controls width="100%" v-else-if="['mp4','avi','mpg','mpeg','wmv','mkv','mov','flv','mpg'].includes(previewType)" :src="fileUrl" />         
        
            <!-- <iframe
                v-else-if="['ppt','pptx'].includes(previewType)"
                :src="`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(fileUrl)}`"
                width="100%"
                height="600px"
                frameborder="0"
            ></iframe> -->

            <div   
                v-else-if="['pptx'].includes(previewType)" 
                class="vue_ppt" id="vue_ppt" ref="vuePpt"
            >
                 
                <div  v-if="pptLoading" class="loading_bg">
                    <el-icon class="is-loading">
                        <Loading />
                    </el-icon>
                    加载中
                </div>
                <!-- ppt加载中 -->
            </div>



            <img  @click="HandleImgPreview" style="text-align: center;" v-else-if="['jpg','png','jpeg','gif','svg','webp'].includes(previewType)" :src="fileUrl"/>
        </div>
        <div  class="preview_item" v-else-if="fileName && fileUrl">
            <span>不支持预览，请点击下载: <a  :href="fileUrl">{{ fileName }}</a></span>
        </div>
       
        <template v-if="props.customFooter" #footer>
            <el-button @click="HandleDialogClose" class="button_border_gray cancel" >取 消</el-button>
            <slot name="footer"></slot>
            
            <slot name="confirm">
                <el-button :disabled="props.disabledConfirm" :loading="props.submitLoading"  @click="props.disabledConfirm ? '' : HandleConfirmCheck()" class="button_background"  >确 定</el-button>
            </slot>
        </template>
    </el-dialog>

    <el-image-viewer
        v-if="imgVisible"
        :url-list="[fileUrl]"
        show-progress
        @close="imgVisible = false"
    />
</div>
</template> 

<script setup lang="ts">
import {init} from 'pptx-preview'
import { watch ,ref } from 'vue'
import VuePdfEmbed from 'vue-pdf-embed'
// optional styles
import 'vue-pdf-embed/dist/styles/annotationLayer.css'
import 'vue-pdf-embed/dist/styles/textLayer.css'

//引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'

interface FileMsg {
    name:String,
    url:String
}


const props = defineProps({
    fileMessage:{
        required:true,
        type:Object
    },
    title:{
        type:String
    },
    customFooter:{
        type:Boolean,
        required:false
    },
    previewVisible:{
        type:Boolean,
        required:true
    },
    submitLoading:{
      type:Boolean,
      default:false,
    },
    disabledConfirm:{
        type:Boolean,
        default:false
    },
    dialogWidth:{
        type:String,
    }
})

const emit = defineEmits(['close','confirm'])


const pptxPrviewer = ref()
const vuePpt = ref()
const pptLoading = ref(false)

const fileUrl = ref()
const fileName = ref('')
// const previewVisible = ref(false)
const previewType = ref('')
const imgVisible = ref(false)

const excelOptions = {
    xls: false,       //预览xlsx文件设为false；预览xls文件设为true
    minColLength: 0,  // excel最少渲染多少列，如果想实现xlsx文件内容有几列，就渲染几列，可以将此值设置为0.
    minRowLength: 0,  // excel最少渲染多少行，如果想实现根据xlsx实际函数渲染，可以将此值设置为0.
    widthOffset: 10,  //如果渲染出来的结果感觉单元格宽度不够，可以在默认渲染的列表宽度上再加 Npx宽
    heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
    beforeTransformData: (workbookData) => {return workbookData}, //底层通过exceljs获取excel文件内容，通过该钩子函数，可以对获取的excel文件内容进行修改，比如某个单元格的数据显示不正确，可以在此自行修改每个单元格的value值。
    transformData: (workbookData) => {return workbookData}, //将获取到的excel数据进行处理之后且渲染到页面之前，可通过transformData对即将渲染的数据及样式进行修改，此时每个单元格的text值就是即将渲染到页面上的内容
}

const  renderedHandler = ()=> {
    console.log("渲染完成")
}
const errorHandler = () => {
    console.log("渲染失败")
}

const HandleImgPreview = ()=>{
    imgVisible.value = true
}

const HandleDialogClose = ()=>{
    emit('close')
    console.log('弹窗关闭===')
    // previewVisible.value = false
    fileUrl.value = ''
    fileName.value = ''
    previewType.value = ''
}



const HandleConfirmCheck = async () => {
    emit('confirm')
}



const HandlePptPreview =(url)=>{
  console.log('初始化ppt中')
  if(url && vuePpt.value){
    pptLoading.value = true

    //调用库的init方法生成一个预览器
    pptxPrviewer.value = init(vuePpt.value, {
        // width: (vuePpt.value?.clientWidth * 0.8),
        width: (vuePpt.value?.clientWidth),
        // height: 540
    })
    //获取文件或者读取文件，获取文件的 ArrayBuffer格式数据，传给组件进行预览
    fetch(props?.fileMessage?.url).then(response=>{
        return response.arrayBuffer()
    }).then(res =>{
        console.log('获取文件完成',res)
        // 在这里监听文档的滚动
        let pptDom = document.querySelectorAll('.vue_ppt')
        console.log('dom',pptDom)
        //调用预览器的preview方法
        pptxPrviewer.value.preview(res).then(previewRes=>{
            // 此处数据加载成功
            console.log('转换结果',previewRes)
            pptLoading.value = false
        }).catch(err=>{
            // 解析失败
            pptLoading.value = false
        })
    }).catch(err=>{
        // 获取文件失败
        pptLoading.value = false
    })
  }
}



const filePreviewList = ref(['pptx','pdf','gif','jpeg','jpg','png','svg','webp','xlsx','docx','mp4','avi','mpg','mpeg','wmv','mkv','mov','flv','mpg'])

watch(()=>props.fileMessage,(newVal)=>{
    // previewVisible.value = true
    let suffixName = newVal?.name?.split('.').pop()
    if(suffixName){
        fileName.value = newVal.name
        fileUrl.value = newVal.url
        if(filePreviewList.value.includes(suffixName)){
            previewType.value = suffixName
        }
        /*
        else{
            let link  = document.createElement('a')
            link.setAttribute('href',newVal.url)
            document.body.appendChild(link)
            link.click()
            console.log('link',link)
            document.body.removeChild(link)
        }
        */
    }
})

watch(()=>vuePpt.value,(newVal)=>{
    if(newVal){
        HandlePptPreview(props.fileMessage?.url)
    }
})
</script>


<style lang="scss" scoped>
.preview_item{
    background-color: #f0f4f8;
    border-radius: 8px;
    padding:10px;
    
    overflow: auto;
    display: flex;
    flex-direction: column;

    .preview_main{
        height: 100%;
        overflow: auto;
        border-radius: 8px;
        width: 100% !important;
    }
}

.vue_ppt{
    display: flex;
    position: relative;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    min-height: 270px;
    // min-height: 100%;
    overflow: auto;
    background-color: #e8eaee;

    .loading_bg{
        width: 100%;
        flex: 1 1;
        display: flex;
        justify-content: center;
        align-items: center;
        gap:3px;
        color:#2e64fa;
    }


}

</style>

<style lang="scss">
.preview_dialog{
    overflow: auto;
    border-radius: 8px;
    padding: 0;

    .el-dialog__headerbtn:focus .el-dialog__close, 
    .el-dialog__headerbtn:hover .el-dialog__close {
        color: #999;
    }
    .el-dialog__header {
        width: 100%;
        height: 48px;
        line-height: 48px;
        text-indent: 20px;
        background-color: #f5f7fa;
        border-bottom: 1px solid #f5f7fa;
        border-top-right-radius: 8px;
        border-top-left-radius: 8px;
        padding: 0 !important;
        text-align: left;
        .el-dialog__title {
        font-weight: 600;
        font-size: 16px;
        color: #303133;
        }
        button:focus, button:focus-visible {
        outline: none;
        }
    }
    //饿了么内容样式覆盖
    .el-dialog__body {
        font-weight: 400;
        font-size: 16px;
        color: #333;
        padding: 20px;
        width: 100%;
        margin: auto;

        display: flex;
        flex-direction: column;
        justify-content: flex-start;
        max-height: calc(90vh - 50px - 66px);
        img{
            border-radius: 8px;
            align-self: center;
        }
        .custom{
            .preview_introduce{
                background-color: #fafafa;
                border: solid #e9e9e9 1px !important;
                padding:10px;
                margin-bottom: 10px;
                border-radius: 8px;
                display: flex;
                flex-direction: row;
                justify-content: flex-start;
                align-items: flex-start;
            }
        }
    }

    .el-dialog__footer{
        padding:15px 20px;
        border-top:solid #EBEEF5 1px;
    }
}

.preview_main{

    .docx-wrapper{
        // width: 100% !important;
        background-color: #f0f4f8 !important;
        overflow: auto;
        box-sizing: border-box;
        padding-top: 20px;
        padding-bottom: 20px;
        .docx{
            width: 100% !important;
            overflow: auto;
        }
    }
    .vue-pdf-embed__page{
        width: 100% !important;
        overflow: auto;
        padding:20px;

        background-color: #f0f4f8 !important;
        canvas{
            width: 100% !important;
            background-color: #f0f4f8 !important;
        }
        .textLayer{
            width: 100% !important;
            height: 100%  !important;
        }

        .annotationLayer{
            width: 100% !important;
            height: 100% !important;
        }
    }
}
</style>