<template>
    <div class="upload-file-box">
        <Upload type="drag" action="" multiple :before-upload="beforeUpload" class="upload-wrap">
            <Icon class="upload-icon" custom="iconfont icon-upload" />
            <p class="upload-text">{{$t('teachContent.uploadText')}}</p>
        </Upload>
        <div class="upload-file-box">
            <div class="upload-file-item" v-for="(item,index) in uploadedList" :key="index">
                <!--<v-icon class="upload-loading-icon" v-if="item.status == 0" iconClass="loading3" />
                <Icon type="md-checkmark" color="aqua" size="20" v-else-if="item.status == 1 || item.status == undefined" />
                <Icon type="md-close" color="red" size="20" v-else-if="item.status == 2" />-->
                <p class="upload-file-name">{{item.fileName}}</p>
                <Icon type="ios-close" class="delete-btn" size="20" style="float:right;" @click="deleteFile(index)" />
                <span style="float:right;margin-left:10px;vertical-align:middle;color:white;">{{parseInt(item.loadedBytes * 100 / item.size)+'%'}}</span>
                <span style="float:right;font-size:12px;vertical-align:middle;margin-top:2px;">{{getSizeByBytes(item.loadedBytes)+'/'+getSizeByBytes(item.size)}}</span>
                <Progress v-if="item.status == 0" :percent="item.loadedBytes * 100 / item.size" status="active" stroke-color="#1CC0F3" :stroke-width="2" hide-info/>
            </div>
        </div>
    </div>
</template>
<script>
    import '@/icons/svg/loading3.svg'
    import sha1 from 'js-sha1'
    const { BlobServiceClient } = require("@azure/storage-blob")//v12
    export default {
        data() {
            return {
                containerURL: undefined,
                uploadedList: [],
                contentTypes: [
                    ['JPG', 'JPEG', 'PNG', 'GIF'],
                    ['AVI', 'MP4'],
                    ['PPT', 'PPTX', 'DOC', 'DOCX', 'PDF', 'XLS', 'XLSX', 'CSV'],
                    ['HTE', 'HETX']
                ],

            }
        },
        props: {
            //默认文件列表
            defaultFileList: {
                default: () => {
                    return []
                },
                type: Array
            },
            //文件夹
            folder: {
                default: 'res',
                type: String
            },
            //授权信息
            sasString:{
                default: 'res',
                type: String
            },
            //blob链接
            urlString:{
                default: '',
                type: String
            },
            //容器名称
            containerName:{
                default: '',
                type: String
            },
            //缩略图压缩质量
            quality: {
                default: 0.2,
                type: Number
            },
            //文件大小限制
            maxSize: {
                default: 2 * 1024 * 1024 * 1024,
                type: Number
            },
            //文件格式限制
            format: {
                default: () => {
                    return []
                },
                type: Array
            }
        },
        methods: {
            getSizeByBytes(bytes) {
                return bytes / 1024 < 1024 ? (bytes / 1024).toFixed(1) + 'KB' : bytes / 1024 / 1024 < 1024 ? (bytes / 1024 / 1024).toFixed(1) + 'M' : (bytes / 1024 / 1024 / 1024).toFixed(1) + 'G'
            },
            /**
             * 清空列表
             * */
            clearUploadedList() {
                this.uploadedList.length = 0
            },
            /**
             * 删除文件
             * */
            deleteFile(index) {
                this.$emit('deleteFile', this.uploadedList[index])
                this.uploadedList.splice(index, 1)
            },
            //初始化blob
            initBlob() {
                let blobServiceClient = new BlobServiceClient(this.urlString + this.sasString)
                this.containerURL = blobServiceClient.getContainerClient(this.containerName)
            },
            dataURLtoFile(dataurl, filename) {
                var arr = dataurl.split(','); var mime = arr[0].match(/:(.*?);/)[1]
                var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n)
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n)
                }
                return new File([u8arr], filename, { type: mime })
            },
            //处理图片缩略图和视频封面
            compressFile(file, fileInfo) {
                if (fileInfo.type == 'picture') {
                    let reader = new FileReader()
                    reader.readAsDataURL(file)
                    reader.onload = (e) => {
                        let dataUrl = e.target.result
                        let img = new Image()
                        img.src = dataUrl
                        img.onload = () => {
                            let canvas = document.createElement('canvas')
                            canvas.width = 300
                            canvas.height = 300 * img.height / img.width
                            let ctx = canvas.getContext('2d')
                            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height)
                            let newImgData = canvas.toDataURL(file.type, this.quality)
                            var resultFile = this.dataURLtoFile(newImgData, file.name)
                            this.initBlob()
                            const blockBlobClient = this.containerURL.getBlockBlobClient(this.folder + "/compress" + file.name)
                            blockBlobClient.uploadBrowserData(resultFile).then(
                                res => {
                                    fileInfo['compressUrl'] = this.urlString + '/' + this.containerName + '/' + this.folder + '/compress' + file.name
                                    this.$emit('successData', fileInfo)
                                },
                                err => {
                                    fileInfo['status'] = 2
                                }
                            )
                        }
                    }
                } else {
                    let video = document.createElement('video')
                    video.setAttribute('width', '300')
                    video.setAttribute('controls', 'controls')
                    video.setAttribute('crossOrigin', '*')
                    video.setAttribute('src', fileInfo.blobUrl + this.sasString)
                    video.addEventListener('loadeddata', () => {
                        let canvas = document.createElement('canvas')
                        canvas.width = 300
                        canvas.height = 300 * video.videoHeight / video.videoWidth
                        let ctx = canvas.getContext('2d')
                        ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.height)
                        let newVideoData = canvas.toDataURL('image/png', this.quality)
                        let resultFile = this.dataURLtoFile(newVideoData, file.name)
                        this.initBlob()
                        let posterName = 'compress' + file.name.replace(fileInfo.extension, 'png')
                        const blockBlobClient = this.containerURL.getBlockBlobClient(this.folder + "/" + posterName)
                        blockBlobClient.uploadBrowserData(resultFile).then(
                            res => {
                                fileInfo['compressUrl'] = this.urlString + '/'+ this.containerName + '/' + this.folder + '/' + posterName
                                this.$emit('successData', fileInfo)
                            },
                            err => {
                                fileInfo['status'] = 2
                            }
                        )
                    })
                }
            },
            uploadToBlob(file) {
                let fileItem = {}
                fileItem['fileName'] = file.name
                fileItem['blobUrl'] = this.urlString + '/' + this.containerName + '/' + this.folder + '/' + file.name
                fileItem['extension'] = file.name.substring(file.name.lastIndexOf('.') + 1)
                fileItem['size'] = file.size
                fileItem['status'] = 0
                fileItem['progress'] = 0
                fileItem['loadedBytes'] = 0
                fileItem['contentType'] = file.type == '' ? file.name.substring(file.name.lastIndexOf('.') + 1) : file.type
                let type = 'other'
                for (let item in this.contentTypes) {
                    if (this.contentTypes[item].indexOf(fileItem.extension.toUpperCase()) !== -1) {
                        switch (true) {
                            case item == 0:
                                type = 'picture'
                                break
                            case item == 1:
                                type = 'video'
                                break
                            case item == 2:
                                type = 'document'
                                break
                            case item == 3:
                                type = 'htex'
                                break
                            default:
                                break
                        }
                        break
                    }
                }
                fileItem['type'] = type
                this.uploadedList.push(fileItem)

                //v12
                let _this = this 
                const blockBlobClient = this.containerURL.getBlockBlobClient(this.folder + "/" + file.name)
                blockBlobClient.uploadBrowserData(file, {
                    onProgress: function (e) {
                        let index = _this.getIndex(_this.uploadedList, fileItem)
                        _this.uploadedList[index].loadedBytes = e.loadedBytes
                        _this.uploadedList[index].progress = parseInt(e.loadedBytes * 100 / file.size)
                    }
                }).then(
                    res => {
                        let index = this.getIndex(this.uploadedList, fileItem)
                        this.uploadedList[index].status = 1
                        this.uploadedList[index]['createTime'] = Date.parse(res.lastModified)
                        if (this.uploadedList[index].type == 'picture' || this.uploadedList[index].type == 'video') {
                            this.compressFile(file, this.uploadedList[index])
                        } else {
                            this.$emit('successData', this.uploadedList[index])
                        }
                    },
                    err => {
                        fileItem['status'] = 2
                    }
                )
                return false
            },
            beforeUpload(file) {
                let url = file.name
                if (file.size > this.maxSize) {
                    this.$Message.error({
                        content: this.$t('system.compt.sizeErr'),
                        duration: 3
                    })
                    return false
                }

                let extension = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
                if (this.format.length > 0 && this.format.indexOf(extension) == -1) {
                    this.$Message.error({
                        content: this.$t('system.compt.typeErr'),
                        duration: 3
                    })
                    return false
                }
                this.initBlob()
                this.uploadToBlob(file)
                
                return false
            },
            getIndex(_arr, _obj) {
                var len = _arr.length
                for (let i = 0; i < len; i++) {
                    if (this.isObjEqual(_arr[i], _obj)) {
                        return parseInt(i)
                    }
                }
                return -1
            },
            isObjEqual(o1, o2) {
                var props1 = Object.keys(o1)
                var props2 = Object.keys(o2)
                if (props1.length != props2.length) {
                    return false
                }
                for (var i = 0, max = props1.length; i < max; i++) {
                    var propName = props1[i]
                    if (o1[propName] !== o2[propName]) {
                        return false
                    }
                }
                return true
            }
        },
        mounted() {
            this.uploadedList = this.defaultFileList
        },
        created() {

        },
        watch: {
            defaultFileList: {
                handler: function (o, n) {
                    this.uploadedList = this.defaultFileList
                },
                deep: true
            }
        }
    }

</script>
<style scoped>
    .upload-text {
        margin: 20px 0px;
        font-size: 30px;
        margin-bottom: 80px;
    }
    .upload-icon {
        font-size: 80px;
        margin-top: 80px;
    }
    .upload-file-item {
        cursor: pointer;
        color: #909090;
        margin-top: 5px;
    }

        .upload-file-item:hover {
            color: white;
            background: #606060;
            border-radius: 5px;
        }

            .upload-file-item:hover .delete-btn {
                display: inline-block;
            }
    .upload-loading-icon {
        vertical-align:middle;
    }
    .upload-file-name {
        display: inline-block;
        /*margin-left: 10px;*/
        color:#EEEEEE;
    }

    .delete-btn {
        display: none;
    }
</style>
