<template>
    <span>
        <span v-if="!supported">{{$t('useChrome')}}</span>
        <span v-else>
            <center v-if="preview && showThumb">
                <img :src="thumbUrl"
                     :height="thumbHeight"
                     :style="{height: `${thumbHeight}px`}">
            </center>
            <input ref="fileInput"
                   type="file"
                   :name="inputName"
                   :id="inputIdentifier"
                   :accept="accept"
                   style="display: none;"
                   @change="onFilePicked">
            <label :for="labelId">{{label}}</label>
            <div class="input-group">
                <input type="text"
                       class="form-control"
                       :id="labelId"
                       :placeholder="$t('select')"
                       :aria-label="$t('select')"
                       :aria-describedby="inputGroupId"
                       @click="pickFile"
                       v-model="fileName"
                       readonly
                       dir="ltr"
                       :disabled="disabled"
                       style="cursor: pointer" />
                <div class="input-group-append">
                    <button class="btn btn-danger"
                            type="button"
                            @click="$emit('input', null)">
                        &times;
                    </button>
                </div>
            </div>
        </span>
    </span>
</template>

<script>
import loc from "./j-fileinput.resx";
import { i18n } from '../../localization/vue-i18n';
import { guid, browserFileApiSupport, mimeHelper, urlParser } from "libj-core";
import { isString, acceptToFileTypes } from "./util";
export default {
    i18n: i18n(loc),
    props: {
        label: {
            type: String,
            default: ""
        },
        value: {
            type: [String, File],
            default: ''
        },
        thumb: {
            type: String,
            default: ""
        },
        //max file size in kilo bytes
        maxSize: {
            type: Number,
            default: 1024 * 1
        },
        //file input accept
        //https://www.w3schools.com/tags/att_input_accept.asp
        //http://www.iana.org/assignments/media-types/
        accept: {
            type: String,
            default: "image/*"
        },
        preview: {
            type: Boolean,
            default: true
        },
        inputName: {
            type: String,
            default: "file"
        },
        inputId: {
            type: String,
            default: null
        },
        disabled: {
            type: Boolean,
            default: false
        },
        /**
         * متن خطای فایل با پسوند اشتباه
         */
        acceptError: {
            type: String,
            default: null
        }
    },
    data() {
        var iid = this.inputId;
        if (iid === undefined || iid === null) {
            iid = guid.newId();
        }
        return {
            supported: browserFileApiSupport.supportsFileInput() && browserFileApiSupport.supportsFileApi(),
            showThumb: false,
            fileName: "",
            fileType: null,
            fileExtension: '',
            validFileTypes: [],
            thumbUrl: this.thumb,
            thumbHeight: 150,
            inputIdentifier: iid,
            labelId: guid.newId(),
            inputGroupId: guid.newId()
        };
    },
    mounted() {
        this.acceptChanged();
        this.valueChanged();
    },
    methods: {
        getInputId() {
            return this.inputIdentifier;
        },
        clear() {
            this.showThumb = false;
            this.fileName = null;
            this.fileType = '';
            this.fileExtension = '';
            this.thumbUrl = '';
            this.$refs.fileInput.value = null;
        },
        valueChanged() {
            if (this.value !== undefined && this.value !== null) {
                //create thumb
                if (isString(this.value)) {
                    if (this.value.length > 0) {
                        //url
                        var x = urlParser.parse(this.value).pathname;
                        this.fileName = x.substring(x.lastIndexOf('/') + 1);
                        this.fileType = mimeHelper.getMediaType(this.fileName);
                        this.fileExtension = mimeHelper.getExtension(this.fileType);
                        this.thumbUrl = mimeHelper.getIconPathForUrl(this.value, 64);
                        this.showThumb = true;
                        this.thumbHeight = 64;
                        this.$emit('thumbChange', this.thumbUrl);
                    }
                } else {
                    //file
                    this.fileName = this.value.name;
                    this.fileType = mimeHelper.getMediaType(this.fileName);
                    this.fileExtension = mimeHelper.getExtension(this.fileType);
                    mimeHelper.getIconPathForFile(this.value, x => {
                        this.showThumb = true;
                        this.thumbUrl = x.icon;
                        this.thumbHeight = 64;
                        this.$emit('thumbChange', this.thumbUrl);
                    }, 64);
                }
            } else {
                //clear
                this.clear();
            }
        },
        acceptChanged() {
            this.validFileTypes.splice(0, this.validFileTypes.length);
            var array = acceptToFileTypes(this.accept);
            array.forEach(a => {
                this.validFileTypes.push(a);
            });
        },
        checkMaxSize(fileSize) {
            if (fileSize > this.maxSize * 1024) {
                this.$toast.show({
                    message: this.$t("maxSizeError", { maxSize: this.maxSize }),
                    color: 'error',
                });
                return false;
            }
            return true;
        },
        checkAccept(fileType) {
            if (this.validFileTypes.length === 0) {
                return true;
            }
            var type = fileType.toString().trim().toLowerCase();
            var index = this.validFileTypes.findIndex(a => {
                return (a.toString().trim().toLowerCase() === type);
            });
            if (index > -1) {
                return true;
            }
            var msg;
            if (this.acceptError === undefined || this.acceptError === null) {
                msg = this.$t("acceptError", { accept: this.accept });
            } else {
                msg = this.acceptError;
            }
            this.$toast.show({
                message: msg,
                color: "error",
            });
            return false;
        },
        set(file) {
            if (file !== undefined && file !== null) {
                //check if file has extension
                if (file.name.lastIndexOf(".") <= 0) {
                    return;
                }
                //check size
                if (!this.checkMaxSize(file.size)) {
                    return;
                }
                //check accept
                if (!this.checkAccept(file.type)) {
                    return;
                }
            }
            this.$emit('input', file);
        },
        pickFile() {
            if (this.disabled) {
                return;
            }
            this.$refs.fileInput.click();
        },
        onFilePicked(e) {
            var files = e.target.files || e.dataTransfer.files;
            //check if file is selected
            if (!files.length) {
                return;
            }
            var file = files[0];
            this.set(file);
            return false;
        }
    },
    watch: {
        accept() {
            this.acceptChanged();
        },
        value() {
            this.valueChanged();
        }
    },
};
</script>