<template>
    <view>
        <sjs src="../wxs/utils.sjs" module="utils" />

        <view class="van-uploader">
            <view class="van-uploader__wrapper">
                <!-- 预览样式 -->
                <view :wx:if="previewImage" :wx:for="lists" wx:key="index" class="van-uploader__preview">
                    <image
                        :wx:if="item.isImage"
                        :mode="imageFit"
                        :src="item.url || item.path"
                        :alt="item.name || '图片' + index"
                        class="van-uploader__preview-image"
                        :style="'width: ' + computedPreviewSize + '; height: ' + computedPreviewSize + ';'"
                        :data-url="item.url || item.path"
                        @tap="doPreviewImage"
                    />
                    <view wx:else class="van-uploader__file" :style="'width: ' + computedPreviewSize + '; height: ' + computedPreviewSize + ';'">
                        <van-icon name="description" class="van-uploader__file-icon" />
                        <view class="van-uploader__file-name van-ellipsis">{{ item.name || item.url || item.path }}</view>
                    </view>
                    <van-icon :wx:if="deletable" name="clear" class="van-uploader__preview-delete" :data-index="index" @tap.native="deleteItem($event, { index })" />
                </view>

                <!-- 上传样式 -->
                <block :wx:if="isInCount">
                    <view :wx:if="useSlot" class="van-uploader__slot" @tap="startUpload">
                        <slot />
                    </view>

                    <!-- 默认上传样式 -->
                    <view wx:else class="van-uploader__upload" :style="'width: ' + computedPreviewSize + '; height: ' + computedPreviewSize + ';'" @tap="startUpload">
                        <van-icon name="plus" class="van-uploader__upload-icon" />
                        <text :wx:if="uploadText" class="van-uploader__upload-text">{{ uploadText }}</text>
                    </view>
                </block>
            </view>
        </view>
    </view>
</template>

<script>
import { VantComponent } from '../common/component';
import { isImageFile } from './utils';
import { addUnit } from '../common/utils';
export default {
    data() {
        return {
            lists: [],
            computedPreviewSize: '',
            isInCount: true
        };
    },
    props: {
        disabled: Boolean,
        multiple: Boolean,
        uploadText: String,
        useSlot: Boolean,
        useBeforeRead: Boolean,
        previewSize: {
            type: null,
            default: 90
        },
        name: {
            type: [Number, String],
            default: ''
        },
        accept: {
            type: String,
            default: 'image'
        },
        fileList: {
            type: Array,
            default: () => []
        },
        maxSize: {
            type: Number,
            default: Number.MAX_VALUE
        },
        maxCount: {
            type: Number,
            default: 100
        },
        deletable: {
            type: Boolean,
            default: true
        },
        previewImage: {
            type: Boolean,
            default: true
        },
        previewFullImage: {
            type: Boolean,
            default: true
        },
        imageFit: {
            type: String,
            default: 'scaleToFill'
        }
    },
    methods: {
        formatFileList() {
            const { fileList = [], maxCount } = this;
            const lists = fileList.map((item) =>
                Object.assign(Object.assign({}, item), {
                    isImage: typeof item.isImage === 'undefined' ? isImageFile(item) : item.isImage
                })
            );
            this.setData({
                lists,
                isInCount: lists.length < maxCount
            });
        },
        setComputedPreviewSize(val) {
            this.setData({
                computedPreviewSize: addUnit(val)
            });
        },
        startUpload() {
            if (this.disabled) {
                return;
            }
            const { name = '', capture = ['album', 'camera'], maxCount = 100, multiple = false, maxSize, accept, lists, useBeforeRead = false } = this;
            let chooseFile = null;
            const newMaxCount = maxCount - lists.length;
            if (accept === 'image') {
                chooseFile = new Promise((resolve, reject) => {
                    wx.chooseImage({
                        count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,
                        sourceType: capture,
                        success: resolve,
                        fail: reject
                    });
                });
            } else {
                chooseFile = new Promise((resolve, reject) => {
                    wx.chooseMessageFile({
                        count: multiple ? newMaxCount : 1,
                        type: 'file',
                        success: resolve,
                        fail: reject
                    });
                });
            }
            chooseFile.then((res) => {
                const file = multiple ? res.tempFiles : res.tempFiles[0];
                if (file instanceof Array) {
                    const sizeEnable = file.every((item) => item.size <= maxSize);
                    if (!sizeEnable) {
                        this.$emit('oversize', {
                            name
                        });
                        return;
                    }
                } else if (file.size > maxSize) {
                    this.$emit('oversize', {
                        name
                    });
                    return;
                }
                if (useBeforeRead) {
                    this.$emit('before-read', {
                        file,
                        name,
                        callback: (result) => {
                            if (result) {
                                this.$emit('after-read', {
                                    file,
                                    name
                                });
                            }
                        }
                    });
                } else {
                    this.$emit('after-read', {
                        file,
                        name
                    });
                }
            });
        },
        deleteItem(event, _dataset) {
            /* ---处理dataset begin--- */
            this.handleDataset(event, _dataset);
            /* ---处理dataset end--- */
            const { index } = event.currentTarget.dataset;
            this.$emit('delete', {
                index,
                name: this.name
            });
        },
        doPreviewImage(event) {
            if (!this.previewFullImage) {
                return;
            }
            const curUrl = event.currentTarget.dataset.url;
            const images = this.lists.filter((item) => item.isImage).map((item) => item.url || item.path);
            this.$emit('click-preview', {
                url: curUrl,
                name: this.name
            });
            wx.previewImage({
                urls: images,
                current: curUrl,
                fail() {
                    wx.showToast({
                        title: '预览图片失败',
                        icon: 'none'
                    });
                }
            });
        }
    },
    watch: {
        previewSize: {
            handler: function (val) {
                this.setData({
                    computedPreviewSize: addUnit(val)
                });
            },

            immediate: true
        },

        fileList: {
            handler: function () {
                const { fileList = [], maxCount } = this;
                const lists = fileList.map((item) =>
                    Object.assign(Object.assign({}, item), {
                        isImage: typeof item.isImage === 'undefined' ? isImageFile(item) : item.isImage
                    })
                );
                this.setData({
                    lists,
                    isInCount: lists.length < maxCount
                });
            },

            immediate: true,
            deep: true
        }
    }
};
</script>
<style>
@import '../common/index.ttss';
.van-uploader {
    position: relative;
    display: inline-block;
}
.van-uploader__wrapper {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-wrap: wrap;
    flex-wrap: wrap;
}
.van-uploader__upload {
    position: relative;
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
    flex-direction: column;
    -webkit-align-items: center;
    align-items: center;
    -webkit-justify-content: center;
    justify-content: center;
    box-sizing: border-box;
    width: 80px;
    height: 80px;
    margin: 0 8px 8px 0;
    background-color: #fff;
    border: 1px dashed #ebedf0;
    border-radius: 4px;
}
.van-uploader__upload-icon {
    display: inline-block;
    width: 24px;
    height: 24px;
    color: #969799;
    font-size: 24px;
}
.van-uploader__upload-text {
    margin-top: 8px;
    color: #969799;
    font-size: 12px;
}
.van-uploader__preview {
    position: relative;
    margin: 0 8px 8px 0;
}
.van-uploader__preview-image {
    display: block;
    width: 80px;
    height: 80px;
    border-radius: 4px;
}
.van-uploader__preview-delete {
    position: absolute;
    top: -8px;
    right: -8px;
    color: #969799;
    font-size: 18px;
    background-color: #fff;
    border-radius: 100%;
}
.van-uploader__file {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
    flex-direction: column;
    -webkit-align-items: center;
    align-items: center;
    -webkit-justify-content: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    background-color: #f7f8fa;
    border-radius: 4px;
}
.van-uploader__file-icon {
    display: inline-block;
    width: 20px;
    height: 20px;
    color: #646566;
    font-size: 20px;
}
.van-uploader__file-name {
    box-sizing: border-box;
    width: 100%;
    margin-top: 8px;
    padding: 0 5px;
    color: #646566;
    font-size: 12px;
    text-align: center;
}
</style>
