<template>
  <div class="sel-file-view">
    <ul v-if="view==='file'" class="fileList">
      <li
        v-for="(item,index) in showLength?viewList.slice(0,showLength):viewList"
        v-show="item.name"
        :key="'file'+index"
      >
        <p @click="previewHandle(item)">
          <svg class="icon" aria-hidden="true">
            <use :xlink:href="typeFilter(item.name)"/>
          </svg>
          {{ item.name }}
        </p>
        <span>
          <svg class="icon" aria-hidden="true" @click="download(item)">
             <use xlink:href="#icon-download"/>
          </svg>
          <svg v-if="remove" class="icon" aria-hidden="true" @click="removeFile(item,index)">
            <use xlink:href="#icon-remove"/>
          </svg>
        </span>
      </li>
    </ul>
    <ul v-if="view==='image'" class="imageList" :class="{remove:remove}">
      <li
        v-show="showLength?index<showLength:true"
        v-for="(item,index) in viewList"
        :key="'file'+index"
        :style="imageStyle"
      >
        <img
          :src="buildUrl(item.url)"
          @click="previewHandler"
        />
        <div class="iconGroup">
          <svg class="icon" aria-hidden="true" v-if="remove" @click="removeFile(item,index)">
            <use xlink:href="#icon-remove"/>
          </svg>
          <svg class="icon" aria-hidden="true" @click="previewHandler">
            <use xlink:href="#icon-yulan"/>
          </svg>
        </div>
      </li>
    </ul>
    <div v-if="view==='slot'" class="fileViewSlot">
      <slot :data="viewList"/>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { cloneDeep } from 'lodash-es'
import { isJsonString } from '../../../Utils'
import { computed } from 'vue'
import { useUpload } from '../../../hooks/use-upload'
import './viewer/style.css'
import * as VueViewer from 'v-viewer'

const { api: viewerApi } = VueViewer

defineOptions({
  name: 'SFileView',
})

interface Props {
  modelValue: any
  upload: any
  imageStyle: any
  remove: boolean
  preview: boolean
  showLength: number
  view: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  upload: () => {
    return {}
  },
  imageStyle: () => {
    return {}
  },
  remove: false,
  preview: true,
  view: 'file',
})
const emits = defineEmits([ 'update:modelValue', 'change' ])
const images = computed(() => {
  return viewList.value.map(item => {
    return buildUrl(item.url)
  })
})

function buildUrl ( url ) {
  if (url.indexOf('http') > -1) {
    return url
  } else {
    return mergeConfig.value.domain + url
  }
}

function typeFilter ( name ) {
  const type = name && name.substr(name.lastIndexOf('.')).slice('.')
  switch (type) {
    case '.pdf':
      return '#icon-ppt1'
    case '.doc':
    case '.docx':
      return '#icon-word'
    case '.ppt':
    case '.pptx':
      return '#icon-ppt'
    case '.xls':
    case '.xlsx':
      return '#icon-excel'
    case '.txt':
      return '#icon-txt'
    case '.png':
    case '.jpg':
    case '.jpeg':
    case '.gif':
      return '#icon-Image_File'
    case '.zip':
    case '.rar':
      return '#icon-yasuobao'
    case '.mp4':
      return '#icon-icon-test'
  }
}

const { mergeConfig } = useUpload()

const viewList = computed(() => {
  let array = []
  if (props.modelValue && typeof props.modelValue === 'string') {
    if (!isJsonString(props.modelValue)) {
      if (props.modelValue.indexOf('base64') < 0) {
        props.modelValue.split(',').map(item => {
          array.push({
            name: item.split('&&')[1],
            url: item.split('&&')[0]
          })
        })
      } else {
        array.push({
          name: props.modelValue.split('&&')[1],
          url: props.modelValue.split('&&')[0]
        })
      }
    } else {
      array = JSON.parse(props.modelValue).map(item => {
        return {
          ...item,
          name: item[mergeConfig.value.nameKey] || item.name,
          url: item[mergeConfig.value.urlKey] || item.url
        }
      })
    }
  } else if (props.modelValue && Array.isArray(props.modelValue)) {
    array = props.modelValue && props.modelValue.map(item => {
      return {
        ...item,
        name: item[mergeConfig.value.nameKey] || item.name,
        url: item[mergeConfig.value.urlKey] || item.url
      }
    })
  }
  return array
})

function removeFile ( item, index ) {
  const value = cloneDeep(viewList.value)
  value.splice(index, 1)
  if (typeof props.modelValue === 'string') {
    emits('update:modelValue', JSON.stringify(value))
    emits('change', JSON.stringify(value))
  } else {
    emits('update:modelValue', value)
    emits('change', value)
  }
}

function download ( item ) {
  const a = document.createElement('a')
  a.setAttribute('download', '')
  if (item.url.indexOf('http') >= 0) {
    a.setAttribute('href', item.url)
  } else {
    a.setAttribute('href', mergeConfig.value.domain + item.url)
  }
  a.click()
}

function previewHandler () {
  if (props.preview) {
    viewerApi({
      images: images.value
    })
  }
}

function previewHandle ( item ) {
  const type = item.name.substr(item.name.lastIndexOf('.'))
  switch (type) {
    case '.pdf':
    case '.xls':
    case '.xlsx':
    default:
      if (item.url.indexOf('http') >= 0) {
        window.open(item.url)
      } else {
        window.open(mergeConfig.value.domain + item.url)
      }
  }
}
</script>
<style>
.viewer-title {
    display: none !important;
}

.icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
}
</style>
<style lang="scss">
.sel-file-view {
  .fileList {
    padding: 0;
    margin: 0;

    li {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 6px;
      margin-bottom: 5px;
      line-height: 30px;
      border: 1px dashed #ddd;

      &:last-child {
        margin-bottom: 0;
      }

      &:hover {
        background-color: #eee;
      }

      p {
        display: flex;
        margin-top: 0;
        margin-bottom: 0;
        cursor: pointer;
        justify-content: flex-start;
        align-items: center;

        .icon {
          width: 24px;
          height: 24px;
          margin-right: 10px;
        }
      }

      span {
        display: flex;
        justify-content: flex-start;
        align-items: center;

        .icon {
          cursor: pointer;
          margin-right: 10px;
          fill: #565D64;
          color: #565D64;
        }
      }
    }
  }

  .imageList {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    padding: 0;
    margin: 0;

    .icon {
      display: none;
    }

    &.remove {
      li:hover {
        .iconGroup {
          position: absolute;
          width: 60%;
          top: 50%;
          left: 50%;
          z-index: 2;
          font-size: 24px;
          display: flex;
          justify-content: space-between;
          color: #fff;
          transform: translate(-50%, -50%);

          .icon {
            display: block;
          }
        }

        &:after {
          position: absolute;
          top: 0;
          left: 0;
          z-index: 1;
          width: 100%;
          height: 100%;
          background-color: rgba(0, 0, 0, 0.4);
          content: '';
        }
      }
    }

    li {
      position: relative;
      display: flex;
      width: 98px;
      height: 98px;
      margin-right: 8px;
      margin-bottom: 8px;
      overflow: hidden;
      border: 1px dashed #f2f2f2;
      justify-content: center;
      align-content: center;

      img {
        width: 100%;
        height: 100%;
      }

      video {
        width: 100%;
        height: 100%;
      }

      i {
        display: none;
      }

      &:hover {
        cursor: pointer;
        background-color: rgba(0, 0, 0, 0.4);

        .icon {
          display: block;
        }
      }
    }
  }
}
</style>
