<template>
    <v-sheet
        tile
        color="transparent"
        :outlined="false"
        width="100%"
        class="cs-file-uploader fill-height d-flex justify-center align-center"
    >
        <v-file-input 
            ref="Input" 
            class="image-upload-box-input"
            dense
            :accept="inputAccept"
            :disabled="inputDisabled"
            :append-outer-icon="null"
            :id="control.id"

            @change="OnFileChange"
        >
        </v-file-input>
        
        <v-hover
            :disabled="actionAlwaysVisible" 
            v-slot="{hover}"
        >
            <v-sheet
                tile
                :color="color"
                :width="width"
                :height="height"
                :outlined="false"
                class="align-self-center"
            >

                <v-progress-linear
                    v-if="loading"
                    indeterminate
                >
                </v-progress-linear>

                <v-sheet
                    color="transparent"
                    class="file-preview d-flex justify-center align-center"
                    :height="height - (hover || actionAlwaysVisible ? actionsHeight : 0)"
                >
                    <template v-if="imageUrl">
                        <v-img
                            v-if="isImage"
                            :src="imageUrl"
                            :height="ImageHeight(hover)"
                            :max-width="imageWidth"
                            contain
                        >
                        </v-img>

                        <v-sheet
                            v-else
                        >
                            Avem url. Nu-i imagine
                        </v-sheet>
                    </template>

                    <v-sheet
                        v-else
                        color="transparent text-center"
                        class="px-2"
                    >
                        <span class="text-caption">
                            {{ noFileText }}
                        </span>

                        <template v-if="control.hint">
                            <br/>
                            <span class="text-caption info--text">
                                {{control.hint}}
                            </span>
                        </template>
                    </v-sheet>

                    <v-sheet
                        v-if="errors.length"
                        class="errors-container overflow-y-auto"
                        :max-height="height - (hover || actionAlwaysVisible ? actionsHeight : 0)"
                    >
                        <cs-info-alert
                            color="red"
                            :icon="null"
                            :message="errors.join('. ')"
                            :closable="true"
                            @visible-toggle="OnErrorsVisibleToggle"
                        />
                    </v-sheet>
                </v-sheet>
                
                <v-sheet
                    v-if="actionAlwaysVisible || hover"
                >
                    <cs-btn
                        icon="mdi-upload"
                        color="blue darken-3"
                        tooltip="Încarcă un fișier"
                        @click="OnClickUpload"
                    />

                    <cs-btn
                        v-if="! immediateInput"
                        icon="mdi-content-save"
                        color="purple darken-3"
                        tooltip="Salvează"
                        :disabled="! canSave"
                        @click="OnClickSave"
                    />

                    <cs-btn
                        icon="mdi-close"
                        color="orange"
                        :disabled="! canCancel"
                        tooltip="Renunță și încarcă fișierul inițial"
                        @click="OnClickRestore"
                    />

                    <cs-btn
                        icon="mdi-delete"
                        color="red"
                        :disabled="! canDelete"
                        tooltip="Șterge fișierul încăcat"
                        @click="OnClickDelete"
                    />

                    
                </v-sheet>
                
                
            </v-sheet>
        </v-hover>
        
    </v-sheet>
</template>

<script>
    import RandomString from '@CsFunc/global/RandomString';
    import JQApply from '@Cs/jquery/Apply';
    import FileProperties from './Requests/FileProperties.request';

    const HumanFileSize = require('@CsFunc/global/HumanFileSize'); 

    export default {
        props: {
            control: {required: true},

            value: {required: true},

            color: {default: 'grey lighten-3'},

            actionsHeight: {default: 28},

            inputDisabled: {default: false},
            
            actionAlwaysVisible: {default: true},

            immediateInput: {default: false},
        },

        data: () => ({

            errors: [],

            localFile: null,
            
            changed: false,

            requests: {
                FileProperties: null,
            },
        }),

        computed: {

            loading() {
                return this.requests.FileProperties.processing;
            },

            imageUrl() {
                return this.localFile ? this.localFile.url : null;
            },

            imageWidth() {
                return '100%';
            },

            /**
             * ca sa fie true ==> tre sa fie cuvantul 'image' in inputAccept
             */
            isImage() {
                return this.inputAccept.indexOf('image') !== -1
            },

            canSave() {
                // (! localFile && ! value) || (localFile && value && (localFile.url == value.url))
                return this.canCancel;
            },  

            canCancel() {
                if( ! this.value && ! this.localFile )
                {
                    /**
                     * ambele null
                     */
                    return false;
                }
                if( this.value && this.localFile )
                {
                    /**
                     * au acelasi url ==> false
                     */
                    return ! (this.localFile.url == this.value.url);
                }
                return true;
            },

            canDelete() {
                return this.localFile;
            },

            width() {
                return this.control.width;
            },

            height() {
                return this.control.height;
            },

            path() {
                return this.control.path;
            },

            /**
             * .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document
             * audio/*
             * video/*
             * image/*
             * image/*,.pdf
             * image/png or .png
             * image/png, image/jpeg
             */
            inputAccept() {
                return this.control.inputAccept;
            },

            noFileText() {
                return this.control.noFileText;
            },

            rules() {
                return this.control.rules;
            }
        },

        watch: {
            canSave: function(value, oldvalue) {
                this.$emit('issaved', ! value);
            }
        },

        methods: {
            OnFileChange(file) {
                if( file != undefined )
                {
                    this.PreValidate(file);

                    if(this.errors.length == 0)
                    {
                        this.requests.FileProperties
                            .ResetData()
                            .SetData({
                                file,
                                is_image: this.isImage ? 1 : 0,
                                user_id: this.$user.id,
                                path: this.path,
                                rules: this.rules,
                            })
                            .Request(
                                [
                                    response => {
                                        this.localFile = response.payload;
                                        this.changed = true;

                                        this.$emit('uploaded', response.payload);

                                        if(this.immediateInput)
                                        {
                                            this.OnClickSave();
                                        }
                                    }
                                ],
                                [
                                    response => {
                                        _.each(response.validator.errors, (errors, field) => {
                                            _.each(errors, error => {
                                                this.errors.push(this.__(error));
                                            })
                                        })
                                    }
                                ]
                            );
                    }
                    else
                    {
                    }
                }
                else
                {
                    this.localFile = null;
                }
            },

            PreValidate(file) {
  
                this.errors = [];
                if(! file.type.match(this.inputAccept)) 
                {
                    return this.errors.push(this.__('Fișierul pare să nu aibă tipul acceptat.'));
                }
                if(file.size > this.rules.maxsize)
                {
                    return this.errors.push(this.__('Fișierul este prea mare. Mărimea maximă acceptată este :max. Fișierul încărcat are :size', {
                        max: HumanFileSize(this.rules.maxsize),
                        size: HumanFileSize(file.size),
                    }));
                }
                if(file.size > this.$config.php.upload_max_size)
                {
                    return this.errors.push(this.__('Serverul nu permite un fișier așa mare. Mărimea maximă acceptată de server este :max. Fișierul încărcat are :size', {
                        max: HumanFileSize(this.$config.php.upload_max_size),
                        size: HumanFileSize(file.size),
                    }));
                }
                /**
                 * Validate extensions
                 */
                let extension = file.name.slice((file.name.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
                let exists = _.find(this.allowedExtensions, item => item.toLowerCase() == extension);
                if(!! undefined)
                {
                    return this.errors.push(this.__('Tipul de fișier nu este acceptat. Extensia :ext nu este permisă', {
                        ext: extension
                    }));
                }
            },

            OnClickUpload(e) {
               
                e.preventDefault();
                e.stopPropagation();
                
                this.$refs.Input.$refs.input.value = null;

                JQApply(this.control.id, [
                    j => {
                        j.trigger('click');
                    }
                ]);
            },

            OnClickSave() {
                this.$emit('input', this.localFile);
                this.$emit('save');
            },

            OnClickDelete() {
                this.localFile = null;
                this.changed = true;

                if(this.immediateInput)
                {
                    this.OnClickSave();
                }
            },

            OnClickRestore() {
                this.ValueToLocalFile();
            },

            Reset() {
                this.ValueToLocalFile();
            },

            ImageHeight(hover) {
                let h = this.height - (this.actionAlwaysVisible || hover ? this.actionsHeight : 0);
                if(this.localFile && (this.localFile.height < h))
                {
                    h = this.localFile.height;
                }
                return h;
            },

            OnErrorsVisibleToggle(visible) {
                if( ! visible)
                {
                    this.errors = [];
                }
            },
            
            ValueToLocalFile() {
                this.localFile = this.value ? {...this.value} : null;
            }
        },

        created() {
            this.control.id = 'cs-file-uploader-' + RandomString(64);
            this.requests.FileProperties = new FileProperties(this);

            this.ValueToLocalFile();
        },

        components: {
            CsBtn: require('@CsVueComp/buttons/CsBtn').default,
            CsInfoAlert: require('@CsVueComp/sheets/CsInfoAlert').default,
        },

        name: 'CsFileUploader',
    }
</script>