export function MainImageManager() {

    return {

        /**
         * Used for gallery managament and indexation.
         * @type {string}
         */
        key: crypto.randomUUID(),

        /**
         * If an image has been uploaded or not.
         * @type {boolean}
         */
        uploaded: false,

        /**
         * Actual image path on the server.
         * @type {string|null}
         */
        serverFilePath: null,

        /**
         * Image filename.
         * @type {string|null}
         */
        name: null,

        /**
         * Image filetype.
         * @type {string|null}
         */
        type: null,

        /**
         * Handle preview.
         * @type {unknown}
         */
        preview: null,

        /**
         * Current error message.
         * @type {string}
         */
        error: null,

        /**
         * Reload image if there is an error.
         *
         * @param {string|null} oldPath If there is already a path.
         */
        init( oldPath = null ){
            if(oldPath === "" || oldPath === null)
                return;

            this.getOldImage(oldPath)
        },

        /**
         * Get old image from old path and refresh preview.
         * @param {string} oldPath
         * @param {function|null} callback Used in the gallery to push the image at the right time.
         */
        getOldImage( oldPath, callback = null ) {
            this.readOldImage( '/storage/' + oldPath ).then( blob => {

                this.uploaded = true;
                this.serverFilePath = oldPath;

                const READER = new FileReader();
                READER.onload = () => {
                    this.preview = READER.result;
                }
                READER.readAsDataURL(blob);
            });
        },

        /**
         * Get old image data.
         * @param {string} url
         * @returns {Promise<Blob>}
         */
        async readOldImage(url){
            const RESPONSE = await fetch(url);
            return await RESPONSE.blob();
        },

        async uploadImageToTemporary( file ){

            const CSRF = document.querySelector('meta[name=csrf-token]')?.content ?? '';
            const URL = `/api/tempfile/upload`;

            const formData = new FormData();

            formData.append('file', file);
            formData.append('_token', CSRF );

            try {
                const RESPONSE = await fetch( URL, { method: 'POST', body: formData } );

                if( !RESPONSE.ok ) // Problem with the request.
                    throw new Error(`${RESPONSE.status} ${RESPONSE.statusText}`);

                const DATA = await RESPONSE.json();

                if( DATA.path === null ){
                    throw new Error(`${RESPONSE.status} ${RESPONSE.statusText}`);
                }

                this.serverFilePath = DATA.path;
                this.uploaded = true;

            } catch (err){
                this.error = 'Error on main image uploading ' + ( i + 1 ) + '. ' + err.message;
                console.error( this.error );
                return;
            }
        },

        /**
         * Upload image, refresh the preview and store image if there is a problem.
         *
         * @param {Event} e
         */
        async handleSubmitFile(e) {
            const FILE = e.target.files[0];
            if (!FILE)
                return; // No file uploaded.

            this.handleRemoveFile(null);
            await this.uploadImageToTemporary(FILE);

            this.name = FILE.name;
            this.type = FILE.type;

            const READER = new FileReader();
            READER.onload = (e2) => {
                this.preview = e2.target.result;
            }
            READER.readAsDataURL(FILE);
        },

        /**
         * Remove main image.
         * @param {Event} e
         */
        handleRemoveFile(e){
            this.uploaded = false;
            this.serverFilePath = null;
            this.preview = null;
            this.name = null;
            this.type = null;
            this.error = null;
        }

    }
}
