<template>

	<div class="uploader_container">

		<div v-for="(file, index) in fileList" :key="index" class="image_holder" :style="picStyle">
		  <el-image v-loading="file.status == 'ready'" v-if="showImage(file)" class="image_content" :src="file.url"
		    fit="cover"></el-image>
		  <div v-loading="file.status == 'ready'" class="video_holder" v-if="showVideo(file)">
		    <el-image src="/images/zanting_b.png" :style="playStyle" />
		  </div>
		  <div class="image_mask">
		    <div class="layout_h_c">
		      <el-button v-if="showDelete(file)" type="text" icon="el-icon-delete"
		        class="dustbin" @click="onFileRemove(index)"></el-button>
		      <el-button v-if="showPlay(file)" type="text" icon="el-icon-video-play"
		        class="dustbin" @click="onPlayVideo(index)"></el-button>
		    </div>
		  </div>
		</div>

		<div class="input_container" v-if="showTrigger" :style="picStyle">
			<input class="input_el" :accept="accept" :multiple="multiple" :max="maxSelected" type="file" @change.prevent.stop="onChange" />
			<div class="plus_loader" slot="trigger" :style="picStyle">
			  <i class="el-icon-plus"></i>
			</div>
		</div>

    <core-player :show="showPlayer" :url="nowUrl" @close="showPlayer = false" />
    <span v-if="tips.default" style="color:#2790e0;white-space: nowrap;">{{tips.content}}</span>

	</div>

</template>

<script>

	export default {
		props: {
      tips:{
        type: Object,
        default: () => {
          return {
            content:"",
            default: false,
          }
        }
      },
			max: {
				type: Number,
				default: 1
			},
			size: {
				type: Object,
				default: () => {
			  return {
						width: "120px",
						height: "160px"
					}
				}
			},
			playSize: {
				type: Object,
				default: () => {
					return {
						width: '60px',
						height: '60px'
					}
				}
			},
			urls: {
				type: String,
				default: ""
			},
			lazyList: {
				type: String,
				default: ""
			},
			image: {
				type: Boolean,
				default: true
			},
			video: {
				type: Boolean,
				default: false
			}
		},
    components: {
      'core-player': () => import('@/components/player.vue')
    },
		data() {
			return {
        nowUrl: '',
        showPlayer: false,
        lazyLoaded: false,
				fileList: []
			}
		},
    watch: {
      lazyList(n, o) {
        if(n && n.length > 0 && !this.lazyLoaded) {
          this.lazyLoad(n)
        }
      }
    },
    created() {
      if(this.urls && this.urls.length > 0) {
        this.pushList(this.urls.split(",").map(url => {
          return {
            url: url,
            name: url
          }
        }))
      }
      let n = this.lazyList
      if(n && n.length > 0 && !this.lazyLoaded) {
        this.lazyLoad(n)
      }
    },
		computed: {
			picStyle() {
			  let size = this.size
			  return {
			    width: size.width,
			    height: size.height,
			    marginRight: "10px"
			  }
			},
			playStyle() {
			  let size = this.playSize
			  return {
			    width: size.width,
			    height: size.height
			  }
			},
      showTrigger() {
        return this.fileList.length < this.max
      },
      //是否显示图片
      showImage() {
        return f => {
          return (f.type && f.type.startsWith('image')) || this.isImage(f.url)
        }
      },
      //是否显示视频
      showVideo() {
        return f => {
          return (f.type && f.type.startsWith('video')) || this.isVideo(f.url)
        }
      },
      //是否显示删除按钮
      showDelete() {
        return f => {
          return f.status == undefined || f.status == 'success'
        }
      },
      //显示播放按钮
      showPlay() {
        return f => {
          return (f.status == undefined || f.status == 'success') && this.isVideo(f.url)
        }
      },
			validCount() {
				return this.fileList.length
			},
			//原生属性
			multiple() {
				return this.max > 1
			},
			maxSelected() {
				return Math.max(0, this.max - this.fileList.length)
			},
			accept() {
				let str = []
				if (this.image) {
					str.push("image/*")
				}
				if (this.video) {
					str.push("video/*")
				}
				return str.join(',')
			}
		},
		methods: {
      urlList() {
        let array = []
        for(let value of this.fileList) {
          if(value.url) {
            array.push(value.url)
          }
        }
        return array
      },
      isImage(str) {
        if(str == undefined) {
          return false
        }
        let sufix = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff', 'ico']
        for (let i = 0; i < sufix.length; i++) {
          let sf = sufix[i]
          if (str.endsWith(sf)) {
            return true
          }
        }
        return false
      },
      isVideo(str) {
        if(str == undefined) {
          return false
        }
        let sufix = ['mp4', 'avi', 'wmv', 'asf', 'rmvb', 'mov', 'm4v', 'mkv', 'flv', 'vob', 'dat', 'rm']
        for (let i = 0; i < sufix.length; i++) {
          let sf = sufix[i]
          if (str.endsWith(sf)) {
            return true
          }
        }
        return false
      },
      //对外接口 start

      lazyLoad(n) {
        this.lazyLoaded = true
        this.delayInit(n)
      },

      delayInit(urls) {
        this.$nextTick(() => {
          this.fileList = urls.split(",").map(url => {
            return {
              url: url,
              name: url
            }
          })
        })
      },

      initList(list) {
        this.fileList = list
      },

      pushList(list) {
        this.$nextTick(() => {
          this.fileList = this.fileList.concat(list)
        })
      },

      getList() {
        return this.fileList.filter(r => {
          return r.status == 'success' || r.url
        }).map(r => {
          return r.url
        })
      },

      //对外接口 end
			fileUpload(value, file) {
				if(value && value.status == 'ready' && file) {
          let bucket = ""
          if (file.type.startsWith('image') && this.image) {
            bucket = 'images'
          } else if (file.type.startsWith('video') && this.video) {
            bucket = 'videos'
          } else {
            this.onFileUploadError(value)
            return
          }
          this.$oss.upload(bucket, file)
            .then(r => {
              this.onFileUploadSuccess(value, r)
            })
            .catch(e => {
              this.onFileUploadError(value)
            })
				}
			},
      onFileRemove(index) {
        this.fileList.splice(index, 1)
        this.$emit('change', this.urlList())
      },
      onFileUploadSuccess(value, r) {
        value.status = 'success'
        value.url = r.url
        this.$emit('change', this.urlList())
      },
      onFileUploadError(value) {
        let index = -1
        for(let i = 0; i < this.fileList.length; i++) {
          let v = this.fileList[i]
          if(v === value) {
            index = i
            break
          }
        }
        if(i >= 0) {
          this.fileList.splice(index, 1)
          this.$emit('change', this.urlList())
        }
      },

      onPlayVideo(index) {
        let f = this.fileList[index]
        if(f.url) {
          this.showPlayer = true
          this.nowUrl = f.url
        }
      },

			onChange(r) {
				let files = event.target.files
				if(files && files.length > 0) {
					let pick = Math.min(this.maxSelected, files.length)
					for(let i = 0; i < pick; i++) {
						let f = files[i]
						let value = {
							name: f.name,
              type: f.type,
							file: f,
							status: 'ready'
						}
						this.fileList.push(value)
						this.fileUpload(value, f)
					}
				}
			}
		}
	}
</script>

<style scoped>
	.uploader_container {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
	}

	.input_container {
		position: relative;
	}

	.input_el:hover, .input_el:focus, .input_el:active {
		cursor: pointer;
	}

	.input_el {
		position: absolute;
		left: 0px;
		top: 0px;
		width: 100%;
		height: 100%;
		opacity: 0;
		-ms-filter: 'alpha(opacity=0)';
	}

	.plus_loader {
	  height: 100%;
	  width: 100%;
	  display: flex;
	  align-items: center;
	  justify-content: center;
	  border-color: #409EFF;
	  border: 1px dashed #d9d9d9;
	  border-radius: 6px;
	}

	.plus_loader:hover {
	  border-color: #409EFF;
	}

	.gallery {
	  display: flex;
	  flex-direction: row;
	  flex-wrap: wrap;
	}

	.dustbin {
	  height: 32px;
	  width: 32px;
	  align-self: center;
	}

	.image_holder {
	  position: relative;
	  border-color: #409EFF;
	  border: 1px dashed #d9d9d9;
	  border-radius: 6px;
	  margin-bottom: 6px;
	  overflow: hidden;
	}

	.image_content {
	   width: 100%;
	   height: 100%;
	}

	.video_holder {
	  width: 100%;
	  height: 100%;
	  display: flex;
	  justify-content: center;
	  align-items: center;
	  background: black;
	}

	.image_mask {
	  width: 100%;
	  height: 100%;
	  position: absolute;
	  left: 0;
	  top: 0;
	  background: rgba(0, 0, 0, 0.65);
	  opacity: 0;
	  display: flex;
	  flex-direction: column;
	  justify-content: center;
	}

	.image_mask:hover {
	  animation: fade 0.3s linear;
	  animation-fill-mode: forwards;
	}

	@keyframes fade {
	  0% {
	    opacity: 0;
	  }
	  50% {
	    opacity: 0.5;
	  }
	  100% {
	    opacity: 1;
	  }
	}
</style>
